【问题标题】:emacs: is before-save-hook a local variable?emacs:before-save-hook 是局部变量吗?
【发布时间】:2009-12-19 02:54:50
【问题描述】:

我该如何解决这个问题?

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

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

【问题讨论】:

  • 还有ws-trim,就是我用的:ftp.lysator.liu.se/pub/emacs/ws-trim.el
  • 钩子是否是缓冲区本地的问题是错误的:所有钩子都是。问题是您添加到其中的函数是添加到缓冲区局部部分还是全局部分(这取决于您传递给add-hooklocal 参数)。

标签: emacs elisp


【解决方案1】:

改为将其添加到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 参考手册所解释的:

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

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

【讨论】:

  • 谢谢;我更正了 EmacsWiki 上的相应错误,并在此处指出了功劳。
  • (几乎)所有的钩子都是本地的和全局的。只需使用local' argument of add-hook' 来说明您是要全局添加函数还是本地缓冲区。 local-write-file-hooks 自 Emacs-22.1 以来已过时,write-file-hooks(已替换为 write-file-functions),因此您可能需要更新参考手册。
【解决方案2】:

不,变量before-save-hook 自然不是本地缓冲区。变量的文档没有说它是本地缓冲区,也没有说设置后它会自动变为本地缓冲区。

如果你想给它添加一个本地缓冲区钩子,正确的做法就是使用标准add-hook函数的可选LOCAL参数:

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

附加钩子文档说:

可选的第四个参数 LOCAL,如果非 nil,表示要修改 挂钩的缓冲区本地值而不是其全局值。 这使钩子成为局部缓冲区,并且使 t 成为 缓冲区本地值。作为运行钩子的标志 全局值和局部值的函数。

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

【讨论】:

  • 有一个问题,我什至会说这是一个关于LOCAL arg 的错误。你看,用非零调用 LOCAL 使它创建 new empty 变量,然后添加你的钩子。也就是说,如果您有任何其他钩子,它们将在缓冲区中消失。因此,您可能希望使用make-local-variable,然后使用纯add-hook,而不需要任何额外的参数。
【解决方案3】:

以前从未想过这样做,但这应该可以:

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

通常 C-h v 会提示输入变量名并显示说明,告诉您该 var 是否为缓冲区本地。

before-save-hook 是一个定义的变量 在“files.el”中。它的值为nil

这个变量有潜在的风险 用作文件局部变量时。

文档:运行的普通挂钩 在将缓冲区保存到其文件之前。

您可以自定义此变量。

对比

next-error-function 是一个变量 在“simple.el”中定义。它的值为 无

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

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

[...]

【讨论】:

  • 我不确定这在编写时是否正确,但当前文档指出“不要使用 make-local-variable 来制作挂钩变量缓冲区本地。而是使用 @987654323 @ 并为 LOCAL 参数指定 t。"
  • 对钩子的弃用 make-local-variable 可以追溯到 Emacs-21。
【解决方案4】:

是的,在您的项目根目录中创建一个 .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: ***

【讨论】:

    【解决方案5】:

    改用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,以便进行进一步处理(并最终保存)。

    【讨论】:

    • 为什么要使用 write-contents-functions 而不是 local-write-file-hooks?
    猜你喜欢
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    相关资源
    最近更新 更多