tags:

views:

711

answers:

3

My windows configuration looks like this:

          +----------+-----------+
      |          |           |
   |          |           |
   |          |           |
   |          |           |
   |          |           |
   |          +-----------+
   |          |           |
   +----------+-----------+

And I use the lower right window for special displays (like help, completion etc.), but emacs insists on using that window when I call commands (find-file-other-window, etc.) that use display-buffer, and resize that window as well. It's annoying... Is there a way that I can force emacs NOT to use that windows? I was thinking of advising display-buffer, but it's a function in c. Any thoughts on this?

EDIT:

Based heavily on Trey's answer, this is what works for me so far:

(setq special-display-function 'my-display-buffer)
(setq special-display-regexps '(".*"))

(defun display-special-buffer (buf)
  "put the special buffers in the right spot (bottom rigt)"
    (let ((target-window (window-at (- (frame-width) 4) (- (frame-height) 4)))
          (pop-up-windows t))
      (set-window-buffer target-window buf)
      target-window))

(defun my-display-buffer (buf)
  "put all buffers in a window other than the one in the bottom right"
  (message (buffer-name  buf))
  (if (member (buffer-name buf) special-display-buffer-names)
      (display-special-buffer buf)
      (progn
     (let ((pop-up-windows t)
        (windows (delete (window-at (- (frame-width) 4) (- (frame-height) 4))
                         (delete (minibuffer-window) (window-list)))))
       (message (buffer-name (window-buffer (car windows))))
       (set-window-buffer (car (cdr windows)) buf)
       (car (cdr windows))))))
+10  A: 

Well, someone already asked the same question for completion. And I wrote up an answer that seemed to work pretty well.

It looks like you could use that same solution, except instead of adding to special-display-buffer-names, you can use the variable special-display-regexps. So something along the lines of:

(add-to-list 'special-display-regexps '(".*" my-display-buffers))

(defun my-display-buffers (buf)
  "put all buffers in a window other than the one in the bottom right"
  (let ((windows (delete (window-at (- (frame-width) 2) (- (frame-height) 4))
                         (delete (minibuffer-window) (window-list))))
    (if (<= 2 (length windows))
        (progn 
          (select-window (cadr windows))
          (split-window-vertically)))
    (let ((pop-up-windows t))
      (set-window-buffer (car windows) buf)
      (car windows)))))

Obviously you'll have to modify the regexp to not match the *Help* and other buffers that you actually want in the lower right window.

Regarding advising display-buffer, that would work. You can advise functions written in c, advice works in pretty much every case you'd want except when functions are called from c, or advising macros (which doesn't work b/c the macros are generally already expanded everywhere they're used).

Trey Jackson
I saw the other question and indeed used your solution; but my question is not the same. I'm asking not on forcing emacs to use a window but on emacs to NOT use a specific window.
polyglot
Right, I don't think Emacs has the ability to exclude windows, so you'll have to use a modified version to exclude the bottom-right window from the window list. I notice I forgot to do that in my cut/paste hurry, lemme update that.
Trey Jackson
When you do (car windows), it actually returns the current windows. But (car (cdr windows)) will work perfectly. Also (- (frame-height) 2) sometimes find the mini-buffer instead (since it sometimes expands to 2 lines), so I use 4 instead of 2.
polyglot
Thanks, updated.
Trey Jackson
+3  A: 

Perhaps something like this could work:

(defun display-buffer-avoiding-lr-corner (buffer &optional not-this-window)
  (save-selected-window
    (when (buffer-file-name buffer)
      (select-window (window-at (- (frame-width) 1)
                                (- (frame-height) 2))))
    (let ((display-buffer-function nil))
      (display-buffer buffer not-this-window))))

(setq display-buffer-function 'display-buffer-avoiding-lr-corner)
huaiyuan
+1  A: 

I was thinking of advising display-buffer, but it's a function in c.

"display-buffer is an interactive Lisp function in `window.el'."

Also, you can advise C functions anyway.

jrockway
My emacs says "display-buffer is an interactive built-in function in `C source code'." Version differences, maybe?
polyglot