Emacs: Buffer-switch indicator
Most of the time, I have many windows open in Emacs, so it really helps to have an indicator of the current window (and buffer) especially when switching between windows.
I've created the following elisp
snippet to be used as an advice :around
the function select-window
:
(defun local-buffer-background-indicator-on-buffer-switch-around-advice (func &rest args) "Advice to change background momentarily on buffer switch." (let* ((old-buffer (current-buffer)) (return (apply func args)) (new-buffer (current-buffer)) (case-fold-search t)) (unless (or (eq new-buffer old-buffer) (string-match-p "\\*minibuf" (concat (buffer-name old-buffer) (buffer-name new-buffer)))) (buffer-face-set '(:background "black")) (run-at-time 0.25 nil (lambda () (when (buffer-live-p new-buffer) (with-current-buffer new-buffer (buffer-face-set nil)))))) return))
The function would make the background black for quarter of a second just to indicate the current buffer.
Adding the above as an advice:
(advice-add #'select-window :around #'local-buffer-background-indicator-on-buffer-switch-around-advice)
Notes:
-
The function is
advised :around
select-window
, which is called by all of the usual buffer-switching (e.g.find-file
,find-alternate-file
) and window-switching (e.g.other-window
,next-window
) functions. As a buffer lives inside a window, the advised function is a buffer switching indicator. Understandably, the function could be advised:around
any window-switching function(s) to make it applicable for such case(s). -
The function keeps track of the previous buffer, then calls
select-window
and saves the returned buffer object for eventual return (as buffer objects are self-evaluating), then keeps track of the new buffer.(eq new-buffer old-buffer)
check is needed in case ofterm-mode
(and alike) as it callsselect-window
after each keypress (it needs to send any raw keypress events to the terminal). So we want to avoid highlighting the buffer again and again after any keypress while in theterm-mode
. I also don't want to highlight the minibuffer so ignored such switching from/to minibuffer. -
I use a theme with light black (color hex-code
#1d2021
) background so for me making the background pureblack
(color hex-code#000000
) is fine to indicate the highlighted buffer. This can be changed to suit ones need. -
The background is changed by using the
buffer-face-set
function -- this enables thebuffer-face-mode
minor mode and change any face properties at once. This is basically a shortcut for setting the buffer-local variablebuffer-face-mode-face
to set any face properties and then enabling thebuffer-face-mode
. For example, in our case,(buffer-face-set '(:background "black"))
would be analogous to:
(setq-local buffer-face-mode-face '((:background "black"))) (buffer-face-mode 1)
-
When it's time to disable the highlighting of the buffer,
buffer-face-set
is called withnil
as argument to disable thebuffer-face-mode
. This is done after quarter of a second (usingrun-at-time
) and can be increased/decreased as needed. -
Prior to changing the background of the whole buffer, I tried to keep things minimal by only changed the background of the
mode line
(leveraging themode-line-active
andmode-line-inactive
faces) but it looked at bit flaky when multiple horizontal/vertical splits are present.
References:
select-window
:around
adviceterm-mode
- Minibuffer
buffer-face-set
buffer-face-mode
buffer-face-mode-face
run-at-time
- Mode line
mode-line-active
/mode-line-inactive
faces
Comments
Comments powered by Disqus