how would I figure this out?
I added 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?
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: ***
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'".
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).
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:
[...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With