如何在Emacs中控制弹出buffer位置
缘起
org-agenda
是每天都要用的,如果不做设置的话,有时会在下部打开,因此需要做一定的配置才可以在右侧打开。原先我抄到的配置是:
(setq split-height-threshold nil)
(setq split-width-threshold 0)
split-height-threshold
和 split-width-threshold
这两个变量来控制窗口切分的行为。如果这两个变量的值是一个整数,比如默认值是80和160,则表示,如果当前窗口高度大于80行,则水平切分,如宽度大于160列,则垂直切分。如果这个值是nil,则表示永远不在水平或垂直方向切分。
这种做法是强制将所有的buffer都在垂直切分,并在右侧打开。这就造成了插入日期的 Calendar
buffer也在右侧打开,这就比较难看。其实有更精确的控制方法。
使用 display-buffer-alist
来控制buffer的行为
在: https://emacs-china.org/t/org-capture-buffer/24645/6 中,有人提问如何设置 org-capture
弹出的位置,Pygmalion 提出了解决方案:
控制org capture弹出的org select 和 capture 这两个buffer的大小和位置有以下三种解决方案。
- 配置display-buffer-alist变量,可同时控制两个buffer的位置和大小,无需安装插件。配置如下:
(add-to-list 'display-buffer-alist '("*Org Select*" (display-buffer-in-side-window) (window-height . 0.4) (side . bottom)) '("CAPTURE-*" (display-buffer-in-side-window) (window-height . 0.4) (side . bottom)))
可以让Org Select和Capture buffer都弹出在bottom。
- 配置display-buffer-alist变量控制org select buffer位置,配置split-width-threshold变量控制capture buffer位置(但不能控制其大小)
;; 控制 org select buffer (add-to-list 'display-buffer-alist '("*Org Select*" (display-buffer-in-side-window) (window-height . 0.4) (side . bottom))) ;; 控制 org capture buffer (setq split-width-threshold nil)
- 安装popper插件,可控制两个buffer的位置,大小无法控制,配置代码如下:
(use-package popper :ensure t ; or :straight t :bind (("C-`" . popper-toggle-latest) ("M-`" . popper-cycle) ("C-M-`" . popper-toggle-type)) :init (setq popper-reference-buffers '(("\\*Org Select\\*" org-mode) ("CAPTURE" org-mode) )) (popper-mode +1) (popper-echo-mode +1))
我用的第二种方案。第一个方案里的condition我试了下写combined condition不起作用,只好分别写了两段代码。
配置分析
可以看出,这个配置其实中是 display-buffer-alist
进行了定义,其中第一行,如 '("CAPTURE-*"
表示,这个定义针对的buffer范围,比如这个就针对 Capture buffer的。
(side . bottom)
表示新窗口打开的位置,这里就是在下方打开,当然也可以是 left 或 right
(window-height . 0.4)
表示这个窗口的大小,这里表示窗口高度是整个窗口的40%。如果你定义了左右侧打开的话,那么就要定义 window-width
了。
解决方案
如果按照上面的配置设置会出现一个问题,就是新开的buffer是以当前frame的side window的形式打开的,它无法单独的存在。即,如果光标在agenda的一个todo任务中,此时如果按 t
它会关闭其它buffer并让你选择要修改的 todo 状态。但如果是side window的话,会提示:“delete-other-windows: Cannot make side window the only window”
想到 org-roam 也有类似的配置来控制 org-roam-buffer 的行为,查看了后,它使用的是 (display-buffer-in-direction),并不会出现上述问题。除了这两个显示行为外,也可以自行 C-h f
查找 display-buffer
查看所有的显示行为。
回到最初的需求,想让 Org Agenda 在右侧打开,可以加上如下配置:
(add-to-list 'display-buffer-alist
'("Org Agenda"
(display-buffer-in-direction)
(window-width . 0.5)
(direction . right)))