Comment vérifier si un tampon visite un fichier?

9

Je voudrais vérifier si un tampon (disons, actuel) visite un fichier ou non. Je pourrais dire:

(if (buffer-file-name) ...)

mais il ne semble pas très élégant - ce qui m'intéresse, c'est seulement la valeur booléenne, pas le nom réel du tampon en question. Si la buffer-file-namefonction était écrite en Elisp, je pourrais regarder sa source pour savoir ce qu'elle utilise - mais elle est écrite en C, et bien que je puisse installer les sources Emacs, j'ai peur de ne pas trouver de nom elisp pour la fonction qui vérifie ce que je recherche de toute façon.

Ce dont j'ai besoin, c'est que je veux créer un répertoire basé sur le nom du fichier du tampon actuel, et actuellement je fais plus ou moins ceci:

(make-directory (if (buffer-file-name) (file-name-base) "default-dir"))

Alors, quelle serait la façon idiomatique Elisp de faire cela?

mbork
la source
2
Je ne sais pas pourquoi vous vous opposez buffer-file-namevraiment à l'utilisation , c'est la bonne façon de le faire (si vous le voulez vraiment t, faites-le, (and (buffer-file-name) t)mais c'est plus laid IMO). Son implémentation est la lecture du filenamechamp de la structure du tampon C, qui n'est de toute façon pas accessible directement depuis Elisp. En fin de compte, c'est juste un pointeur qui est nul ou non.
Sigma
Eh bien, si c'est la bonne façon, ça me convient. Comme je l'ai dit - je ne connaissais pas l'implémentation C, et le bon sens dit que demander le nom du fichier quand je veux seulement savoir s'il y en a peut être redondant.
mbork
Et je suis d'accord, ça a l' (and (buffer-file-name) t)air étrange.
mbork
Si vous ne pensez pas que c'est (if (buffer-file-name) ... )élégant, alors vous n'avez pas codé en elisp depuis très longtemps. Cela devient plus laid d'ici.
nispio

Réponses:

12

Je dirais que votre utilisation est idiomatique, car le nom du tampon est une valeur booléenne parfaitement appropriée en soi. Citant du manuel :

Il y a un aspect important au test de vérité dans une expression if. Jusqu'à présent, nous avons parlé de «vrai» et de «faux» comme valeurs de prédicats comme s'il s'agissait de nouveaux types d'objets Emacs Lisp. En fait, «faux» n'est que notre vieil ami nil. Tout le reste - rien du tout - est «vrai».

Pour approfondir le point, consultez le code pour clone-buffer. J'espère que vous verrez ce qui suit:

(interactive
 (progn
   (if buffer-file-name
       (error "Cannot clone a file-visiting buffer"))
...

Notez que cela teste la liaison de variable buffer-file-nameau lieu d'appeler la fonction sans argument (buffer-file-name), mais les deux doivent toujours se comporter de la même manière.

purple_arrows
la source
8

Vous pouvez utiliser (buffer-file-name)(avec l' argument tampon en option) ou le tampon local buffer-file-namevariable. Les deux évaluent à la même valeur pour un tampon donné.

C'est la façon idiomatiques de le faire dans Elisp, cependant, de sorte que votre code est bien. Si vous le vouliez désespérément, vous pourriez toujours créer une buffer-has-file-pfonction wrapper.

phils
la source
Merci. Y a-t-il une différence significative pour choisir la fonction ou la variable?
mbork
1
Je ne pense pas. Si vous devez indiquer l'argument tampon, (buffer-file-name BUFFER)c'est certainement plus agréable que cela (with-current-buffer BUFFER buffer-file-name), mais sinon je ne pense pas que celui que vous utilisez soit important (et comme la fonction est écrite en C, je doute qu'il y ait même beaucoup de différence dans les performances).
phils
3

Utilisez simplement buffer-file-name. En Lisp, nous utilisons souvent une non- nilvaleur pour dire vrai .

Les seules fois où vous voudrez peut-être éviter cela, c'est si la fonction est coûteuse ou a des effets secondaires indésirables.

A dessiné
la source
Je vois. Je sais que tout ce qui nilest non -vrai est vrai, je pensais juste que saisir le nom quand je veux seulement savoir si un nom existe est "coûteux" - mais apparemment ce n'est pas le cas.
mbork
1

A partir du chapitre "Buffer List" de la documentation:

La liste renvoyée par buffer-list est construite spécifiquement; il ne s'agit pas d'une structure de données Emacs interne et sa modification n'a aucun effet sur l'ordre des tampons.

Vous devez donc trouver un moyen de rechercher dans la liste des tampons en direct. En voici un:

  (if (string-match-p (regexp-quote "My buffer name") (format "%s" (buffer-list)))
      (message "Open")
    (message "Not open"))
yPhil
la source