]> git.eshelyaron.com Git - emacs.git/commitdiff
Make Temp Buffer Resize Mode less intrusive (Bug#1806).
authorMartin Rudalics <rudalics@gmx.at>
Sat, 22 Sep 2012 12:56:08 +0000 (14:56 +0200)
committerMartin Rudalics <rudalics@gmx.at>
Sat, 22 Sep 2012 12:56:08 +0000 (14:56 +0200)
* window.c (Fsplit_window_internal): Handle only Qt value of
Vwindow_combination_limit separately.
(Qtemp_buffer_resize): New symbol.
(Vwindow_combination_limit): New default value.  Rewrite
doc-string.
* cus-start.el (window-combination-limit): Add new optional
values.
* window.el (temp-buffer-window-show)
(window--try-to-split-window): Obey new values of
window-combination-limit.
(split-window): Test window-combination-limit for t instead of
non-nil.
(display-buffer-at-bottom): New buffer display action function.
* help.el (temp-buffer-resize-regexps): New option.
(temp-buffer-resize-mode): Rewrite doc-string.
(resize-temp-buffer-window): Obey temp-buffer-resize-regexps.
Don't resize reused window.  Suggested by Glen Morris.

etc/NEWS
lisp/ChangeLog
lisp/cus-start.el
lisp/help.el
lisp/window.el
src/ChangeLog
src/window.c

index ccd8a6fe35bd0070d9fc3b42ee56b918a971d647..30648a5961a9c2986db4a15d042b5bf23a2dd208 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -719,15 +719,21 @@ recursive invocations.
 *** The functions get-lru-window, get-mru-window and get-largest-window
 now accept a third argument to avoid choosing the selected window.
 
+*** Additional values recognized for option `window-combination-limit'.
+
 *** New macro `with-temp-buffer-window'.
 
-*** New option `temp-buffer-resize-frames'.
+*** New options `temp-buffer-resize-frames' and
+`temp-buffer-resize-regexps'.
+
+*** `temp-buffer-resize-mode' no longer resizes windows that have been
+reused.
 
 *** New function `fit-frame-to-buffer' and new option
-    `fit-frame-to-buffer-bottom-margin'.
+`fit-frame-to-buffer-bottom-margin'.
 
-*** New display action functions `display-buffer-below-selected' and
-`display-buffer-in-previous-window'.
+*** New display action functions `display-buffer-below-selected',
+`display-buffer-at-bottom' and `display-buffer-in-previous-window'.
 
 *** New display action alist entry `inhibit-switch-frame', if non-nil,
 tells display action functions to avoid changing which frame is
index 7f9044e4f365769b705ad1363a14b78294254fa1..f18bfd7361104d2768cf939b3c3b5b1b6aa60ebe 100644 (file)
@@ -1,3 +1,18 @@
+2012-09-22  Martin Rudalics  <rudalics@gmx.at>
+
+       * cus-start.el (window-combination-limit): Add new optional
+       values.
+       * window.el (temp-buffer-window-show)
+       (window--try-to-split-window): Handle new values of
+       window-combination-limit (Bug#1806).
+       (split-window): Test window-combination-limit for t instead of
+       non-nil.
+       (display-buffer-at-bottom): New buffer display action function.
+       * help.el (temp-buffer-resize-regexps): New option.
+       (temp-buffer-resize-mode): Rewrite doc-string.
+       (resize-temp-buffer-window): Obey temp-buffer-resize-regexps.
+       Don't resize reused window.  Suggested by Glen Morris.
+
 2012-09-22  Stefan Merten  <smerten@oekonux.de>
 
        * rst.el: Revamp section title faces.
index 0eb8b2d63c3c68f0e3e9b6e80257c33f6cccfc38..a91a479b0546a57f60134be2b596b15bd5d69613 100644 (file)
@@ -422,7 +422,17 @@ since it could result in memory overflow and make Emacs crash."
                       (const :tag "Only on ttys" :value tty)
                       (other :tag "Always" t)) "23.1")
             (window-combination-resize windows boolean "24.1")
-            (window-combination-limit windows boolean "24.1")
+            (window-combination-limit
+             windows (choice
+                      (const :tag "Never (nil)" :value nil)
+                      (const :tag "For Temp Buffer Resize mode (temp-buffer-resize)"
+                             :value temp-buffer-resize)
+                      (const :tag "For temporary buffers (temp-buffer)"
+                             :value temp-buffer)
+                      (const :tag "For buffer display (display-buffer)"
+                             :value display-buffer)
+                      (other :tag "Always (t)" :value t))
+             "24.3")
             ;; xdisp.c
             (show-trailing-whitespace whitespace-faces boolean nil
                                       :safe booleanp)
index da11389d87cf42cbcb2998de48f5a44e828e19d2..707c8e3c84f40bdde11dfdb65ead03a86d5fff59 100644 (file)
@@ -990,6 +990,17 @@ window.  The height of the root window is subject to the values of
   :version "24.2"
   :group 'help)
 
+(defcustom temp-buffer-resize-regexps nil
+  "List of regexps that inhibit Temp Buffer Resize mode.
+Any window of a buffer whose name matches one of these regular
+expressions is left alone by Temp Buffer Resize mode."
+  :type '(repeat
+         :tag "Buffer"
+         :value ""
+         (regexp :format "%v"))
+  :version "24.3"
+  :group 'help)
+
 (define-minor-mode temp-buffer-resize-mode
   "Toggle auto-resizing temporary buffer windows (Temp Buffer Resize Mode).
 With a prefix argument ARG, enable Temp Buffer Resize mode if ARG
@@ -1001,6 +1012,12 @@ show a temporary buffer are automatically resized in height to
 fit the buffer's contents, but never more than
 `temp-buffer-max-height' nor less than `window-min-height'.
 
+A window is resized only if it has been specially created for the
+buffer.  Windows that have shown another buffer before are not
+resized.  A window showing a buffer whose name matches any of the
+expressions in `temp-buffer-resize-regexps' is not resized.  A
+frame is resized only if `temp-buffer-resize-frames' is non-nil.
+
 This mode is used by `help', `apropos' and `completion' buffers,
 and some others."
   :global t :group 'help
@@ -1017,27 +1034,33 @@ WINDOW can be any live window and defaults to the selected one.
 Do not make WINDOW higher than `temp-buffer-max-height' nor
 smaller than `window-min-height'.  Do nothing if WINDOW is not
 vertically combined or some of its contents are scrolled out of
-view."
+view.  Do nothing if the name of WINDOW's buffer matches an
+expression in `temp-buffer-resize-regexps'."
   (setq window (window-normalize-window window t))
-  (let ((height (if (functionp temp-buffer-max-height)
-                   (with-selected-window window
-                     (funcall temp-buffer-max-height (window-buffer)))
-                 temp-buffer-max-height)))
-    (cond
-     ((and (pos-visible-in-window-p (point-min) window)
-          (window-combined-p window))
-      (fit-window-to-buffer window height))
-     ((and temp-buffer-resize-frames
-          (eq window (frame-root-window window))
-          (memq (car (window-parameter window 'quit-restore))
-                ;; If 'same is too strong, we might additionally check
-                ;; whether the second element is 'frame.
-                '(same frame)))
-      (let ((frame (window-frame window)))
-       (fit-frame-to-buffer
-        frame (+ (frame-height frame)
-                 (- (window-total-size window))
-                 height)))))))
+  (let ((buffer-name (buffer-name (window-buffer window))))
+    (unless (catch 'found
+             (dolist (regexp temp-buffer-resize-regexps)
+               (when (string-match regexp buffer-name)
+                 (throw 'found t))))
+      (let ((height (if (functionp temp-buffer-max-height)
+                       (with-selected-window window
+                         (funcall temp-buffer-max-height (window-buffer)))
+                     temp-buffer-max-height))
+           (quit-cadr (cadr (window-parameter window 'quit-restore))))
+       (cond
+        ;; Don't resize WINDOW if it showed another buffer before.
+        ((and (eq quit-cadr 'window)
+              (pos-visible-in-window-p (point-min) window)
+              (window-combined-p window))
+         (fit-window-to-buffer window height))
+        ((and temp-buffer-resize-frames
+              (eq quit-cadr 'frame)
+              (eq window (frame-root-window window)))
+         (let ((frame (window-frame window)))
+           (fit-frame-to-buffer
+            frame (+ (frame-height frame)
+                     (- (window-total-size window))
+                     height)))))))))
 
 ;;; Help windows.
 (defcustom help-window-select 'other
index fccb68bd94ac61733cc7183cb720326e3ca9c25a..87817fb87730adff72dbcdfb603a27ce924bf368 100644 (file)
@@ -111,7 +111,19 @@ to `display-buffer'."
       (set-buffer-modified-p nil)
       (setq buffer-read-only t)
       (goto-char (point-min))
-      (when (setq window (display-buffer buffer action))
+      (when (let ((window-combination-limit
+                  ;; When `window-combination-limit' equals
+                  ;; `temp-buffer' or `temp-buffer-resize' and
+                  ;; `temp-buffer-resize-mode' is enabled in this
+                  ;; buffer bind it to t so resizing steals space
+                  ;; preferably from the window that was split.
+                  (if (or (eq window-combination-limit 'temp-buffer)
+                          (and (eq window-combination-limit
+                                   'temp-buffer-resize)
+                               temp-buffer-resize-mode))
+                      t
+                    window-combination-limit)))
+             (setq window (display-buffer buffer action)))
        (setq frame (window-frame window))
        (unless (eq frame (selected-frame))
          (raise-frame frame))
@@ -3678,9 +3690,8 @@ frame.  The selected window is not changed by this function."
         (parent (window-parent window))
         (function (window-parameter window 'split-window))
         (window-side (window-parameter window 'window-side))
-        ;; Rebind `window-combination-limit' and
-        ;; `window-combination-resize' since in some cases we may have
-        ;; to override their value.
+        ;; Rebind the following two variables since in some cases we
+        ;; have to override their value.
         (window-combination-limit window-combination-limit)
         (window-combination-resize window-combination-resize)
         atom-root)
@@ -3738,7 +3749,7 @@ frame.  The selected window is not changed by this function."
              (and window-combination-resize
                   (or (window-parameter window 'window-side)
                       (not (eq window-combination-resize 'side)))
-                  (not window-combination-limit)
+                  (not (eq window-combination-limit t))
                   ;; Resize makes sense in iso-combinations only.
                   (window-combined-p window horizontal)))
             ;; `old-size' is the current size of WINDOW.
@@ -3818,7 +3829,7 @@ frame.  The selected window is not changed by this function."
              ;; Make new-parent non-nil if we need a new parent window;
              ;; either because we want to nest or because WINDOW is not
              ;; iso-combined.
-             (or window-combination-limit
+             (or (eq window-combination-limit t)
                  (not (window-combined-p window horizontal))))
        (setq new-normal
              ;; Make new-normal the normal size of the new window.
@@ -5066,12 +5077,19 @@ Return value returned by `split-window-preferred-function' if it
 represents a live window, nil otherwise."
       (and (window-live-p window)
           (not (frame-parameter (window-frame window) 'unsplittable))
-          (let ((new-window
-                 ;; Since `split-window-preferred-function' might
-                 ;; throw an error use `condition-case'.
-                 (condition-case nil
-                     (funcall split-window-preferred-function window)
-                   (error nil))))
+          (let* ((window-combination-limit
+                  ;; When `window-combination-limit' equals
+                  ;; `display-buffer' bind it to t so resizing steals
+                  ;; space preferably from the window that was split.
+                  (if (eq window-combination-limit 'display-buffer)
+                      t
+                    window-combination-limit))
+                 (new-window
+                  ;; Since `split-window-preferred-function' might
+                  ;; throw an error use `condition-case'.
+                  (condition-case nil
+                      (funcall split-window-preferred-function window)
+                    (error nil))))
             (and (window-live-p new-window) new-window))))
 
 (defun window--frame-usable-p (frame)
@@ -5524,6 +5542,29 @@ the selected one."
             (window--display-buffer
              buffer window 'reuse display-buffer-mark-dedicated)))))
 
+(defun display-buffer-at-bottom (buffer _alist)
+  "Try displaying BUFFER in a window at the botom of the selected frame.
+This either splits the window at the bottom of the frame or the
+frame's root window, or reuses an existing window at the bottom
+of the selected frame."
+  (let (bottom-window window)
+    (walk-window-tree (lambda (window) (setq bottom-window window)))
+    (or (and (not (frame-parameter nil 'unsplittable))
+            (setq window (window--try-to-split-window bottom-window))
+            (window--display-buffer
+             buffer window 'window display-buffer-mark-dedicated))
+       (and (not (frame-parameter nil 'unsplittable))
+            (setq window
+                  (condition-case nil
+                      (split-window (frame-root-window))
+                    (error nil)))
+            (window--display-buffer
+             buffer window 'window display-buffer-mark-dedicated))
+       (and (setq window bottom-window)
+            (not (window-dedicated-p window))
+            (window--display-buffer
+             buffer window 'reuse display-buffer-mark-dedicated)))))
+
 (defun display-buffer-in-previous-window (buffer alist)
   "Display BUFFER in a window previously showing it.
 If ALIST has a non-nil `inhibit-same-window' entry, the selected
index 4033f51ca1a9a5691356377cc85e03d2889557ab..6ea40b3f122a47c0360e116106047a4e1aff135f 100644 (file)
@@ -1,3 +1,11 @@
+2012-09-22  Martin Rudalics  <rudalics@gmx.at>
+
+       * window.c (Fsplit_window_internal): Handle only Qt value of
+       Vwindow_combination_limit separately.
+       (Qtemp_buffer_resize): New symbol.
+       (Vwindow_combination_limit): New default value.  Rewrite
+       doc-string.
+
 2012-09-22  Eli Zaretskii  <eliz@gnu.org>
 
        * xdisp.c (next_overlay_string): Initialize it->end_charpos for
index a6f1104587e87c04ed4385622c4483677d670ede..6798be8231c8bbfa102e5d36eca3f1ca90667ad3 100644 (file)
@@ -60,8 +60,7 @@ static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
 static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
 static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
 static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
-static Lisp_Object Qsafe, Qabove, Qbelow;
-static Lisp_Object Qclone_of;
+static Lisp_Object Qsafe, Qabove, Qbelow, Qtemp_buffer_resize, Qclone_of;
 
 static int displayed_window_lines (struct window *);
 static int count_windows (struct window *);
@@ -613,10 +612,10 @@ WINDOW are never \(re-)combined with WINDOW's siblings.  */)
 DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
        doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
 WINDOW must be a valid window and defaults to the selected one.
-If LIMIT is nil, child windows of WINDOW can be recombined with
-WINDOW's siblings.  LIMIT t means that child windows of WINDOW are
-never \(re-)combined with WINDOW's siblings.  Other values are reserved
-for future use.  */)
+If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
+siblings.  LIMIT t means that child windows of WINDOW are never
+\(re-)combined with WINDOW's siblings.  Other values are reserved for
+future use.  */)
   (Lisp_Object window, Lisp_Object limit)
 {
   wset_combination_limit (decode_valid_window (window), limit);
@@ -3466,7 +3465,7 @@ make_window (void)
      allocate_window.  */
   wset_prev_buffers (w, Qnil);
   wset_next_buffers (w, Qnil);
-  
+
   /* Initialize non-Lisp data.  Note that allocate_window zeroes out all
      non-Lisp data, so do it only for slots which should not be zero.  */
   w->nrows_scale_factor = w->ncols_scale_factor = 1;
@@ -3848,7 +3847,7 @@ set correctly.  See the code of `split-window' for how this is done.  */)
      We do that if either `window-combination-limit' is t, or OLD has no
      parent, or OLD is ortho-combined.  */
   combination_limit =
-    !NILP (Vwindow_combination_limit)
+    EQ (Vwindow_combination_limit, Qt)
     || NILP (o->parent)
     || NILP (horflag
             ? (XWINDOW (o->parent)->hchild)
@@ -3903,9 +3902,9 @@ set correctly.  See the code of `split-window' for how this is done.  */)
 
       make_parent_window (old, horflag);
       p = XWINDOW (o->parent);
-      /* Store value of `window-combination-limit' in new parent's
-        combination_limit slot.  */
-      wset_combination_limit (p, Vwindow_combination_limit);
+      /* Store t in the new parent's combination_limit slot to avoid
+       that its children get merged into another window.  */
+      wset_combination_limit (p, Qt);
       /* These get applied below.  */
       wset_new_total (p, horflag ? o->total_cols : o->total_lines);
       wset_new_normal (p, new_normal);
@@ -6705,6 +6704,7 @@ syms_of_window (void)
   DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
   DEFSYM (Qrecord_window_buffer, "record-window-buffer");
   DEFSYM (Qget_mru_window, "get-mru-window");
+  DEFSYM (Qtemp_buffer_resize, "temp-buffer-resize");
   DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
   DEFSYM (Qabove, "above");
   DEFSYM (Qbelow, "below");
@@ -6800,23 +6800,36 @@ This variable takes no effect if `window-combination-limit' is non-nil.  */);
   Vwindow_combination_resize = Qnil;
 
   DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
-              doc: /* If t, splitting a window makes a new parent window.
-If this variable is nil, splitting a window will create a new parent
-window only if the window has no parent window or the window shall
-become a combination orthogonal to the one it is part of.
+              doc: /* If non-nil, splitting a window makes a new parent window.
+The following values are recognized:
 
-If this variable is t, splitting a window always creates a new parent
-window.  If all splits behave this way, each frame's window tree is a
-binary tree and every window but the frame's root window has exactly one
-sibling.
+nil means splitting a window will create a new parent window only if the
+    window has no parent window or the window shall become a combination
+    orthogonal to the one it is part of.
 
-Other values are reserved for future use.
+`temp-buffer-resize' means that splitting a window for displaying a
+    temporary buffer makes a new parent window provided
+    `temp-buffer-resize-mode' is enabled.  Otherwise, this value is
+    handled like nil.
+
+`temp-buffer' means that splitting a window for displaying a temporary
+    buffer always makes a new parent window.  Otherwise, this value is
+    handled like nil.
+
+
+`display-buffer' means that splitting a window for displaying a buffer
+    always makes a new parent window.  Since temporary buffers are
+    displayed by the function `display-buffer', this value is stronger
+    than `temp-buffer'.  Splitting a window for other purpose makes a
+    new parent window only if needed.
+
+t means that splitting a window always creates a new parent window.  If
+    all splits behave this way, each frame's window tree is a binary
+    tree and every window but the frame's root window has exactly one
+    sibling.
 
-The value of this variable is also assigned to the combination limit of
-the new parent window.  The combination limit of a window can be
-retrieved via the function `window-combination-limit' and altered by the
-function `set-window-combination-limit'.  */);
-  Vwindow_combination_limit = Qnil;
+Other values are reserved for future use.  */);
+  Vwindow_combination_limit = Qtemp_buffer_resize;
 
   DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
               doc: /* Alist of persistent window parameters.