如何强制Emacs不在特定窗口显示缓冲区?

18

我的Windows配置如下:

          +----------+-----------+
      |          |           |
      |          |           |
      |          |           |
      |          |           |
      |          |           |
      |          +-----------+
      |          |           |
      +----------+-----------+

我使用右下角的窗口来显示特殊内容(如帮助,自动完成等)。但是当我调用命令(find-file-other-window等)使用display-buffer时,Emacs会坚持使用该窗口,并且还会调整该窗口的大小。这很烦人...有没有办法强制Emacs不使用那个窗口?我想过建议display-buffer,但它是一个C函数。对此有什么想法吗?
编辑: 在Trey的答案的基础上,这是目前适合我的解决方案:
(setq special-display-function 'my-display-buffer)
(setq special-display-regexps '(".*"))

(defun display-special-buffer (buf)
  "put the special buffers in the right spot (bottom rigt)"
    (let ((target-window (window-at (- (frame-width) 4) (- (frame-height) 4)))
          (pop-up-windows t))
      (set-window-buffer target-window buf)
      target-window))

(defun my-display-buffer (buf)
  "put all buffers in a window other than the one in the bottom right"
  (message (buffer-name  buf))
  (if (member (buffer-name buf) special-display-buffer-names)
      (display-special-buffer buf)
      (progn
        (let ((pop-up-windows t)
              (windows (delete (window-at (- (frame-width) 4) (- (frame-height) 4))
                         (delete (minibuffer-window) (window-list)))))
          (message (buffer-name (window-buffer (car windows))))
          (set-window-buffer (car (cdr windows)) buf)
          (car (cdr windows))))))
4个回答

18

嗯,已经有人问过同样的补全问题了。我写了一个答案,似乎效果不错。

看起来你可以使用相同的解决方案,只需将其添加到 special-display-regexps 而不是 special-display-buffer-names 变量中即可。因此,可以尝试以下代码:

(add-to-list 'special-display-regexps '(".*" my-display-buffers))

(defun my-display-buffers (buf)
  "put all buffers in a window other than the one in the bottom right"
  (let ((windows (delete (window-at (- (frame-width) 2) (- (frame-height) 4))
                         (delete (minibuffer-window) (window-list))))
    (if (<= 2 (length windows))
        (progn 
          (select-window (cadr windows))
          (split-window-vertically)))
    (let ((pop-up-windows t))
      (set-window-buffer (car windows) buf)
      (car windows)))))

显然,你需要修改正则表达式以使其不匹配你实际想要在右下窗口中显示的*Help*和其他缓冲区。

关于建议使用display-buffer,这将起作用。你可以建议使用c语言编写的函数,除了从c调用函数或建议宏(这种情况通常无法工作,因为宏通常已经在它们使用的所有地方展开)外,建议几乎适用于你想要的每种情况。


我看到了另一个问题,确实使用了你的解决方案;但我的问题不同。我不是在问如何强制emacs使用一个窗口,而是让emacs不要使用特定的窗口。 - polyglot
没错,我认为Emacs没有排除窗口的能力,所以你必须使用修改过的版本来从窗口列表中排除右下角的窗口。我注意到我在剪切/粘贴时忘记了这样做,让我更新一下。 - Trey Jackson
当你执行(car windows)时,它实际上返回的是当前窗口。但是(car (cdr windows))将完美运行。同时(- (frame-height) 2)有时会找到迷你缓冲区(因为它有时会扩展到2行),所以我用4代替了2。 - polyglot
我在这里问了同样的问题链接。这是解决方案。谢谢! - swdev
如果:let绑定只能有一个值形式:如果,(<= 2(length windows)),(progn(select-window(cadr windows))(split-window-vertically)) - lawlist

3
也许像这样的东西可以起作用:
(defun display-buffer-avoiding-lr-corner (buffer &optional not-this-window)
  (save-selected-window
    (when (buffer-file-name buffer)
      (select-window (window-at (- (frame-width) 1)
                                (- (frame-height) 2))))
    (let ((display-buffer-function nil))
      (display-buffer buffer not-this-window))))

(setq display-buffer-function 'display-buffer-avoiding-lr-corner)

2
我本来想建议使用display-buffer,但它是一个c函数。
"display-buffer is an interactive Lisp function in `window.el'."

此外,您可以以任何方式建议C函数。

我的emacs显示“display-buffer是`C源代码'中的交互式内置函数。”也许是版本差异? - polyglot

2
也许对你来说,将这个右下角的窗口设为专用窗口(set-window-dedicated-p)会更有意义。然后,像你想要的那样,在操作中忽略此窗口,例如find-file-other-window

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接