emacs:是pre-save-hook一个局部变量?

时间:2009-12-19 02:54:50

标签: emacs elisp

我怎么知道这个?

我已将delete-trailing-whitespace添加到before-save-hook中的c-mode-common-hook,但看起来delete-trailing-whitespace正在调用每个文件,而不仅仅是使用c模式和衍生物的缓冲区。

我可以将before-save-hook缓冲区设为本地吗?

5 个答案:

答案 0 :(得分:20)

将其添加到write-contents-functions

(add-hook 'c-mode-common-hook
  (lambda()
    (add-hook 'write-contents-functions
      (lambda()
        (save-excursion
          (delete-trailing-whitespace)))
      nil t)))

正如Emacs Lisp参考手册所述:

  

这就像写文件函数一样,但它适用于与之相关的钩子   缓冲区的内容,而不是特定的访问文件或其位置。这样的钩子是   通常由主要模式设置,作为此变量的缓冲区本地绑定。这个变量   每当设置时自动变为缓冲区本地;切换到新的主要模式   总是重置此变量,但调用set-visited-file-name不会。

这在Emacs 24.2.1中适用于我(即,它从C文件中删除所有尾随空格,但在所有其他文件类型中保留尾随空格)。

答案 1 :(得分:17)

不,变量before-save-hook本身不是缓冲区。变量的文档并没有说它是本地的缓冲区,或者说它在设置时会自动变为缓冲区本地。

如果要为其添加缓冲区本地挂钩,正确的方法是使用标准add-hook函数的可选LOCAL参数:

(add-hook 'before-save-hook 'foo nil t)

add-hook文档说:

  

可选的第四个参数LOCAL,如果是非nil,则说要修改   hook的缓冲区本地值而不是其全局值。   这使得hook buffer-local,并且它成为了一个成员   缓冲区本地值。这充当了运行钩子的标志   全局价值的函数以及本地价值。

我认为,选择将其添加到local-write-file-hooks的答案是错误的。如果你查看该函数的文档,在emacs 24.3上,它说该变量自22.1以来已经过时,你应该使用write-file-functions。如果查找write-file-functions的文档,它会描述更复杂的行为,并在最后说“要在保存缓冲区之前执行各种检查或更新,请使用`before-save-hook'”。

答案 2 :(得分:3)

以前从不想这样做,但这应该有效:

(set (make-local-variable 'before-save-hook) '((lambda() (rg-msg "foobie")))) 

一般情况下,C-h v会提示输入变量名称,并显示一条描述,告诉你var是否是缓冲区本地的。

  

before-save-hook是一个定义的变量   在`files.el'中。它的值是零

     

此变量具有潜在风险   当用作文件局部变量时。

     

文档:正常运行的钩子   在将缓冲区保存到其文件之前。

     

您可以自定义此变量。

VS

  

next-error-function是一个变量   在`simple.el'中定义。它的价值在于   零

     

自动成为缓冲区本地   以任何方式设置。这个   变量具有潜在风险   用作文件局部变量。

     

文档:用于查找的函数   当前缓冲区中的下一个错误。   该函数用2调用   参数:

     

[...]

答案 3 :(得分:0)

改为使用write-contents-function

write-contents-functions is a variable defined in `files.el'.
Its value is nil

  Automatically becomes buffer-local when set in any fashion.

Documentation:
List of functions to be called before writing out a buffer to a file.
If one of them returns non-nil, the file is considered already written
and the rest are not called and neither are the functions in
`write-file-functions'.

This variable is meant to be used for hooks that pertain to the
buffer's contents, not to the particular visited file; thus,
`set-visited-file-name' does not clear this variable; but changing the
major mode does clear it.

For hooks that _do_ pertain to the particular visited file, use
`write-file-functions'.  Both this variable and
`write-file-functions' relate to how a buffer is saved to file.
To perform various checks or updates before the buffer is saved,
use `before-save-hook'.

您应该创建一个包装来调用delete-trailing-whitespace,以确保从包装器返回nil,以便进一步处理(并最终保存)。

答案 4 :(得分:0)

是,在项目根目录中使用以下内容创建一个.dir-locals.el文件:

((c-mode . ((before-save-hook . (lambda() (delete-trailing-whitespace)) )) ))

这只会将此钩子添加到此目录下的c-mode缓冲区中。

但是,如果您只想要一个特定文件而不是整个目录,则应该可以使用“文件局部变量”将此文件添加到文件顶部:

-*- eval: (setq before-save-hook (lambda() (delete-trailing-whitespace))); -*-

或文件底部,如下所示:

;;; Local Variables: ***
;;; eval: (setq before-save-hook (lambda() (delete-trailing-whitespace))) ***
;;; End: ***