29.17.3 带侧边窗口的框架布局

侧边窗口可用于创建更复杂的框架布局,类似集成开发环境(IDE)。 在这类布局中,主窗口区域用于常规编辑活动。 侧边窗口并非为普通编辑设计,而是用于显示与当前编辑互补的信息,如文件列表、标签、缓冲区列表、帮助信息、搜索或 grep 结果、shell 输出等。

这类框架的布局大致如下:

     ___________________________________
    |          *Buffer List*            |
    |___________________________________|
    |     |                       |     |
    |  *  |                       |  *  |
    |  d  |                       |  T  |
    |  i  |                       |  a  |
    |  r  |   Main Window Area    |  g  |
    |  e  |                       |  s  |
    |  d  |                       |  *  |
    |  *  |                       |     |
    |_____|_______________________|_____|
    | *help*/*grep*/  |  *shell*/       |
    | *Completions*   |  *compilation*  |
    |_________________|_________________|
    |             Echo Area             |
    |___________________________________|


下面的示例展示了如何结合窗口参数(see 窗口参数)与 display-buffer-in-side-window(see 在侧边窗口中显示缓冲区)编写代码,实现上述布局。

(defvar parameters
  '(window-parameters . ((no-other-window . t)
                         (no-delete-other-windows . t))))

(setq fit-window-to-buffer-horizontally t)
(setq window-resize-pixelwise t)

(setq
 display-buffer-alist
 `(("\\*Buffer List\\*" display-buffer-in-side-window
    (side . top) (slot . 0) (window-height . fit-window-to-buffer)
    (preserve-size . (nil . t)) ,parameters)
   ("\\*Tags List\\*" display-buffer-in-side-window
    (side . right) (slot . 0) (window-width . fit-window-to-buffer)
    (preserve-size . (t . nil)) ,parameters)
   ("\\*\\(?:help\\|grep\\|Completions\\)\\*"
    display-buffer-in-side-window
    (side . bottom) (slot . -1) (preserve-size . (nil . t))
    ,parameters)
   ("\\*\\(?:shell\\|compilation\\)\\*" display-buffer-in-side-window
    (side . bottom) (slot . 1) (preserve-size . (nil . t))
    ,parameters)))

这段代码为固定名称的缓冲区设置了 display-buffer-alist 条目(see 为显示缓冲区选择窗口)。 具体来说: 在框架顶部显示 *Buffer List*,高度自适应; 在框架右侧显示 *Tags List*,宽度自适应; 让 *help**grep**Completions* 共享底部左侧边窗; 让 *shell**compilation* 显示在底部右侧边窗。

注意,必须将 fit-window-to-buffer-horizontally 设为非 nil,才能让窗口支持水平自适应调整。 同时设置了保留顶部/底部边窗高度、左右边窗宽度的条目。 为确保最大化框架时侧边窗口保持尺寸,将 window-resize-pixelwise 设为非 nil。See 调整窗口大小

最后一段代码还为所有创建的侧边窗口设置了 no-other-window 参数,使其无法通过 C-x o 切换到; 并设置了 no-delete-other-windows 参数,使其不会被 C-x 1 删除。

由于 dired 缓冲区没有固定名称,我们使用专用函数 dired-default-directory-on-left 在框架左侧显示精简的目录缓冲区。

(defun dired-default-directory-on-left ()
  "Display `default-directory' in side window on left, hiding details."
  (interactive)
  (let ((buffer (dired-noselect default-directory)))
    (with-current-buffer buffer (dired-hide-details-mode t))
    (display-buffer-in-side-window
     buffer `((side . left) (slot . 0)
              (window-width . fit-window-to-buffer)
              (preserve-size . (t . nil)) ,parameters))))

依次执行以上代码,并按任意顺序键入: M-x list-buffersC-h fM-x shellM-x list-tagsM-x dired-default-directory-on-left, 即可复现上述框架布局。