23

My Emacs frame looks like this:

+---------------------------+
|             |             |
|             |             |
|             |      B      |
|      A      |             |
|             |             |
|             |             |
|             |-------------|
|             |      C      |
+---------------------------+

C is usually a terminal with some kind of long-running process, like a web server or daemon. Unfortunately, all sorts of things like to switch the buffer in that window and occasionally it gets resized. How can I lock the buffer and height of window C?

a paid nerd
  • 30,702
  • 30
  • 134
  • 179

4 Answers4

12

One possibility is to dedicate the window to its buffer, using set-window-dedicated-p. This will not prevent the window from being resized manually, only protect it from being clobbered by display-buffer. For example,

(add-hook 'shell-mode-hook
      (lambda ()
        (interactive)
        (set-window-dedicated-p (selected-window) 1)))

Replace shell-mode-hook as necessary.

huaiyuan
  • 26,129
  • 5
  • 57
  • 63
  • using a 't' instead of '1' is even stronger. as in: (set-window-dedicated-p (selected-window) t) ...refer to: https://www.gnu.org/software/emacs/manual/html_node/elisp/Dedicated-Windows.html – pestophagous Jan 11 '17 at 00:27
12

If you don't want to be annoyed by window stealing and resizing, put the following lines in your .emacs for a definitive solution that works even with libraries like gud that tries to open a new frame when they can't steal your windows :

(see this answer for info on the following advice)

(defadvice pop-to-buffer (before cancel-other-window first)
  (ad-set-arg 1 nil))

(ad-activate 'pop-to-buffer)

;; Toggle window dedication
(defun toggle-window-dedicated ()
  "Toggle whether the current active window is dedicated or not"
  (interactive)
  (message
   (if (let (window (get-buffer-window (current-buffer)))
         (set-window-dedicated-p window 
                                 (not (window-dedicated-p window))))
       "Window '%s' is dedicated"
     "Window '%s' is normal")
   (current-buffer)))

;; Press [pause] key in each window you want to "freeze"
(global-set-key [pause] 'toggle-window-dedicated)

and customize pop-up-windows variable to nil.

you could also use StickyWindows instead of window-dedicated feature.

Community
  • 1
  • 1
Jérôme Radix
  • 10,285
  • 4
  • 34
  • 40
2

This one also works fine (for emacs 24) https://lists.gnu.org/archive/html/help-gnu-emacs/2007-05/msg00975.html

(define-minor-mode sticky-buffer-mode
  "Make the current window always display this buffer."
  nil " sticky" nil
  (set-window-dedicated-p (selected-window) sticky-buffer-mode))
user1882585
  • 313
  • 2
  • 5
1

You could use winner-mode to be able to undo the changes to be the window sizes.

You could also explicitly save and restore the window configuration in registers.

Teddy
  • 6,013
  • 3
  • 26
  • 38