Search code examples
emacs

How do I automatically run a function after manually saving a buffer in Emacs Lisp in a particular mode?


I would like to run untabify on the current buffer on manually saving the buffer. Is there an easy way using Emacs Lisp to run this function as a on-save-hook for elm-mode?

This did not work:

(when (eq (print major-mode) "elm-mode")
   (add-hook 'after-save-hook 'untabify))

Solution

  • First of all, the code you posted cannot work, because (assuming it is written exactly like this in your init file), it will run when Emacs starts; at this point, major-mode is most likely not elm-mode and so no hook gets added.

    Then: print does not return a string. It prints a string, and returns what it was passed as argument. In that case, major-mode is a symbol. To check if the current major-mode is elm-mode, you would do (eq major-mode 'elm-mode), effectively comparing symbols. As a side note, eq is not suitable for string comparison, use string= or string-equal.

    What you would do is add a hook to after-save-hook without condition, and check inside the hook whether or not you should perform the action:

    (add-hook 'after-save-hook (lambda ()
                                 (when (eq major-mode 'elm-mode)
                                   (untabify (point-min) (point-max)))))
    

    You need to give arguments to untabify. In that case, it simply untabifies the whole buffer.

    Another way would be to add a buffer local hook, using something like

    (add-hook 'elm-mode-hook (lambda ()
                               (add-hook 'after-save-hook <my-function> nil t)))
    

    As always: see the manual, accessible from within Emacs in info mode, using describe-function on add-hook, and so on. In general, you will learn a lot if you start by trying to check the built-in documentation.