11

我想对 Emacs 做一个简单的更改,以便next-bufferandprevious-buffer命令(我已经绑定到C-x <RIGHT>并且C-x <LEFT>将跳过*Messages*缓冲区。

我正在使用 Emacs 24 和Emacs Starter Kit

我已阅读以下相关问题和答案,但它们不是我想要的:

以下是它们不起作用的一些原因:

  • 我想让它尽可能简单。配置更改越少越好。
  • 我不想*Messages*完全杀死或阻止。
  • (add-to-list 'ido-ignore-buffers "^\*Messages\*"C-x b对我的( )有帮助,ido-switch-buffer但不会改变方式next-bufferprevious-buffer行为。
4

4 回答 4

16

这样可以避免无限循环:

(defun next-code-buffer ()
  (interactive)
  (let (( bread-crumb (buffer-name) ))
    (next-buffer)
    (while
        (and
         (string-match-p "^\*" (buffer-name))
         (not ( equal bread-crumb (buffer-name) )) )
      (next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)

"^\*"此代码在未加星标的缓冲区 ( )上循环。对于您的情况(仅避免*Messages*),它将是:

(defun next-code-buffer ()
  (interactive)
  (let (( bread-crumb (buffer-name) ))
    (next-buffer)
    (while
        (and
         (equal "*Messages*" (buffer-name))
         (not ( equal bread-crumb (buffer-name) )) )
      (next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)

你可以写只是用previous-code-buffer替换every 。next-bufferprevious-buffer

于 2014-07-19T08:34:50.977 回答
7

我能想到的最简单的方法是为这两个函数定义一个建议。这里是为了next-buffer。对于previous-buffer. 您还可以定义一个配置变量来启用/禁用行为(或激活/停用建议):

(defadvice next-buffer (after avoid-messages-buffer-in-next-buffer)
  "Advice around `next-buffer' to avoid going into the *Messages* buffer."
  (when (string= "*Messages*" (buffer-name))
    (next-buffer)))

;; activate the advice
(ad-activate 'next-buffer)

也许您可以用其他方式而不是字符串名称来比较缓冲区,但这会起作用。先前缓冲区的代码几乎相同。我也不知道是否有一种方法可以调用原始函数而无需在通知本身内部触发通知,但同样,即使缓冲区的名称在之后测试,代码也会起作用(如果你只是有一个缓冲区,它是消息缓冲区;一些代码可以检查是否只有一个缓冲区并且不再调用next-buffer)。

如果您想使用执行相同操作的独立函数:

(defun my-next-buffer ()
  "next-buffer, only skip *Messages*"
  (interactive)
  (next-buffer)
  (when (string= "*Messages*" (buffer-name))
      (next-buffer)))

(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-next-buffer)
于 2013-01-14T17:53:49.643 回答
5

这就是我正在使用的,基于 Diego 的回答:

(setq skippable-buffers '("*Messages*" "*scratch*" "*Help*"))

(defun my-next-buffer ()
  "next-buffer that skips certain buffers"
  (interactive)
  (next-buffer)
  (while (member (buffer-name) skippable-buffers)
    (next-buffer)))

(defun my-previous-buffer ()
  "previous-buffer that skips certain buffers"
  (interactive)
  (previous-buffer)
  (while (member (buffer-name) skippable-buffers)
    (previous-buffer)))

(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)

它还不是很好,因为如果除了skippable-buffersI 列表之外没有缓冲区,它将挂起。C-g当它作为一个hackaround发生时,我会跳出循环。

于 2013-01-24T21:51:25.227 回答
2

正如 RubenCaro 的回答所指出的,其他答案可以进入无限循环。不过,我认为 David James 的可跳过缓冲区列表的方法更好一些,所以这里有一个变体。

(setq my-skippable-buffers '("*Messages*" "*scratch*" "*Help*"))

(defun my-change-buffer (change-buffer)
  "Call CHANGE-BUFFER until current buffer is not in `my-skippable-buffers'."
  (let ((initial (current-buffer)))
    (funcall change-buffer)
    (let ((first-change (current-buffer)))
      (catch 'loop
        (while (member (buffer-name) my-skippable-buffers)
          (funcall change-buffer)
          (when (eq (current-buffer) first-change)
            (switch-to-buffer initial)
            (throw 'loop t)))))))

(defun my-next-buffer ()
  "`next-buffer' that skips `my-skippable-buffers'."
  (interactive)
  (my-change-buffer 'next-buffer))

(defun my-previous-buffer ()
  "`previous-buffer' that skips `my-skippable-buffers'."
  (interactive)
  (my-change-buffer 'previous-buffer))

(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
于 2014-07-19T13:33:31.233 回答