How to Kill a "Visible" Buffer Quickly in Emacs


/img/2022-04-09-ace-window-selecting-window.png
Selecting Emacs windows using ace-window

Recently I've been building a simple Emacs config for myself, along the way I re-discovered some fantastic packages, for example, I found that ace-window is a simple yet powerful package to enhance the default other-window command to select other windows quickly when it has more than two windows in a frame.

I replaced the key binding of other-window to ace-window by simply doing (global-set-key (kbd "C-x o") #'ace-window), then when there are >2 windows, it will show a white-in-red number at the top-left corner for every window, hit the number (1, 2, 3, …) and then Emacs will select the corresponding window (as demonstrated in the above screenshot).

It's that simple.

But it goes even beyond that. It has two other functions besides selecting windows:

  1. Prefixed with one C-u, swap between the selected window and the current window, so that the selected buffer moves to the current window (and the current buffer moves to the selected window).
  2. Prefixed with two C-u’s, deletes the selected window. (But it does NOT kill the buffer.)

For me, I used case 2 more often. And after using it for a few weeks, I found that I desire another feature: killing a specified buffer in a window (let's call it a "visible" buffer in this post) and keep the window layout unchanged. If you have been annoyed by buffers like *Help* after looking up a function or a key binding, you know what I am talking about.

The way I want to use it is by pressing C-u three times and then selecting a window number, then the buffer in that window is killed.

The advice mechanism is suitable for this simple task. Here is the :around advice that I came up with:

(advice-add #'ace-window :around
            (lambda (oldfun &rest arg)
              "Prefixed with three C-u's, kill the buffer of that window."
              (if (/= 64 (car arg))
                  (apply oldfun arg)
                (save-window-excursion
                  (apply oldfun arg)
                  (kill-buffer))))
            '((name . kill-buffer)))

P.S. It seems that the author @abo-abo doesn't want to have this feature built in as discussed in GitHub issue #146, so I'd rather implement it in an advice.

Emacs 

See also

comments powered by Disqus