1
votes

When I'm editing a bunch of files in emacs, I like to use emacs --daemon, so I end up with a lot of frames open. The problem is when I try to switch buffers, via C-x b. I'm not sure exactly how it happens, but sometimes the next buffer will already be in a frame minimized in the background. In that case it puts the buffer I'm leaving into that frame, shoves the buffer down to the bottom of the buffer list, and makes me tab like crazy to get back to it. Then it happens to the second buffer, making me have to tab like crazy to get back to it.

It turns an efficient work cycle of "C-x b [edit] C-x b [edit]" into "C-x b [tabtabtabatbatbatbat] [enter] [edit] C-x b [tabtabtabatbatbabatbtba] [sigh] [enter] [edit]". The only solution I can find is to Alt-Tab around until I find the frame that's stealing these buffers, and close it. Until it just goes and happens again, and I want to strangle something.

What I want is... when I switch buffers with "C-x b" the buffer I leave should never get shuffled off into another open frame, but merely be no longer visible, staying at the top of the buffer list for the next "C-x b" to switch back to it. How would I do that?

2
You cannot rely upon the regular buffer-list, either global or frame-local -- they change all the time and are generally beyond your control. You should consider using frame-bufs by Alp Aker -- github.com/alpaker/Frame-Bufs -- which embeds a buffer-local list into the frame-parameter to associate select buffers with certain frames. To control what buffers get displayed in certain frames, take a look at How to intercept a file before it opens and decide which frame: stackoverflow.com/questions/18346785/… - lawlist
If you like the idea of tabs, the following link marries the concept of frame-bufs with tabbar -- with an extra custom twist to dynamically add and remove select tabs of buffers on a frame-local basis: emacs.stackexchange.com/a/10112/2287 and all of that can be married with the concept in the second link of the comment above (to display a buffer in a particular frame). - lawlist

2 Answers

0
votes

Two things that might help you:

  1. It turns an efficient work cycle of "C-x b [edit] C-x b [edit]" into "C-x b [tabtabtabatbatbatbat] [enter] [edit] C-x b [tabtabtabatbatbabatbtba] [sigh] [enter] [edit]".

    It's likely you can use C-r to cycle through buffers backward. So you could C-x b TAB to go forward, and C-x b C-r to go backward.

  2. Are you opening file with emacsclient file.txt? If so, it's causing Emacs to treat the file.txt buffer in a special way, and you don't like that. You can fool Emacs into treating it like any other buffer by running emacsclient -e '(find-file "file.txt")' instead. That way, Emacs doesn't know you opened file.txt from an emacsclient command, and won't put the buffer at the bottom of the buffer list. Does that make sense?

    emacsclient -e '(find-file "file.txt")' is quite a bit to type, you could shorten it by putting this in your .bashrc:

    edit() {
        emacsclient -e '(find-file "'"$1"'")'
    }
    

    Then, open a file with edit file.txt.

0
votes

I found a solution, I think. The problem is that other-buffer ignores already visible buffers, so when switch-to-buffer tries to get a default buffer to switch to, other-buffer returns buried buffers in preference to visible ones. And C-x b calls switch-to-buffer.

Fortunately, other-buffer has an optional argument that disables this deferential treatment of visible buffers. switch-to-buffer doesn't specify that argument, but overriding other people's code is exactly what defadvice is for!

(defadvice other-buffer (before switch-to-visible-darnyou
                                activate preactivate compile)
  (ad-set-arg 1 t))

And poof, now calling (other-buffer something) results in (other-buffer something t), and a buffer's visibility doesn't steal it from the switch-to-buffer prompt.