emacs: is before-save-hook a local variable?
how would I figure this out?
I a开发者_如何学JAVAdded delete-trailing-whitespace
to the before-save-hook
in my c-mode-common-hook
, but it looks like delete-trailing-whitespace
is getting called for every file, not just buffers using c-mode and derivatives.
Can I make the before-save-hook
buffer local?
Add it to write-contents-functions
instead:
(add-hook 'c-mode-common-hook
(lambda()
(add-hook 'write-contents-functions
(lambda()
(save-excursion
(delete-trailing-whitespace)))
nil t)))
As the Emacs Lisp Reference Manual explains:
This works just like write-file-functions, but it is intended for hooks that pertain to the buffer's contents, not to the particular visited file or its location. Such hooks are usually set up by major modes, as buffer-local bindings for this variable. This variable automatically becomes buffer-local whenever it is set; switching to a new major mode always resets this variable, but calling set-visited-file-name does not.
This works properly for me in Emacs 24.2.1 (i.e., it deletes all trailing whitespace from C files but preserves trailing whitespace in all other file types).
No, the variable before-save-hook
is not naturally buffer local. The variable's documentation does not say it's buffer local or say it will automatically become buffer local when set.
If you want to add a buffer-local hook to it, the correct way to do this is just to use the optional LOCAL parameter of the standard add-hook
function:
(add-hook 'before-save-hook 'foo nil t)
The add-hook documentation says:
The optional fourth argument, LOCAL, if non-nil, says to modify the hook's buffer-local value rather than its global value. This makes the hook buffer-local, and it makes t a member of the buffer-local value. That acts as a flag to run the hook functions of the global value as well as in the local value.
The selected answer to add it to local-write-file-hooks
is wrong, I believe. If you look at the documentation for that function, on emacs 24.3, it says the variable is obsolete since 22.1, and you should use write-file-functions
. And if you lookup the documentation of write-file-functions
, it describes more complex behavior and says at the end that "To perform various checks or updates before the buffer is saved, use `before-save-hook'".
Never wanted to do this before, but this should work:
(set (make-local-variable 'before-save-hook) '((lambda() (rg-msg "foobie"))))
In general C-h v will prompt for a variable name and display a description telling you whether the var is buffer-local.
before-save-hook is a variable defined in `files.el'. Its value is nil
This variable is potentially risky when used as a file local variable.
Documentation: Normal hook that is run before a buffer is saved to its file.
You can customize this variable.
vs.
next-error-function is a variable defined in `simple.el'. Its value is nil
Automatically becomes buffer-local when set in any fashion. This variable is potentially risky when used as a file local variable.
Documentation: Function to use to find the next error in the current buffer. The function is called with 2 parameters:
[...]
Yes create a .dir-locals.el
file in your project root directory with this contents:
((c-mode . ((before-save-hook . (lambda() (delete-trailing-whitespace)) )) ))
This will add this hook only to c-mode
buffers below this directory.
But if you only want a specific file and not a whole directory you should be able to add this to top of file using File Local Variables:
-*- eval: (setq before-save-hook (lambda() (delete-trailing-whitespace))); -*-
or bottom of file like this:
;;; Local Variables: ***
;;; eval: (setq before-save-hook (lambda() (delete-trailing-whitespace))) ***
;;; End: ***
Use write-contents-function
instead:
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'.
You should create a wrapper to call delete-trailing-whitespace
as you want to ensure that you return nil
from the wrapper, so that further processing (and eventual saving) takes place.
精彩评论