如何使用Emacs Lisp检查文件是否存在?

我想emacs标记打开文件时生成只读的文件。 我缺less的难题是如何检查一个文件是否存在。 我目前有以下几点:

;; ;; get file extension ;; (defun get-ext (file-name) (car (cdr (split-string file-name "\\.")))) ;; ;; get the base name of the file ;; (defun base-name (file-name) (car (split-string file-name "\\."))) ;; ;; if an 'lzz' file exists for this header, mark it as read only ;; (defun mark-read-only () (if (string= (get-ext (cur-file)) "h") (if ( ??file-exists??? (concat (base-name (cur-file)) ".lzz") ) (toggle-read-only)))) 

我可以使用什么“???文件存在???”?

一旦我find这个,我将添加“标记只读”到适当的钩子(我认为是find-file-hook)。

背景

我们使用lzz作为代码生成器来简化我们的C / C ++开发过程。 简而言之,lzz需要一个input文件(它看起来非常像C / C ++),并根据需要生成头文件和源文件。

默认情况下,lzz包含#line指令,以便debugging器指向原始源而不是生成的源,但是为了减less编译依赖性,我们通常在头文件中禁用这些指令。 结果是,当debugging模板或内联函数时,debugging器通常指向生成的头文件而不是原始源文件。

这不是什么大不了的事,但是最近我发现在debugging的时候我会对显示的文件做一个快速的修改,然后重新编译。 当然,这通常意味着我所做的更改会消失,因为我编辑的文件已生成,因此在库重build期间,这些更改将被“吹走”。

感谢大家的帮助和评论。 特别感谢cobbal指出正确的使用function。

下面是结果代码(更新的基础上的其他评论):

 (defun cur-file () "Return the filename (without directory) of the current buffer" (file-name-nondirectory (buffer-file-name (current-buffer))) ) (defun mark-generated-as-read-only () "Mark generated source files as read only. Mark generated files (lzz or gz) read only to avoid accidental updates." (if (or (string= (file-name-extension (cur-file)) "h") (string= (file-name-extension (cur-file)) "cpp")) (cond ( (file-exists-p (concat (file-name-sans-extension (cur-file)) ".lzz")) (toggle-read-only)) ( (file-exists-p (concat (file-name-sans-extension (cur-file)) ".gz") ) (toggle-read-only)) ) ) ) 

尝试file-exists-p

“如果文件的文件名存在,就返回t(不pipe你是否可以读取它)。”

  • 根据你的需要,你可能需要file-readable-p而不是file-exists-p

  • Apropos只会让你到目前为止。 冰柱提供了apropos完成和渐进式完成 ,让您轻松find与任意顺序(即file-exists-pexists-file-p ?)匹配子部分的命令,函数,variables等名称的帮助。

使用f.el ,现代库进行文件和目录操作。 你可以使用f-exists?f-file?f-directory? 和其他许多谓词。 该库比标准函数更好,因为它是每个文件相关的函数,你将需要在一个命名空间下。