Make emacs next-buffer skip * Message * buffer

I would like to make a simple change for Emacs so that the next-buffer and previous-buffer commands (which I linked to Cx <RIGHT> and Cx <LEFT> ) skip the *Messages* buffer.

I am using Emacs 24 and Emacs Starter Kit .

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

Here are some of the reasons why they do not work:

  • I would like to keep it as simple as possible. Fewer configuration changes are better.
  • I do not want to kill or prevent *Messages* .
  • (add-to-list 'ido-ignore-buffers "^\*Messages\*" helps with my Cx b ( ido-switch-buffer ), but does not change the behavior of next-buffer and previous-buffer .
+7
source share
4 answers

The simplest one I can think of is defining recommendations for both functions. Here it is for next-buffer . It would be the same for previous-buffer . You can also define a configuration variable for enabling / disabling behavior (or activating / deactivating advice):

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

Maybe you can compare the buffers in some other way instead of the string name, but that will work. The code for the previous buffer is almost the same. I also don’t know if there is a way to call the original function without calling the advice once in the advice itself, but again, the code will work even if the buffer name is checked later (it will fail if you just have one buffer, and this is a message buffer , and some code can check if there is only one buffer and not call next-buffer again).

If you want to use a standalone function that does the same thing:

 (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) 
+6
source

This way you can avoid an 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 iterates over nonzero buffers ( "^\*" ). For your case (just to avoid *Messages* ) this 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 by simply replacing each next-buffer with previous-buffer .

+13
source

This is what I use, 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) 

This is not great, because it will freeze if there are no buffers other than the skippable-buffers list I. I use Cg to break out of the loop when this happens as a hackdown.

+4
source

As RubenCaro's answer indicates, other answers may introduce infinite loops. I thought David James's approach to the list of skipped buffers is a little better, so here is an option.

 (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) 
+2
source

All Articles