This question is inspired by https://emacs.stackexchange.com/a/5947/.

Assume that I have a function like

(defun do-some-actions () ()
(..put a copy of the current file in a specific folder...)

And I would like that the above function to be run after saving files. The following hook can do the job:

(add-hook 'after-save-hook 'do-some-actions)

But in this way Emacs runs the function do-some-action even for the files which have not been manually saved. For instance when I install the packages via Melpa, Emacs itself saves some files with the name package_name-autoloads.el in the directory ~/.emacs.d/elpa/package_name/ and even though these files have not been saved manually, the function do-some-actions is executed.

My question is about the possibility to prevent Emacs to this after-save-hook when the file has not been saved manually.

  • 3
    You can probably create a my-save-buffer wrapper function that first calls (save-buffer) and then does do-some-actions and bind that to C-x C-s in a specific mode map or as a buffer-local binding. – Kaushal Modi Aug 4 '15 at 21:24
  • 4
    Alternatively, define what "saved manually" actually means (it could cover multiple commands, to my mind; M-x apropos-command RET save\|write RET may help), and then test those conditions in your hook function (e.g. by checking whether the this-command value is a member of your list of "saved manually" commands). – phils Aug 4 '15 at 21:34
  • @phils Thank you for mentioning this-command, indeed very useful command. What I had in mind by manually saving was saving via save-buffer (C-x C-s). I think your comment to test if this-command has been save-buffer is the answer of my question. If you are comfortable please feel free to convert your comment to an answer. – Name Aug 4 '15 at 21:57
  • @kaushalmodi thanks for your alternative solution which bypasses after-save-hook. – Name Aug 4 '15 at 22:03

Firstly you need to define what "saved manually" actually means. It could cover multiple commands, to my mind. M-x apropos-command RET save\|write RET probably includes all the typical cases.

Once you know which commands you're interested in, you could simply test the this-command variable in your hook function, to see whether its value is a member of your list of "saved manually" commands.


(defun my-after-save-actions ()
  "Used in `after-save-hook'."
  (when (memq this-command '(save-buffer save-some-buffers))
    ;; put a copy of the current file in a specific folder...

(add-hook 'after-save-hook 'my-after-save-actions)
| improve this answer | |
  • Isn't called-interactively-p what were looking for? – Nordlöw May 11 '16 at 22:53
  • Nordlöw: How would that help? – phils May 11 '16 at 23:11
  • See answer below. – Nordlöw May 11 '16 at 23:21
  • That's fine, but is a completely different approach with a very specific definition of "saved manually". called-interactively-p just isn't relevant to my answer. – phils May 11 '16 at 23:56

Here's an alternative solution:

(defcustom after-save-interactively-hook nil
  "Normal hook that is run after a buffer is saved interactively to its file.
  See `run-hooks'."
  :group 'files
  :type 'hook)

(defun save-buffer-and-call-interactive-hooks (&optional arg)
  (interactive "p")
  (save-buffer arg)
  (when (called-interactively-p 'all)  ;; run post-hooks only if called interactively
    (run-hooks 'after-save-interactively-hook)))

(global-set-key [(control x) (control s)] 'save-buffer-and-call-interactive-hooks)

(defun run-mode-specific-after-save-interactively-buffer-hooks ())

(add-hook 'after-save-interactively-hook 'run-mode-specific-after-save-interactively-buffer-hooks t)

that I use.

| improve this answer | |
  • 1
    I'd suggest that if you've bound C-x C-s to a command you've written yourself, you could be reasonably sure that nothing is going to call that function non-interactively, unless you've written such code yourself (which would be pointless for this particular instance, of course). – phils May 11 '16 at 23:57
  • That won't trigger in cases where saving is invoked by another command, such as C-x # in a server buffer, which is probably not what was desired. – Gilles 'SO- stop being evil' May 12 '16 at 8:06

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.