I often have various files open and cycle through them using C-x <left> and C-x <right>. However, this means I also need to cycle through various "informative" buffers that I really don't care about. For example, at work I connect to a remote machine (call it foo) via tramp and edit files there. This opens various buffers such as *debug tramp/sshx foo* *tramp/sshx foo*. Then, we have *Messages*, *Completions*, *scratch* etc, etc.

So, how can I define a list of buffers that are never shown when cycling through the open buffers with C-x <left> and C-x <right>? Ideally, these would still be shown in the buffer drop-down menu in the GUI and in Ibuffer so I can switch to them if I ever want to, but they will be hidden when cycling through open buffers.

  • Burying a buffer means to put it at the end of the buffer list, not removing it. I suspect that C-x left moves up in the list, and C-x right moves right. So if you bury a buffer, C-x left will bring it back, while cycling with C-x right will go through all other buffers before showing this one again. What you can do if you want to get rid of a buffer is to kill it (C-x k). (I am aware that it is not what you ask for, just a temporary workaround for some buffers) – T. Verron Oct 12 '16 at 9:56
  • @T.Verron ah, OK, wrong terminology then. Thanks, I know how to kill buffers, however, most of these reappear after killing as soon as a new message is shown. I removed the code from the question then since it seems to be irrelevant. – terdon Oct 12 '16 at 10:05
  • It's not that irrelevant, for example burying a buffer has an effect on what buffer C-x b suggests. I guess that C-x left and C-x right require a different approach though. By the way, have you looked at ido and similar packages, which will enhance C-x b with a list of buffers you can cycle through? – T. Verron Oct 12 '16 at 10:14
  • @T.Verron well, the buried buffers are still shown in ibuffer even if I manually run the crs-bury-buffer command. In any case, what I really want is to remove them from the C-x right cycling so the function in the first version of the question is only going to confuse things. – terdon Oct 12 '16 at 10:18
  • They should be in ibuffer but at the very end of the list, no? – T. Verron Oct 12 '16 at 10:20

You can set the buffer-predicate parameter of a frame to a function that decides which buffers you want to see in the cycle for windows in that frame.

For example, say that you want to see only buffers that are associated to a file. The function buffer-file-name returns nil for buffers that are not associated to files and a non-nil value (the filename) for those that are. Evaluate the following expression in some frame:

(set-frame-parameter (selected-frame) 'buffer-predicate #'buffer-file-name)

After doing so, C-x <left> and C-x <right> called from windows in that frame will only cycle through buffers with associated files.

As another example, if you want to only cycle through buffers whose name does not start with an asterisk you could evaluate:

(set-frame-parameter (selected-frame) 'buffer-predicate
  (lambda (buf) (not (string-match-p "^*" (buffer-name buf)))))

I had no idea about any of that before trying to answer this question. I started by looking up which function C-x <left> runs, then took a look at the source code of that function and that's when I saw a suspicious (frame-parameter frame 'buffer-predicate) call. I love how easy it is to get definitive answers about how Emacs does something, I've never used another system that comes close in transparency!

  • Ah, this looked promising but doesn't seem to work. I evaluated your command (by running M-x eval-expression, enter and then the command; it would be great if you could add that to your answer) in an open window with various open files (emacs 25.1.1 running on Arch Linux). It returned 'nill' on both the *scratch* buffer and one with an associated file. Neither made any difference to Ctrl+left. Any ideas? – terdon Oct 13 '16 at 10:10
  • I take that back. Adding the second command to my ~/.emacs file, works like a charm. I don't know why it doesn't when evaluating it. – terdon Oct 13 '16 at 12:27
  • Mmh, I tested those expressions using eval-expression (which is bound by default to M-:) and they did work for me, @terdon. I tested them on whatever the Ubuntu PPA called Emacs snapshot has, which is at least 25.1. – Omar Oct 13 '16 at 15:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.