make emacs next-buffer skip * Messages * buffer

时间:2013-01-14 17:31:01

标签: emacs elisp

我想对Emacs进行简单的更改,以便next-bufferprevious-buffer命令(我已绑定到C-x <RIGHT>C-x <LEFT>将跳过*Messages*缓冲区。

我正在使用Emacs 24和Emacs Starter Kit

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

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

  • 我想尽量保持简单。更少的配置更改更好。
  • 我不想完全杀死或阻止*Messages*
  • (add-to-list 'ido-ignore-buffers "^\*Messages\*"有助于我的C-x bido-switch-buffer),但不会改变next-bufferprevious-buffer的行为方式。

4 个答案:

答案 0 :(得分:13)

这样你可以避免无限循环:

(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替换每个next-buffer即可previous-buffer

答案 1 :(得分: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)

答案 2 :(得分:4)

这是我正在使用的,基于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-buffers我列表之外没有缓冲区,它会挂起。 C-g来摆脱循环。

答案 3 :(得分: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)