如何检查缓冲区是否正在访问文件?


9

我想检查某些(例如当前)缓冲区是否正在访问文件。我可以说:

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

但它似乎不是很优雅-我感兴趣的只是布尔值,而不是相关缓冲区的实际名称。如果该buffer-file-name函数是用Elisp编写的,我可以查看其源代码以查明它的用途-但它是用C编写的,尽管我可以安装Emacs源代码,但恐怕找不到一个elisp名称。该功能可以检查我到底在哪里。

我需要的是我想根据当前缓冲区的文件名创建一个目录,目前我正在或多或少地这样做:

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

那么,Elisp惯用的方式是什么呢?


2
不知道为什么您反对使用buffer-file-name真正的方法,这是正确的方法(如果您确实想t要这样做(and (buffer-file-name) t),那就是更丑陋的IMO)。它的实现是读取filename缓冲区C结构的字段,但无论如何都不能直接从Elisp访问。最后,它只是一个为空或不为空的指针。
Sigma

好吧,如果这是正确的方法,那对我很好。就像我说的那样-我不知道C的实现,常识说,当我只想知道是否有多余的文件时,要求输入文件名。
mbork 2014年

我同意这(and (buffer-file-name) t)看起来很奇怪。
mbork 2014年

如果您不觉得这(if (buffer-file-name) ... )很优雅,那么您已经很长时间没有使用elisp进行编码了。从这里只会变得更难看。
nispio 2014年

Answers:


12

我认为您的用法惯用的elisp,因为缓冲区的名称本身就是一个非常合适的布尔值。引用手册

在if表达式中,真相测试有一个重要方面。到目前为止,我们已经将谓词的值称为“ true”和“ false”,就好像它们是Emacs Lisp新对象一样。实际上,“ false”只是我们的老朋友nil。任何其他任何事情都是“真实”。

为了进一步说明这一点,请查看的代码clone-buffer。我希望您会看到以下内容:

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

请注意,这是测试的变量绑定,buffer-file-name而不是不带参数调用函数(buffer-file-name),但是两者应始终表现相同。


8

您可以使用(buffer-file-name)(带有可选的buffer参数)或buffer-local buffer-file-name变量。对于给定的缓冲区,两者的值均相同。

为此在elisp的,虽然如此,你的代码是罚款习惯的方法。如果您迫切希望,可以始终使用buffer-has-file-p包装函数。


谢谢。选择功能或变量有什么显着差异?
mbork 2014年

1
我不这么认为。如果您需要指示buffer参数,那(buffer-file-name BUFFER)肯定比更好(with-current-buffer BUFFER buffer-file-name),但否则我认为使用哪一个参数都不重要(而且由于函数是用C编写的,因此我怀疑性能会有很大差异)。
phils 2014年

3

只需使用buffer-file-name。在Lisp中,我们经常使用非nil值表示true

您可能唯一想避免的情况是该功能昂贵或有不良副作用。


我知道了。我知道所有非nil事实都是如此,当我只想知道是否存在任何名称时,我只是想抓住该名称是“昂贵的”-但似乎并非如此。
mbork 2014年

1

“缓冲列表”一章的文件:

buffer-list返回的列表是专门构造的;它不是内部Emacs数据结构,对其进行修改不会影响缓冲区的顺序。

因此,您必须找到一种在实时缓冲区列表中进行搜索的方法。这是一个:

  (if (string-match-p (regexp-quote "My buffer name") (format "%s" (buffer-list)))
      (message "Open")
    (message "Not open"))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.