2
votes

I have Emacs Windmove setup well and working, but I still have a small annoyance with it. There seems to be no way to slide one buffer over another buffer without switching the placement of both buffers. How can I slide a buffer over another buffer, displacing only that buffer.

Here's what I want to do:

   ___________               ___________           ___________
   |    |  B  |             |    |  B  |          |    |  C  |<-----
   | A  |_____|   --->      | A  |_____|   --->   | A  |_____|     |
   |    |  D  |             |    |  C  |          |    |  D  |     |
   |____|_____|             |____|_____|          |____|_____|     |
          Buffer C opens up,  ------^     With a key combo, maybe__|
          covering buffer D               I can slide up buffer C 
                                          to get back buffer D

EDIT: I forgot to mention I have some elisp that uses windmove to actually switch two buffers. The use case for what I want to do is that sometimes a buffer will open up in a certain window, covering up another buffer that I want to see. I want to slide the newly open buffer around without disturbing the other buffers, and to get the buffer back that was covered up. I hope that makes sense.

2
You could place focus in window B and then call M-x switch-to-buffer RET and then use the down arrow key to select the C buffer or type in the name the buffer if you know it and then press RET. Then, repeat the process for the other window. - lawlist
That works, but it's definitely not as efficient as using a key combination to do it. - imcn
I think I understand the question, but I'm very confused by the way it's been phrased: windmove doesn't include any functionality for changing the window configuration in the frame. All it does is provide an easy interface for changing the currently-selected window (within that un-modified window configuration). I don't understand why you mentioned it. - phils
Hey, thank you. I edited my post, hopefully its more clear. - imcn

2 Answers

1
votes
(defun slide-buffer (dir)
  "Move current buffer into window at direction DIR.
DIR is handled as by `windmove-other-window-loc'."
  (require 'windmove)
  (let ((buffer (current-buffer))
        (target (windmove-find-other-window dir)))
    (if (null target)
        (user-error "There is no window %s from here" dir)
      (switch-to-prev-buffer)
      (select-window target)
      (switch-to-buffer buffer nil t))))

(defun slide-buffer-up () (interactive) (slide-buffer 'up))
(defun slide-buffer-down () (interactive) (slide-buffer 'down))
(defun slide-buffer-left () (interactive) (slide-buffer 'left))
(defun slide-buffer-right () (interactive) (slide-buffer 'right))

Bind it to C-S-<arrow>:

(define-key global-map (kbd "C-S-<up>")    #'slide-buffer-up)
(define-key global-map (kbd "C-S-<down>")  #'slide-buffer-down)
(define-key global-map (kbd "C-S-<left>")  #'slide-buffer-left)
(define-key global-map (kbd "C-S-<right>") #'slide-buffer-right)
0
votes

In your comment you say that you would like a "key combination to do it", meaning to (1) switch to the window showing buffer B and then (2) to switch the buffer shown in that window to buffer C.

How do you do that now? You use keys, no? So you already have a "key combination to do it". If you mean that you want a shorter key combination then write a command that chains together the commands bound to the keys you use now to do that.

There are several ways to do #1, and #2 is just C-x b C.

One way to do #1 is to use C-0 C-o in Icicles. It lets you pick a window by name, using completion. The command in question is icicle-choose-window-by-name.

Putting the two together, with Icicles you could use this code. Then hit F3 to do what you want.

 (defun foo ()
   (interactive)
    (call-interactively #'icicle-choose-window-by-name)
    (call-interactively #'switch-to-buffer))

 (global-set-key [f3] 'foo)

There are other ways to choose a window, if you don't want to use Icicles. This is the place to start, when looking for info about selecting (navigating among) windows.