Search code examples
emacswhitespacemode

emacs only delete-trailing-whitespace while saving in programming mode


following line removes all training white space while saving.

(add-hook 'write-file-hooks 'delete-trailing-whitespace)

but I want to hook this feature only when i'm in programming mode, so i did

(defun nuke_traling ()
  (add-hook 'write-file-hooks 'delete-trailing-whitespace) 
)

(add-hook 'prog-mode-hook 'nuke_traling)

which doesn't is not stopping which are not in programming mode.


Solution

  • Making the hook variable buffer-local has been mentioned. Don't do that. Or rather, don't do it using make-local-variable.

    The normal hook mechanisms have buffer-local support built in -- that's the purpose of the LOCAL argument to add-hook. When the hook is run, it runs both the global and the buffer-local values.

    So taking the example code in the question, you could change it to use:

    (add-hook 'write-file-hooks 'delete-trailing-whitespace nil t)
    

    And then delete-trailing-whitespace would be called whenever write-file-hooks was run, but only in the buffers in which prog-mode-hook had run.

    However there are better ways to achieve this.

    I agree with Drew that you are better to test whether your mode is derived from prog-mode, and with juanleon that before-save-hook is a better hook to use. So you might do something like:

    (add-hook 'before-save-hook 'my-prog-nuke-trailing-whitespace)
    
    (defun my-prog-nuke-trailing-whitespace ()
      (when (derived-mode-p 'prog-mode)
        (delete-trailing-whitespace)))
    

    But what I actually recommend is using either ws-trim or ws-butler to take care of this in a smarter way.

    Blindly removing all trailing whitespace from a file is a great way to wind up committing loads of unrelated lines to a version-control repository. Both of the libraries mentioned will ensure that your own commits are free of trailing whitespace, without also introducing unwanted modifications elsewhere in the file.