According to the write-file-functions doc-string, "[t]his variable's value is permanent if it is given a local binding."

  • Step 1: Start from emacs -q using Emacs 25.2.1.

  • Step 2: Switch to the *scratch* buffer.

  • Step 3: Type the following in the *scratch* buffer, so that it gets modified and so that we can later evaluate what we typed.

    (add-hook 'write-file-functions (lambda () (message "hello-world")) 'append 'local)

  • Step 4: Evaluate the statement that we typed in Step 3 above -- e.g., C-x C-e

  • Step 5: M-x save-buffer and save it anywhere that is appropriate. I chose to call the file foo and I saved it as ~/Desktop/foo

  • Step 6: M-x describe-variable RET write-file-functions RET; or, C-h v and then the name of the variable we are looking up.

    write-file-functions is a variable defined in ‘files.el’.

    Its value is nil

I expected the write-file-functions hook to maintain the original value because it is permanent when given a local binding. Why is my assumption incorrect?


C-hv write-file-functions

write-file-functions is a variable defined in ‘files.el’.

This variable’s value is permanent if it is given a local binding.
This variable may be risky if used as a file-local variable.

List of functions to be called before saving a buffer to a file.
Only used by ‘save-buffer’.

If one of them returns non-nil, the file is considered already written and the rest are not called.

These hooks are considered to pertain to the visited file. So any buffer-local binding of this variable is discarded if you change the visited file name with M-x set-visited-file-name, but not when you change the major mode.

This hook is not run if any of the functions in ‘write-contents-functions’ returns non-nil. Both hooks pertain to how to save a buffer to file, for instance, choosing a suitable coding system and setting mode bits. (See Info node ‘(elisp)Saving Buffers’.) To perform various checks or updates before the buffer is saved, use ‘before-save-hook’.


No explanation, but here are some observations:

  1. I can reproduce this with emacs -Q.

  2. In the help to this var is stated: This variable may be risky if used as a file-local variable.
    This line is added dynamically, it is not stated in the source files.el

  3. You are saving a buffer without a file (*scratch*) to a file. The buffer *scratch* does not exist afterwards, but you have a new buffer called foo.

    If you redo your (add-hook ...) inside the new buffer foo and then save the foo buffer with the already given name, this write-file-functions variable keeps it value.

  4. Doing the same with a local variable (set (make-local-variable 'foo) "value") keeps the variable value always.

And then, I do not know emacs nor elisp good enough. :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.