如何使`C-x b RET`切换到先前的缓冲区,即使它已经在另一个窗口中显示了?

时间:2014-12-26 18:29:59

标签: emacs

简而言之,问题是:在一个窗口中,如何快速切换到之前在该窗口中访问过的缓冲区,即使它已经在另一个窗口中打开过了?

更详细的描述如下。

通常,为了将窗口切换到上一个缓冲区,只需键入C-x b RET即可。也就是说,switch-to-buffer(或ido-switch-buffer)的默认参数是前一个缓冲区。

但是,当(前一个)缓冲区已经显示在另一个窗口中时,情况并非如此。这正是让我烦恼的原因。

让我们考虑一个例子。假设我有三个缓冲区(ABC),两个窗口显示缓冲区ABC在这一点)。

然后我也在第二个窗口中打开缓冲区A。所以,现在我在两个窗口中都显示了缓冲区A。然后我再次(C-x b RET)切换到B。在此之后,C-x b RET将不会A,而是C,因为A已经显示在其他窗口中。

如何让C-x b RET表现得更一致?

更新

在这个问题解决之后,我意识到我需要更多:即,每个窗口记住点位置,而不是每个缓冲区。幸运的是,有现成的解决方案:

他们非常相似;有关差异的讨论,请参阅here

2 个答案:

答案 0 :(得分:4)

我找到了switch-to-buffer的修复程序。它最终调用

(other-buffer (current-buffer))

虽然为了解决您的问题,通话需要看起来像这样:

(other-buffer (current-buffer) t)

即。 visible-ok参数必须为t

以下建议始终在t。希望它不会破坏使用other-buffer的其他内容:

(defadvice other-buffer (around fix-switch-to-buffer 
                          (&optional buffer visible-ok frame) activate)
  (setq visible-ok t)
  ad-do-it)

请注意ido-switch-to-buffer使用不同的机制,因此需要使用其他方法来修复它。

更新:修复ido-switch-to-buffer

我需要重新定义ido-make-buffer-list

(defun ido-make-buffer-list (default)
  (let* ((ido-current-buffers (list (buffer-name (current-buffer))))
         (ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
    (if ido-temp-list
        (nconc ido-temp-list ido-current-buffers)
      (setq ido-temp-list ido-current-buffers))
    (if default
        (setq ido-temp-list
              (cons default (delete default ido-temp-list))))
    (if (bound-and-true-p ido-enable-virtual-buffers)
        (ido-add-virtual-buffers-to-list))
    (run-hooks 'ido-make-buffer-list-hook)
    ido-temp-list))

差异只是一行,但建议它太乱了。

更新:使用other-buffer

的新建议系统

旧的东西应该还有一段时间了,但这是新的方法:

(defun other-buffer-advice (orig-fun &optional buffer visible-ok frame)
  (funcall orig-fun buffer t frame))
(advice-add 'other-buffer :around #'other-buffer-advice)
;; (advice-remove 'other-buffer :around #'other-buffer-advice) 

答案 1 :(得分:1)

Ido mode中执行此操作时有两种可能性:

1切换到另一帧中显示的缓冲区

如果通过" window"你的意思是"框架" (即,您希望将ido-switch-buffer添加到当前在另一帧中显示的缓冲区中),然后ido-mode会为您提供您在更改{{1}时所寻找的行为从默认值ido-default-buffer-methodraise-frame

selected-window

Emacs为每个帧构建一个独立的缓冲区列表,因此您唯一需要做的就是配置Ido以避免在切换缓冲区时跳转到另一个帧。

2切换到同一帧内另一个窗口中显示的缓冲区

要在同一帧内的窗口中获得此行为,您应该挂钩一个将缓冲区列表重新排序到(setq ido-default-buffer-method 'selected-window) 的函数。

来自ido-make-buffer-list-hook

ido.el