【问题标题】:prevent emacs commands from showing new buffers in other windows防止 emacs 命令在其他窗口中显示新缓冲区
【发布时间】:2014-02-13 17:59:49
【问题描述】:

我在控制台模式下使用 emacs(即没有鼠标,一帧),具有固定的四个窗口配置:

+------+------+ |赢|赢| | 1 | 3 | +------+------+ |赢|赢| | 2 | 4 | +------+------+

窗口 3 是我的主要编辑窗口,我大部分时间都在那个窗口中度过。 Windows 1 和 2 一直保持相同的两个缓冲区,我很少更改这些窗口,因为缓冲区会自动更新,并且它们包含只读信息。 Windows 4 是我的附属窗口,很高兴大多数打开新缓冲区的 emacs 命令(例如 grep、编译命令等)总是在窗口 4 中显示新缓冲区。这让生活变得非常轻松,因为我绑定了 F12 直接在窗口 3 和窗口 4 以及后面。

坏家伙是 psvn.el。 svn-status 缓冲区总是根据需要在窗口 3 中打开。
但是所有其他缓冲区(*svn-diff*、*svn-log*、...)在窗口 1、2 或 3 中随机打开,我永远无法预测它们会在哪个窗口中打开。有时,甚至同时在其中两个窗口上显示相同的缓冲区,这让我抓狂!

我如何告诉 emacs/psvn 停止这样做?我尝试了所有常用的措施(调整相同的窗口缓冲区名称、拆分高度阈值、拆分宽度阈值……),但到目前为止没有任何效果:-(

请不要有涉及 ecb 的解决方案。

【问题讨论】:

  • 要完全控制某些缓冲区的显示方式,您可以进入psvn.el 的源代码并使用display-buffer 系列函数对其进行修改(或创建新函数)。以下是两个最近线程的链接,我和其他线程参与者给出了如何在给定窗口中显示特定缓冲区的示例(或者如果它不存在则创建一个新窗口):stackoverflow.com/a/21544307/2112489stackoverflow.com/a/21591259/2112489其他选择,但从源头上扼杀萌芽是我处理事情的首选方式。
  • 例如,问题源代码的作者似乎对pop-to-buffer 有个人偏好——您可以将其替换为您自己的显示缓冲区功能。您可能需要调整代码的其他部分,但这是一般的想法。

标签: svn emacs


【解决方案1】:

根据@lawlist 所说,这里有一个示例,说明如何通过编写自己的display-buffer 函数并向display-buffer-alist 添加一个元素来覆盖display-buffer 功能。

这里我们有一个交互函数,它将当前选择的窗口标记为“卫星”窗口:

(defun mark-this-window-as-satellite ()
  "Mark the current window as the satellite window."
  (interactive)
  (mapc (lambda (win) (set-window-parameter win 'satellite nil))
    (window-list))
  (set-window-parameter nil 'satellite t)
  (message "Window: %s is now the satellite window." (selected-window)))

这是一个帮助我们扫描并找到卫星窗口的助手:

(defun get-satellite-window ()
  "Find and return the satellite window or nil if non exists."
  (find-if (lambda (win) (window-parameter win 'satellite)) (window-list)))

然后我们编写一个函数来覆盖display-buffer 的行为。这个函数将寻找一个卫星窗口并在那里显示缓冲区:

(defun display-buffer-in-satellite (buffer ignore)
  "Display the buffer in the satellite window, or the first window \
    it finds if there is no satellite."
  (let ((satellite-window (or (get-satellite-window)
                              (first (window-list)))))
    (select-window satellite-window)
    (display-buffer-same-window buffer nil)
    (display-buffer-record-window 'reuse satellite-window buffer)
    satellite-window))

最后,您需要向display-buffer-alist 添加一个正则表达式/函数对,这将使您的所有 SVN 缓冲区都使用新的卫星函数:

(push '("\\*svn-" display-buffer-in-satellite) display-buffer-alist)

您也可以为其他烦人的模式添加类似的元素。

【讨论】:

  • 虽然display-buffer-function 目前在最新版本的 Emacs Trunk 中可用,但 Emacs 团队计划在未来某个时候弃用它,并由 display-buffer-alist 取代。话虽如此,我认为没有理由不使用它,因为它仍然是一个可用的选项。摘自window.el:(make-obsolete-variable 'display-buffer-function 'display-buffer-alist "24.3")
  • IIUC 你应该可以用(push '("\\*svn-" display-buffer-in-satellite) display-buffer-alist)得到同样的结果。
  • 我不知道,这似乎是一个更好的选择,我已经改变了答案。
  • 另一个注意事项:看起来您只使用一个框架,但以防万一。您可以映射window-list' across frame-list' 以获取所有框架中的所有窗口。
【解决方案2】:

也许您可以将窗口 1 和 2 标记为专用。这将防止任何更改它们显示的缓冲区(您甚至需要在您想使用 C-xb手动切换缓冲区的事件中取消它们的专用性 - 据说很少见>)。

如果您安装了dedicated-mode,只需在相关窗口中运行M-xdedicated-mode

如果没有,您可以定义自己的小函数来将窗口标记为专用:

(defun my-dedicated-window-toggle ()
  "Toggle `window-dedicated-p' in the current window"
  (interactive)
  (set-window-dedicated-p
    (selected-window)
    (not (window-dedicated-p))))

【讨论】:

    猜你喜欢
    • 2011-03-02
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多