Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make emacs next-buffer skip *Messages* buffer

Tags:

emacs

elisp

I'd like to make a simple change to Emacs so that the next-buffer and previous-buffer commands (which I have bound to C-x <RIGHT> and C-x <LEFT> will skip over the *Messages* buffer.

I'm using Emacs 24 and the Emacs Starter Kit.

I've read the following related questions and answers, but they are not what I want:

  • Buffer cycling in Emacs: avoiding scratch and Messages buffer
  • Emacs disable *Messages* buffer
  • Emacs Lisp Buffer out of focus function?

Here are some of the reasons why they don't work:

  • I'd like to keep it as simple as possible. Fewer configuration changes are better.
  • I don't want to kill or prevent *Messages* altogether.
  • (add-to-list 'ido-ignore-buffers "^\*Messages\*" helps with my C-x b (ido-switch-buffer) but does not change how next-buffer and previous-buffer behave.
like image 494
David J. Avatar asked Jan 14 '13 17:01

David J.


People also ask

How to switch between buffers in Emacs?

To move between the buffers, type C-x b. Emacs shows you a default buffer name. Press Enter if that's the buffer you want, or type the first few characters of the correct buffer name and press Tab. Emacs fills in the rest of the name.

How to open a new buffer in Emacs?

You can create new buffers with switch-to-buffer . Type C-x b , enter a buffer name, and press RET . If no buffer with that name exists, Emacs creates a new one automatically in Fundamental Mode. You may switch to any other mode as usual with M-x , e.g. M-x python-mode .

How many buffers can you open in Emacs at a time?

At any time, one and only one buffer is selected. It is also called the current buffer. Often we say that a command operates on "the buffer" as if there were only one; but really this means that the command operates on the selected buffer (most commands do).

What is Emacs buffer?

Buffers in Emacs editing are objects that have distinct names and hold text that can be edited. Buffers appear to Lisp programs as a special data type. You can think of the contents of a buffer as a string that you can extend; insertions and deletions may occur in any part of the buffer.


2 Answers

This way you can avoid the infinite loop:

(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)

This code loops over non-starred buffers ("^\*"). For your case (only avoid *Messages*) it would be:

(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)

You can write previous-code-buffer just replacing every next-buffer with previous-buffer.

like image 70
RubenCaro Avatar answered Oct 20 '22 17:10

RubenCaro


This is what I'm using, based on Diego's answer:

(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)

It is not great yet, because it will hang if there are no buffers other than the skippable-buffers I list. I use C-g to break out of the loop when it happens as a hackaround.

like image 41
David J. Avatar answered Oct 20 '22 16:10

David J.