Emacs bury-all

使用 emacs 时,经常会打开一些特殊的 buffer,比如 magit、rg、compilation。这些 buffer 都有自己的 keymap。如果使用了模态编辑插件(modalka、evil 等),很容易在这些 buffer 触发误操作。所以我个人的习惯是这一类 buffer 用完即关。

目前关掉这些 buffer 的方式有些低效,需要多次操作。比如下面图中左侧是普通 buffer,右侧是 rg,当前活跃的是左侧窗口,如果要关闭 rg,需要先跳到右侧,再按下 q

另外当打开了多个 magit buffer 时,需要在每个 magit buffer 里面都按下 q ,才可以关闭所有的 magit buffer。

因此实现了下面这个 bury all 的操作,不管当前在哪个窗口,只要按一个键就可以关掉所有的这一类 buffer。之所以叫 bury all 是因为 emacs 的 buffer 并不是真的退出,而是把这些 buffer 放在 buffer list 的最下层不展示出来而已,的确是 bury。

(defun jxq-bury-window-buffers (window)
  (let ((continue t))
    (while (and continue (window-valid-p window))
      (when-let ((buff (window-buffer window)))
        (if (with-current-buffer buff
              (memq (keymap-local-lookup "q")
                    (list #'magit-mode-bury-buffer
                          #'magit-log-bury-buffer
                          #'quit-window)))
            (progn
              (quit-window nil window))
          (setq continue nil))))))

(defun jxq-bury-all ()
  (interactive)
  (mapcar #'jxq-bury-window-buffers (window-list)))

实现原理很简单,通过 window-list 函数遍历所有 window,看当前展示的 buffer 是否有给 q 键定义 keymap,如果 q 映射到的是诸如 quit-window 这样的函数,那就说明 buffer 是可以 bury 的。