mail

valettearnaud

Emacs: on-save actions

Sometimes I dream about automatically performing actions after having saved some file from a project.

Each project would have its own behavior:

(defvar my-hash-actions (make-hash-table :test 'equal)
  "Projectile projects on save actions.
PROJECT_NAME->FUNCTION.")

You would link project on-save actions to project names like that:

(my-add-projects-actions
 '("chess" (lambda () (shell-command "source ~/.zshrc && ./build.sh &")))
 '("valettearnaud" (lambda () (org-publish-all)))
 )

The implementation of which would ressembles this:

(defun my-add-project-action (name action)
  "Associate a project NAME with an ACTION (function)."
  (puthash name action my-hash-actions))

(defun my-add-projects-actions (&rest pairs)
  "Associate multiple project NAMES with ACTIONS.
Takes a list of (NAME ACTION) pairs"
  (dolist (pair pairs)
    (let ((name (car pair))
          (action (cadr pair)))
      (my-add-project-action name action))))

And so, you would just add the following function as an after-save-hook :

(defun my-projectile-run-command-on-save ()
  "Run a specific bash command when saving a file inside a Projectile project."
  (when (and (projectile-project-p)
             (buffer-file-name))
    (let* ((project-name (projectile-project-name))
           (action (gethash project-name my-hash-actions)))
      (when action
        (let ((default-directory (projectile-project-root)))
          (funcall action))))))

(add-hook 'after-save-hook 'my-projectile-run-command-on-save)

How many dreams can you make come true with elisp ?


Bonus: Shell buffer

That's always a nice NOT to have your cmake output fill half of your screen for nothing.

(add-to-list 'display-buffer-alist
             '("\\*Async Shell Command\\*"
               (display-buffer-reuse-window display-buffer-in-side-window)
               (side . bottom)
               (window-height . 10)))

(add-to-list 'display-buffer-alist
             '("\\*Shell Command Output\\*"
               (display-buffer-reuse-window display-buffer-in-side-window)
               (side . bottom)
               (window-height . 10)
               (inhibit-same-window . t)))

Created: 2026-07-14 Tue 10:05

Validate