I recently have been working in a Clojure project which is made up of several microservices. While trying to build in a secure method for each service to be able to call the others, I’ve been in several different projects at the same time.
At least once I accidentally opened the wrong “handler.clj” buffer, and spent a few minutes adding a function that never worked. Since I hate doing things like this, I wanted a simple way to see what project I was currently viewing.
I started with a changing the title of the frame to show the whole path of the current buffer, like this:
The code to change the title is simple, and the default in some of the pre-packaged emacs bundles:
(setq frame-title-format '((:eval (if (buffer-file-name) (abbreviate-file-name (buffer-file-name)) "%b"))))
This is fine, but still not great. The font is tiny and the important part: “octopress” is buried. I wanted something a little more fluid, so I could easily tell the different projects apart instantly. I came up with the idea to color the background faintly different based on the path of the file. Files with a path containing “octopress” might be different from those containing “.emacs”.
buffer-face-mode makes it easy to change a single
property of a single buffer’s face without changing any other
buffer. So long as you disable buffer-face-mode when closing emacs,
your files will open with the correct coloring scheme, then have the
new background overlaid.
While not perfect, this was the result.
The colors I choose are only faintly different, but just enough for me to tell instantly which is which.
The buffer colors are applied when opening a file, using these functions:
(defun my-buffer-face-mode-variable (color) (interactive) (setq buffer-face-mode-face (list :background color)) (buffer-face-mode 1)) (defun my-set-theme-on-mode () (interactive) (let ((file-name (buffer-file-name))) (cond ;; add your own project/color mappings here ((string-match "halcyon" file-name) (my-buffer-face-mode-variable "#00001A")) ((string-match "dwarf" file-name) (my-buffer-face-mode-variable "#001A1A")) ((string-match "nimbus" file-name) (my-buffer-face-mode-variable "black")) (t ""))))
To force them to run when opening a file, since I use helm, I set it to execute on exiting helm for any reason:
(add-hook 'helm-after-action-hook 'my-set-theme-on-mode) ;; uncomment if not using helm ;; (add-hook 'find-file-hook 'my-set-theme-on-mode)
Lastly, to make sure emacs applies my normal theme and settings to a buffer when starting, I disable buffer-face-mode on all buffers before exiting.
(defun disable-all-buffer-face-mode () (interactive) (let ((current (get-buffer (current-buffer)))) (-map (lambda (x) (progn (switch-to-buffer x) (buffer-face-mode 0))) (buffer-list)) (switch-to-buffer current 1))) (add-hook 'kill-emacs-hook 'disable-all-buffer-face-mode)
This block needs dash.el to get the -map function.
While not the only solution, this seemed a simple and elegant way to quickly be reminded of your current project.