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.