Using saved parent location: http://bzr.savannah.gnu.org/r/emacs/trunk/ Now on revision 104551. ------------------------------------------------------------ revno: 104551 committer: martin rudalics branch nick: trunk timestamp: Fri 2011-06-10 08:55:18 +0200 message: Move window resize code from window.c to window.el. * window.c: Remove declarations of Qwindow_size_fixed, window_min_size_1, window_min_size_2, window_min_size, size_window, window_fixed_size_p, enlarge_window, delete_window. Remove static from declaration of Qdelete_window, it's temporarily needed by Fbury_buffer. (replace_window): Don't assign orig_top_line and orig_total_lines. (Fdelete_window, delete_window): Remove. Window deletion is handled by window.el. (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace Fdelete_window calls with calls to Qdelete_window. (Fdelete_other_windows): Remove. Deleting other windows is handled by window.el. (window_fixed_size_p): Remove. Fixed-sizeness of windows is handled in window.el. (window_min_size_2, window_min_size_1, window_min_size): Remove. Window minimum sizes are handled in window.el. (shrink_windows, size_window, set_window_height) (set_window_width, change_window_heights, window_height) (window_width, CURBEG, CURSIZE, enlarge_window) (adjust_window_trailing_edge, Fadjust_window_trailing_edge) (Fenlarge_window, Fshrink_window): Remove. Window resizing is handled in window.el. (make_dummy_parent): Rename to make_parent_window and give it a second argument horflag. (make_window): Don't set resize_proportionally any more. (Fsplit_window): Remove. Windows are split in window.el. (save_restore_action, save_restore_orig_size) (shrink_window_lowest_first, save_restore_orig_size): Remove. Resize mini windows in window.el. (grow_mini_window, shrink_mini_window): Implement by calling Qresize_root_window_vertically, resize_window_check and resize_window_apply. (saved_window, Fset_window_configuration, save_window_save): Do not handle orig_top_line, orig_total_lines, and resize_proportionally. (window_min_height, window_min_width): Move to window.el. (keys_of_window): Move bindings for delete-other-windows, split-window, delete-window and enlarge-window to window.el. * buffer.c: Temporarily extern Qdelete_window. (Fbury_buffer): Temporarily call Qdelete_window instead of Fdelete_window (Fbury_buffer will move to window.el soon). * frame.c (set_menu_bar_lines_1): Remove code handling orig_top_line and orig_total_lines. * dispnew.c (adjust_frame_glyphs_initially): Don't use set_window_height but set heights directly. (change_frame_size_1): Use resize_frame_windows. * xdisp.c (init_xdisp): Don't use set_window_height but set heights directly. * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use resize_frame_windows instead of change_window_heights and run run_window_configuration_change_hook. * w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows instead of change_window_heights and run run_window_configuration_change_hook. * window.el (window-min-height, window-min-width): Move here from window.c. Add defcustoms and rewrite doc-strings. (resize-mini-window, resize-window): New functions. (adjust-window-trailing-edge, enlarge-window, shrink-window): Move here from window.c. (maximize-window, minimize-window): New functions. (delete-window, delete-other-windows, split-window): Move here from window.c. (window-split-min-size): New function. (split-window-keep-point): Mention split-window-above-each-other instead of split-window-vertically. (split-window-above-each-other, split-window-vertically): Rename split-window-vertically to split-window-above-each-other and provide defalias for old definition. (split-window-side-by-side, split-window-horizontally): Rename split-window-horizontally to split-window-side-by-side and provide defalias for the old definition. (ctl-x-map): Move bindings for delete-window, delete-other-windows and enlarge-window here from window.c. Replace bindings for split-window-vertically and split-window-horizontally by bindings for split-window-above-each-other and split-window-side-by-side. * cus-start.el (all): Remove entries for window-min-height and window-min-width. Add entries for window-splits and window-nest. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-09 20:25:34 +0000 +++ lisp/ChangeLog 2011-06-10 06:55:18 +0000 @@ -1,3 +1,32 @@ +2011-06-10 Martin Rudalics + + * window.el (window-min-height, window-min-width): Move here + from window.c. Add defcustoms and rewrite doc-strings. + (resize-mini-window, resize-window): New functions. + (adjust-window-trailing-edge, enlarge-window, shrink-window): + Move here from window.c. + (maximize-window, minimize-window): New functions. + (delete-window, delete-other-windows, split-window): Move here + from window.c. + (window-split-min-size): New function. + (split-window-keep-point): Mention split-window-above-each-other + instead of split-window-vertically. + (split-window-above-each-other, split-window-vertically): Rename + split-window-vertically to split-window-above-each-other and + provide defalias for old definition. + (split-window-side-by-side, split-window-horizontally): Rename + split-window-horizontally to split-window-side-by-side and provide + defalias for the old definition. + (ctl-x-map): Move bindings for delete-window, + delete-other-windows and enlarge-window here from window.c. + Replace bindings for split-window-vertically and + split-window-horizontally by bindings for + split-window-above-each-other and split-window-side-by-side. + + * cus-start.el (all): Remove entries for window-min-height and + window-min-width. Add entries for window-splits and + window-nest. + 2011-06-09 Glenn Morris * calendar/appt.el (appt-mode-line): New function. === modified file 'lisp/cus-start.el' --- lisp/cus-start.el 2011-04-26 11:26:05 +0000 +++ lisp/cus-start.el 2011-06-10 06:55:18 +0000 @@ -388,19 +388,18 @@ ;; window.c (temp-buffer-show-function windows (choice (const nil) function)) (next-screen-context-lines windows integer) - (window-min-height windows integer) - (window-min-width windows integer) (scroll-preserve-screen-position windows (choice (const :tag "Off (nil)" :value nil) (const :tag "Full screen (t)" :value t) (other :tag "Always" 1)) "22.1") - (recenter-redisplay windows - (choice - (const :tag "Never (nil)" :value nil) - (const :tag "Only on ttys" :value tty) - (other :tag "Always" t)) - "23.1") + (recenter-redisplay + windows (choice + (const :tag "Never (nil)" :value nil) + (const :tag "Only on ttys" :value tty) + (other :tag "Always" t)) "23.1") + (window-splits windows boolean "24.1") + (window-nest windows boolean "24.1") ;; xdisp.c (show-trailing-whitespace whitespace-faces boolean nil :safe booleanp) === modified file 'lisp/window.el' --- lisp/window.el 2011-06-09 08:41:36 +0000 +++ lisp/window.el 2011-06-10 06:55:18 +0000 @@ -161,10 +161,41 @@ "The absolut minimum number of lines of a window. Anything less might crash Emacs.") +(defcustom window-min-height 4 + "The minimum number of lines of any window. +The value has to accomodate a mode- or header-line if present. A +value less than `window-safe-min-height' is ignored. The value +of this variable is honored when windows are resized or split. + +Applications should never rebind this variable. To resize a +window to a height less than the one specified here, an +application should instead call `resize-window' with a non-nil +IGNORE argument. In order to have `split-window' make a window +shorter, explictly specify the SIZE argument of that function." + :type 'integer + :version "24.1" + :group 'windows) + (defconst window-safe-min-width 2 "The absolut minimum number of columns of a window. Anything less might crash Emacs.") +(defcustom window-min-width 10 + "The minimum number of columns of any window. +The value has to accomodate margins, fringes, or scrollbars if +present. A value less than `window-safe-min-width' is ignored. +The value of this variable is honored when windows are resized or +split. + +Applications should never rebind this variable. To resize a +window to a width less than the one specified here, an +application should instead call `resize-window' with a non-nil +IGNORE argument. In order to have `split-window' make a window +narrower, explictly specify the SIZE argument of that function." + :type 'integer + :version "24.1" + :group 'windows) + (defun window-iso-combination-p (&optional window horizontal) "If WINDOW is a vertical combination return WINDOW's first child. WINDOW can be any window and defaults to the selected one. @@ -1336,6 +1367,97 @@ (when (window-right window) (resize-window-reset-1 (window-right window) horizontal))) +;; The following routine is used to manually resize the minibuffer +;; window and is currently used, for example, by ispell.el. +(defun resize-mini-window (window delta) + "Resize minibuffer window WINDOW by DELTA lines. +If WINDOW cannot be resized by DELTA lines make it as large \(or +as small) as possible but don't signal an error." + (when (window-minibuffer-p window) + (let* ((frame (window-frame window)) + (root (frame-root-window frame)) + (height (window-total-size window)) + (min-delta + (- (window-total-size root) + (window-min-size root)))) + ;; Sanitize DELTA. + (cond + ((<= (+ height delta) 0) + (setq delta (- (- height 1)))) + ((> delta min-delta) + (setq delta min-delta))) + + ;; Resize now. + (resize-window-reset frame) + ;; Ideally we should be able to resize just the last subwindow of + ;; root here. See the comment in `resize-root-window-vertically' + ;; for why we do not do that. + (resize-this-window root (- delta) nil nil t) + (set-window-new-total window (+ height delta)) + ;; The following routine catches the case where we want to resize + ;; a minibuffer-only frame. + (resize-mini-window-internal window)))) + +(defun resize-window (window delta &optional horizontal ignore) + "Resize WINDOW vertically by DELTA lines. +WINDOW can be an arbitrary window and defaults to the selected +one. An attempt to resize the root window of a frame will raise +an error though. + +DELTA a positive number means WINDOW shall be enlarged by DELTA +lines. DELTA negative means WINDOW shall be shrunk by -DELTA +lines. + +Optional argument HORIZONTAL non-nil means resize WINDOW +horizontally by DELTA columns. In this case a positive DELTA +means enlarge WINDOW by DELTA columns. DELTA negative means +WINDOW shall be shrunk by -DELTA columns. + +Optional argument IGNORE non-nil means ignore any restrictions +imposed by fixed size windows, `window-min-height' or +`window-min-width' settings. IGNORE any window means ignore +restrictions for that window only. IGNORE equal `safe' means +live windows may get as small as `window-safe-min-height' lines +and `window-safe-min-width' columns. + +This function resizes other windows proportionally and never +deletes any windows. If you want to move only the low (right) +edge of WINDOW consider using `adjust-window-trailing-edge' +instead." + (setq window (normalize-any-window window)) + (let* ((frame (window-frame window)) + sibling) + (cond + ((eq window (frame-root-window frame)) + (error "Cannot resize the root window of a frame")) + ((window-minibuffer-p window) + (resize-mini-window window delta)) + ((window-resizable-p window delta horizontal ignore) + (resize-window-reset frame horizontal) + (resize-this-window window delta horizontal ignore t) + (if (and (not (window-splits window)) + (window-iso-combined-p window horizontal) + (setq sibling (or (window-right window) (window-left window))) + (window-sizable-p sibling (- delta) horizontal ignore)) + ;; If window-splits returns nil for WINDOW, WINDOW is part of + ;; an iso-combination, and WINDOW's neighboring right or left + ;; sibling can be resized as requested, resize that sibling. + (let ((normal-delta + (/ (float delta) + (window-total-size (window-parent window) horizontal)))) + (resize-this-window sibling (- delta) horizontal nil t) + (set-window-new-normal + window (+ (window-normal-size window horizontal) + normal-delta)) + (set-window-new-normal + sibling (- (window-normal-size sibling horizontal) + normal-delta))) + ;; Otherwise, resize all other windows in the same combination. + (resize-other-windows window delta horizontal ignore)) + (resize-window-apply frame horizontal)) + (t + (error "Cannot resize window %s" window))))) + (defsubst resize-subwindows-skip-p (window) "Return non-nil if WINDOW shall be skipped by resizing routines." (memq (window-new-normal window) '(ignore stuck skip))) @@ -1805,6 +1927,153 @@ (resize-this-window window delta nil ignore t) delta))) +(defun adjust-window-trailing-edge (window delta &optional horizontal) + "Move WINDOW's bottom edge by DELTA lines. +Optional argument HORIZONTAL non-nil means move WINDOW's right +edge by DELTA columns. WINDOW defaults to the selected window. + +If DELTA is greater zero, then move the edge downwards or to the +right. If DELTA is less than zero, move the edge upwards or to +the left. If the edge can't be moved by DELTA lines or columns, +move it as far as possible in the desired direction." + (setq window (normalize-any-window window)) + (let ((frame (window-frame window)) + (right window) + left this-delta min-delta max-delta failed) + ;; Find the edge we want to move. + (while (and (or (not (window-iso-combined-p right horizontal)) + (not (window-right right))) + (setq right (window-parent right)))) + (cond + ((and (not right) (not horizontal) (not resize-mini-windows) + (eq (window-frame (minibuffer-window frame)) frame)) + (resize-mini-window (minibuffer-window frame) (- delta))) + ((or (not (setq left right)) (not (setq right (window-right right)))) + (if horizontal + (error "No window on the right of this one") + (error "No window below this one"))) + (t + ;; Set LEFT to the first resizable window on the left. This step is + ;; needed to handle fixed-size windows. + (while (and left (window-size-fixed-p left horizontal)) + (setq left + (or (window-left left) + (progn + (while (and (setq left (window-parent left)) + (not (window-iso-combined-p left horizontal)))) + (window-left left))))) + (unless left + (if horizontal + (error "No resizable window on the left of this one") + (error "No resizable window above this one"))) + + ;; Set RIGHT to the first resizable window on the right. This step + ;; is needed to handle fixed-size windows. + (while (and right (window-size-fixed-p right horizontal)) + (setq right + (or (window-right right) + (progn + (while (and (setq right (window-parent right)) + (not (window-iso-combined-p right horizontal)))) + (window-right right))))) + (unless right + (if horizontal + (error "No resizable window on the right of this one") + (error "No resizable window below this one"))) + + ;; LEFT and RIGHT (which might be both internal windows) are now the + ;; two windows we want to resize. + (cond + ((> delta 0) + (setq max-delta (window-max-delta-1 left 0 horizontal nil 'after)) + (setq min-delta (window-min-delta-1 right (- delta) horizontal nil 'before)) + (when (or (< max-delta delta) (> min-delta (- delta))) + ;; We can't get the whole DELTA - move as far as possible. + (setq delta (min max-delta (- min-delta)))) + (unless (zerop delta) + ;; Start resizing. + (resize-window-reset frame horizontal) + ;; Try to enlarge LEFT first. + (setq this-delta (window-resizable left delta horizontal)) + (unless (zerop this-delta) + (resize-this-window + left this-delta horizontal nil t 'before + (if horizontal + (+ (window-left-column left) (window-total-size left t)) + (+ (window-top-line left) (window-total-size left))))) + ;; Shrink windows on right of LEFT. + (resize-other-windows + left delta horizontal nil 'after + (if horizontal + (window-left-column right) + (window-top-line right))))) + ((< delta 0) + (setq max-delta (window-max-delta-1 right 0 horizontal nil 'before)) + (setq min-delta (window-min-delta-1 left delta horizontal nil 'after)) + (when (or (< max-delta (- delta)) (> min-delta delta)) + ;; We can't get the whole DELTA - move as far as possible. + (setq delta (max (- max-delta) min-delta))) + (unless (zerop delta) + ;; Start resizing. + (resize-window-reset frame horizontal) + ;; Try to enlarge RIGHT. + (setq this-delta (window-resizable right (- delta) horizontal)) + (unless (zerop this-delta) + (resize-this-window + right this-delta horizontal nil t 'after + (if horizontal + (window-left-column right) + (window-top-line right)))) + ;; Shrink windows on left of RIGHT. + (resize-other-windows + right (- delta) horizontal nil 'before + (if horizontal + (+ (window-left-column left) (window-total-size left t)) + (+ (window-top-line left) (window-total-size left))))))) + (unless (zerop delta) + ;; Don't report an error in the standard case. + (unless (resize-window-apply frame horizontal) + ;; But do report an error if applying the changes fails. + (error "Failed adjusting window %s" window))))))) + +(defun enlarge-window (delta &optional horizontal) + "Make selected window DELTA lines taller. +Interactively, if no argument is given, make the selected window +one line taller. If optional argument HORIZONTAL is non-nil, +make selected window wider by DELTA columns. If DELTA is +negative, shrink selected window by -DELTA lines or columns. +Return nil." + (interactive "p") + (resize-window (selected-window) delta horizontal)) + +(defun shrink-window (delta &optional horizontal) + "Make selected window DELTA lines smaller. +Interactively, if no argument is given, make the selected window +one line smaller. If optional argument HORIZONTAL is non-nil, +make selected window narrower by DELTA columns. If DELTA is +negative, enlarge selected window by -DELTA lines or columns. +Return nil." + (interactive "p") + (resize-window (selected-window) (- delta) horizontal)) + +(defun maximize-window (&optional window) + "Maximize WINDOW. +Make WINDOW as large as possible without deleting any windows. +WINDOW can be any window and defaults to the selected window." + (interactive) + (setq window (normalize-any-window window)) + (resize-window window (window-max-delta window)) + (resize-window window (window-max-delta window t) t)) + +(defun minimize-window (&optional window) + "Minimize WINDOW. +Make WINDOW as small as possible without deleting any windows. +WINDOW can be any window and defaults to the selected window." + (interactive) + (setq window (normalize-any-window window)) + (resize-window window (- (window-min-delta window))) + (resize-window window (- (window-min-delta window t)) t)) + (defsubst frame-root-window-p (window) "Return non-nil if WINDOW is the root window of its frame." (eq window (frame-root-window window))) @@ -1886,6 +2155,458 @@ (throw 'done t) (setq parent (window-parent parent)))))))) +(defun delete-window (&optional window) + "Delete WINDOW. +WINDOW can be an arbitrary window and defaults to the selected +one. Return nil. + +If the variable `ignore-window-parameters' is non-nil or the +`delete-window' parameter of WINDOW equals t, do not process any +parameters of WINDOW. Otherwise, if the `delete-window' +parameter of WINDOW specifies a function, call that function with +WINDOW as its sole argument and return the value returned by that +function. + +Otherwise, if WINDOW is part of an atomic window, call +`delete-window' with the root of the atomic window as its +argument. If WINDOW is the only window on its frame or the last +non-side window, signal an error." + (interactive) + (setq window (normalize-any-window window)) + (let* ((frame (window-frame window)) + (function (window-parameter window 'delete-window)) + (parent (window-parent window)) + atom-root) + (window-check frame) + (catch 'done + ;; Handle window parameters. + (cond + ;; Ignore window parameters if `ignore-window-parameters' tells + ;; us so or `delete-window' equals t. + ((or ignore-window-parameters (eq function t))) + ((functionp function) + ;; The `delete-window' parameter specifies the function to call. + ;; If that function is `ignore' nothing is done. It's up to the + ;; function called here to avoid infinite recursion. + (throw 'done (funcall function window))) + ((and (window-parameter window 'window-atom) + (setq atom-root (window-atom-root window)) + (not (eq atom-root window))) + (throw 'done (delete-window atom-root))) + ((and (eq (window-parameter window 'window-side) 'none) + (or (not parent) + (not (eq (window-parameter parent 'window-side) 'none)))) + (error "Attempt to delete last non-side window")) + ((not parent) + (error "Attempt to delete minibuffer or sole ordinary window"))) + + (let* ((horizontal (window-hchild parent)) + (size (window-total-size window horizontal)) + (frame-selected + (window-or-subwindow-p (frame-selected-window frame) window)) + ;; Emacs 23 preferably gives WINDOW's space to its left + ;; sibling. + (sibling (or (window-left window) (window-right window)))) + (resize-window-reset frame horizontal) + (cond + ((and (not (window-splits window)) + sibling (window-sizable-p sibling size)) + ;; Resize WINDOW's sibling. + (resize-this-window sibling size horizontal nil t) + (set-window-new-normal + sibling (+ (window-normal-size sibling horizontal) + (window-normal-size window horizontal)))) + ((window-resizable-p window (- size) horizontal nil nil nil t) + ;; Can do without resizing fixed-size windows. + (resize-other-windows window (- size) horizontal)) + (t + ;; Can't do without resizing fixed-size windows. + (resize-other-windows window (- size) horizontal t))) + ;; Actually delete WINDOW. + (delete-window-internal window) + (when (and frame-selected + (window-parameter + (frame-selected-window frame) 'no-other-window)) + ;; `delete-window-internal' has selected a window that should + ;; not be selected, fix this here. + (other-window -1 frame)) + (run-window-configuration-change-hook frame) + (window-check frame) + ;; Always return nil. + nil)))) + +(defun delete-other-windows (&optional window) + "Make WINDOW fill its frame. +WINDOW may be any window and defaults to the selected one. +Return nil. + +If the variable `ignore-window-parameters' is non-nil or the +`delete-other-windows' parameter of WINDOW equals t, do not +process any parameters of WINDOW. Otherwise, if the +`delete-other-windows' parameter of WINDOW specifies a function, +call that function with WINDOW as its sole argument and return +the value returned by that function. + +Otherwise, if WINDOW is part of an atomic window, call this +function with the root of the atomic window as its argument. If +WINDOW is a non-side window, make WINDOW the only non-side window +on the frame. Side windows are not deleted. If WINDOW is a side +window signal an error." + (interactive) + (setq window (normalize-any-window window)) + (let* ((frame (window-frame window)) + (function (window-parameter window 'delete-other-windows)) + (window-side (window-parameter window 'window-side)) + atom-root side-main) + (window-check frame) + (catch 'done + (cond + ;; Ignore window parameters if `ignore-window-parameters' is t or + ;; `delete-other-windows' is t. + ((or ignore-window-parameters (eq function t))) + ((functionp function) + ;; The `delete-other-windows' parameter specifies the function + ;; to call. If the function is `ignore' no windows are deleted. + ;; It's up to the function called to avoid infinite recursion. + (throw 'done (funcall function window))) + ((and (window-parameter window 'window-atom) + (setq atom-root (window-atom-root window)) + (not (eq atom-root window))) + (throw 'done (delete-other-windows atom-root))) + ((eq window-side 'none) + ;; Set side-main to the major non-side window. + (setq side-main (window-with-parameter 'window-side 'none nil t))) + ((memq window-side window-sides) + (error "Cannot make side window the only window"))) + ;; If WINDOW is the main non-side window, do nothing. + (unless (eq window side-main) + (delete-other-windows-internal window side-main) + (run-window-configuration-change-hook frame) + (window-check frame)) + ;; Always return nil. + nil))) + +;;; Splitting windows. +(defsubst window-split-min-size (&optional horizontal) + "Return minimum height of any window when splitting windows. +Optional argument HORIZONTAL non-nil means return minimum width." + (if horizontal + (max window-min-width window-safe-min-width) + (max window-min-height window-safe-min-height))) + +(defun split-window (&optional window size side) + "Make a new window adjacent to WINDOW. +WINDOW can be any window and defaults to the selected one. +Return the new window which is always a live window. + +Optional argument SIZE a positive number means make WINDOW SIZE +lines or columns tall. If SIZE is negative, make the new window +-SIZE lines or columns tall. If and only if SIZE is non-nil, its +absolute value can be less than `window-min-height' or +`window-min-width'; so this command can make a new window as +small as one line or two columns. SIZE defaults to half of +WINDOW's size. Interactively, SIZE is the prefix argument. + +Optional third argument SIDE nil (or `below') specifies that the +new window shall be located below WINDOW. SIDE `above' means the +new window shall be located above WINDOW. In both cases SIZE +specifies the new number of lines for WINDOW \(or the new window +if SIZE is negative) including space reserved for the mode and/or +header line. + +SIDE t (or `right') specifies that the new window shall be +located on the right side of WINDOW. SIDE `left' means the new +window shall be located on the left of WINDOW. In both cases +SIZE specifies the new number of columns for WINDOW \(or the new +window provided SIZE is negative) including space reserved for +fringes and the scrollbar or a divider column. Any other non-nil +value for SIDE is currently handled like t (or `right'). + +If the variable `ignore-window-parameters' is non-nil or the +`split-window' parameter of WINDOW equals t, do not process any +parameters of WINDOW. Otherwise, if the `split-window' parameter +of WINDOW specifies a function, call that function with all three +arguments and return the value returned by that function. + +Otherwise, if WINDOW is part of an atomic window, \"split\" the +root of that atomic window. The new window does not become a +member of that atomic window. + +If WINDOW is live, properties of the new window like margins and +scrollbars are inherited from WINDOW. If WINDOW is an internal +window, these properties as well as the buffer displayed in the +new window are inherited from the window selected on WINDOW's +frame. The selected window is not changed by this function." + (interactive "i") + (setq window (normalize-any-window window)) + (let* ((horizontal (not (memq side '(nil below above)))) + (frame (window-frame window)) + (parent (window-parent window)) + (function (window-parameter window 'split-window)) + (window-side (window-parameter window 'window-side)) + ;; Rebind `window-nest' since in some cases we may have to + ;; override its value. + (window-nest window-nest) + atom-root) + + (window-check frame) + (catch 'done + (cond + ;; Ignore window parameters if either `ignore-window-parameters' + ;; is t or the `split-window' parameter equals t. + ((or ignore-window-parameters (eq function t))) + ((functionp function) + ;; The `split-window' parameter specifies the function to call. + ;; If that function is `ignore', do nothing. + (throw 'done (funcall function window size side))) + ;; If WINDOW is a subwindow of an atomic window, split the root + ;; window of that atomic window instead. + ((and (window-parameter window 'window-atom) + (setq atom-root (window-atom-root window)) + (not (eq atom-root window))) + (throw 'done (split-window atom-root size side)))) + + (when (and window-side + (or (not parent) + (not (window-parameter parent 'window-side)))) + ;; WINDOW is a side root window. To make sure that a new parent + ;; window gets created set `window-nest' to t. + (setq window-nest t)) + + (when (and window-splits size (> size 0)) + ;; If `window-splits' is non-nil and SIZE is a non-negative + ;; integer, we cannot reasonably resize other windows. Rather + ;; bind `window-nest' to t to make sure that subsequent window + ;; deletions are handled correctly. + (setq window-nest t)) + + (let* ((parent-size + ;; `parent-size' is the size of WINDOW's parent, provided + ;; it has one. + (when parent (window-total-size parent horizontal))) + ;; `resize' non-nil means we are supposed to resize other + ;; windows in WINDOW's combination. + (resize + (and window-splits (not window-nest) + ;; Resize makes sense in iso-combinations only. + (window-iso-combined-p window horizontal))) + ;; `old-size' is the current size of WINDOW. + (old-size (window-total-size window horizontal)) + ;; `new-size' is the specified or calculated size of the + ;; new window. + (new-size + (cond + ((not size) + (max (window-split-min-size horizontal) + (if resize + ;; When resizing try to give the new window the + ;; average size of a window in its combination. + (min (- parent-size + (window-min-size parent horizontal)) + (/ parent-size + (1+ (window-iso-combinations + parent horizontal)))) + ;; Else try to give the new window half the size + ;; of WINDOW (plus an eventual odd line). + (+ (/ old-size 2) (% old-size 2))))) + ((>= size 0) + ;; SIZE non-negative specifies the new size of WINDOW. + + ;; Note: Specifying a non-negative SIZE is practically + ;; always done as workaround for making the new window + ;; appear above or on the left of the new window (the + ;; ispell window is a typical example of that). In all + ;; these cases the SIDE argument should be set to 'above + ;; or 'left in order to support the 'resize option. + ;; Here we have to nest the windows instead, see above. + (- old-size size)) + (t + ;; SIZE negative specifies the size of the new window. + (- size)))) + new-parent new-normal) + + ;; Check SIZE. + (cond + ((not size) + (cond + (resize + ;; SIZE unspecified, resizing. + (when (and (not (window-sizable-p parent (- new-size) horizontal)) + ;; Try again with minimum split size. + (setq new-size + (max new-size (window-split-min-size horizontal))) + (not (window-sizable-p parent (- new-size) horizontal))) + (error "Window %s too small for splitting" parent))) + ((> (+ new-size (window-min-size window horizontal)) old-size) + ;; SIZE unspecified, no resizing. + (error "Window %s too small for splitting" window)))) + ((and (>= size 0) + (or (>= size old-size) + (< new-size (if horizontal + window-safe-min-width + window-safe-min-width)))) + ;; SIZE specified as new size of old window. If the new size + ;; is larger than the old size or the size of the new window + ;; would be less than the safe minimum, signal an error. + (error "Window %s too small for splitting" window)) + (resize + ;; SIZE specified, resizing. + (unless (window-sizable-p parent (- new-size) horizontal) + ;; If we cannot resize the parent give up. + (error "Window %s too small for splitting" parent))) + ((or (< new-size + (if horizontal window-safe-min-width window-safe-min-height)) + (< (- old-size new-size) + (if horizontal window-safe-min-width window-safe-min-height))) + ;; SIZE specification violates minimum size restrictions. + (error "Window %s too small for splitting" window))) + + (resize-window-reset frame horizontal) + + (setq new-parent + ;; 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-nest (not (window-iso-combined-p window horizontal)))) + (setq new-normal + ;; Make new-normal the normal size of the new window. + (cond + (size (/ (float new-size) (if new-parent old-size parent-size))) + (new-parent 0.5) + (resize (/ 1.0 (1+ (window-iso-combinations parent horizontal)))) + (t (/ (window-normal-size window horizontal) 2.0)))) + + (if resize + ;; Try to get space from OLD's siblings. We could go "up" and + ;; try getting additional space from surrounding windows but + ;; we won't be able to return space to those windows when we + ;; delete the one we create here. Hence we do not go up. + (progn + (resize-subwindows parent (- new-size) horizontal) + (let* ((normal (- 1.0 new-normal)) + (sub (window-child parent))) + (while sub + (set-window-new-normal + sub (* (window-normal-size sub horizontal) normal)) + (setq sub (window-right sub))))) + ;; Get entire space from WINDOW. + (set-window-new-total window (- old-size new-size)) + (resize-this-window window (- new-size) horizontal) + (set-window-new-normal + window (- (if new-parent 1.0 (window-normal-size window horizontal)) + new-normal))) + + (let* ((new (split-window-internal window new-size side new-normal))) + ;; Inherit window-side parameters, if any. + (when (and window-side new-parent) + (set-window-parameter (window-parent new) 'window-side window-side) + (set-window-parameter new 'window-side window-side)) + + (run-window-configuration-change-hook frame) + (window-check frame) + ;; Always return the new window. + new))))) + +;; I think this should be the default; I think people will prefer it--rms. +(defcustom split-window-keep-point t + "If non-nil, \\[split-window-above-each-other] keeps the original point \ +in both children. +This is often more convenient for editing. +If nil, adjust point in each of the two windows to minimize redisplay. +This is convenient on slow terminals, but point can move strangely. + +This option applies only to `split-window-above-each-other' and +functions that call it. `split-window' always keeps the original +point in both children." + :type 'boolean + :group 'windows) + +(defun split-window-above-each-other (&optional size) + "Split selected window into two windows, one above the other. +The upper window gets SIZE lines and the lower one gets the rest. +SIZE negative means the lower window gets -SIZE lines and the +upper one the rest. With no argument, split windows equally or +close to it. Both windows display the same buffer, now current. + +If the variable `split-window-keep-point' is non-nil, both new +windows will get the same value of point as the selected window. +This is often more convenient for editing. The upper window is +the selected window. + +Otherwise, we choose window starts so as to minimize the amount of +redisplay; this is convenient on slow terminals. The new selected +window is the one that the current value of point appears in. The +value of point can change if the text around point is hidden by the +new mode line. + +Regardless of the value of `split-window-keep-point', the upper +window is the original one and the return value is the new, lower +window." + (interactive "P") + (let ((old-window (selected-window)) + (old-point (point)) + (size (and size (prefix-numeric-value size))) + moved-by-window-height moved new-window bottom) + (when (and size (< size 0) (< (- size) window-min-height)) + ;; `split-window' would not signal an error here. + (error "Size of new window too small")) + (setq new-window (split-window nil size)) + (unless split-window-keep-point + (with-current-buffer (window-buffer) + (goto-char (window-start)) + (setq moved (vertical-motion (window-height))) + (set-window-start new-window (point)) + (when (> (point) (window-point new-window)) + (set-window-point new-window (point))) + (when (= moved (window-height)) + (setq moved-by-window-height t) + (vertical-motion -1)) + (setq bottom (point))) + (and moved-by-window-height + (<= bottom (point)) + (set-window-point old-window (1- bottom))) + (and moved-by-window-height + (<= (window-start new-window) old-point) + (set-window-point new-window old-point) + (select-window new-window))) + (split-window-save-restore-data new-window old-window))) + +(defalias 'split-window-vertically 'split-window-above-each-other) + +;; This is to avoid compiler warnings. +(defvar view-return-to-alist) + +(defun split-window-save-restore-data (new-window old-window) + (with-current-buffer (window-buffer) + (when view-mode + (let ((old-info (assq old-window view-return-to-alist))) + (when old-info + (push (cons new-window (cons (car (cdr old-info)) t)) + view-return-to-alist)))) + new-window)) + +(defun split-window-side-by-side (&optional size) + "Split selected window into two windows side by side. +The selected window becomes the left one and gets SIZE columns. +SIZE negative means the right window gets -SIZE lines. + +SIZE includes the width of the window's scroll bar; if there are +no scroll bars, it includes the width of the divider column to +the window's right, if any. SIZE omitted or nil means split +window equally. + +The selected window remains selected. Return the new window." + (interactive "P") + (let ((old-window (selected-window)) + (size (and size (prefix-numeric-value size))) + new-window) + (when (and size (< size 0) (< (- size) window-min-width)) + ;; `split-window' would not signal an error here. + (error "Size of new window too small")) + (split-window-save-restore-data (split-window nil size t) old-window))) + +(defalias 'split-window-horizontally 'split-window-side-by-side) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; `balance-windows' subroutines using `window-tree' @@ -2866,102 +3587,6 @@ ;; input focus and is risen. (select-frame-set-input-focus new-frame)) buffer)) - -;; I think this should be the default; I think people will prefer it--rms. -(defcustom split-window-keep-point t - "If non-nil, \\[split-window-vertically] keeps the original point \ -in both children. -This is often more convenient for editing. -If nil, adjust point in each of the two windows to minimize redisplay. -This is convenient on slow terminals, but point can move strangely. - -This option applies only to `split-window-vertically' and -functions that call it. `split-window' always keeps the original -point in both children." - :type 'boolean - :group 'windows) - -(defun split-window-vertically (&optional size) - "Split selected window into two windows, one above the other. -The upper window gets SIZE lines and the lower one gets the rest. -SIZE negative means the lower window gets -SIZE lines and the -upper one the rest. With no argument, split windows equally or -close to it. Both windows display the same buffer, now current. - -If the variable `split-window-keep-point' is non-nil, both new -windows will get the same value of point as the selected window. -This is often more convenient for editing. The upper window is -the selected window. - -Otherwise, we choose window starts so as to minimize the amount of -redisplay; this is convenient on slow terminals. The new selected -window is the one that the current value of point appears in. The -value of point can change if the text around point is hidden by the -new mode line. - -Regardless of the value of `split-window-keep-point', the upper -window is the original one and the return value is the new, lower -window." - (interactive "P") - (let ((old-window (selected-window)) - (old-point (point)) - (size (and size (prefix-numeric-value size))) - moved-by-window-height moved new-window bottom) - (and size (< size 0) - ;; Handle negative SIZE value. - (setq size (+ (window-height) size))) - (setq new-window (split-window nil size)) - (unless split-window-keep-point - (with-current-buffer (window-buffer) - (goto-char (window-start)) - (setq moved (vertical-motion (window-height))) - (set-window-start new-window (point)) - (when (> (point) (window-point new-window)) - (set-window-point new-window (point))) - (when (= moved (window-height)) - (setq moved-by-window-height t) - (vertical-motion -1)) - (setq bottom (point))) - (and moved-by-window-height - (<= bottom (point)) - (set-window-point old-window (1- bottom))) - (and moved-by-window-height - (<= (window-start new-window) old-point) - (set-window-point new-window old-point) - (select-window new-window))) - (split-window-save-restore-data new-window old-window))) - -;; This is to avoid compiler warnings. -(defvar view-return-to-alist) - -(defun split-window-save-restore-data (new-window old-window) - (with-current-buffer (window-buffer) - (when view-mode - (let ((old-info (assq old-window view-return-to-alist))) - (when old-info - (push (cons new-window (cons (car (cdr old-info)) t)) - view-return-to-alist)))) - new-window)) - -(defun split-window-horizontally (&optional size) - "Split selected window into two windows side by side. -The selected window becomes the left one and gets SIZE columns. -SIZE negative means the right window gets -SIZE lines. - -SIZE includes the width of the window's scroll bar; if there are -no scroll bars, it includes the width of the divider column to -the window's right, if any. SIZE omitted or nil means split -window equally. - -The selected window remains selected. Return the new window." - (interactive "P") - (let ((old-window (selected-window)) - (size (and size (prefix-numeric-value size)))) - (and size (< size 0) - ;; Handle negative SIZE value. - (setq size (+ (window-width) size))) - (split-window-save-restore-data (split-window nil size t) old-window))) - (defun set-window-text-height (window height) "Set the height in lines of the text display area of WINDOW to HEIGHT. @@ -3663,9 +4288,12 @@ (if (integerp t-p-w-w) (< (window-width window) t-p-w-w) t-p-w-w)))) - -(define-key ctl-x-map "2" 'split-window-vertically) -(define-key ctl-x-map "3" 'split-window-horizontally) + +(define-key ctl-x-map "0" 'delete-window) +(define-key ctl-x-map "1" 'delete-other-windows) +(define-key ctl-x-map "2" 'split-window-above-each-other) +(define-key ctl-x-map "3" 'split-window-side-by-side) +(define-key ctl-x-map "^" 'enlarge-window) (define-key ctl-x-map "}" 'enlarge-window-horizontally) (define-key ctl-x-map "{" 'shrink-window-horizontally) (define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer) === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-09 06:35:02 +0000 +++ src/ChangeLog 2011-06-10 06:55:18 +0000 @@ -1,3 +1,67 @@ +2011-06-10 Martin Rudalics + + * window.c: Remove declarations of Qwindow_size_fixed, + window_min_size_1, window_min_size_2, window_min_size, + size_window, window_fixed_size_p, enlarge_window, delete_window. + Remove static from declaration of Qdelete_window, it's + temporarily needed by Fbury_buffer. + (replace_window): Don't assign orig_top_line and + orig_total_lines. + (Fdelete_window, delete_window): Remove. Window deletion is + handled by window.el. + (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace + Fdelete_window calls with calls to Qdelete_window. + (Fdelete_other_windows): Remove. Deleting other windows is + handled by window.el. + (window_fixed_size_p): Remove. Fixed-sizeness of windows is + handled in window.el. + (window_min_size_2, window_min_size_1, window_min_size): Remove. + Window minimum sizes are handled in window.el. + (shrink_windows, size_window, set_window_height) + (set_window_width, change_window_heights, window_height) + (window_width, CURBEG, CURSIZE, enlarge_window) + (adjust_window_trailing_edge, Fadjust_window_trailing_edge) + (Fenlarge_window, Fshrink_window): Remove. Window resizing is + handled in window.el. + (make_dummy_parent): Rename to make_parent_window and give it a + second argument horflag. + (make_window): Don't set resize_proportionally any more. + (Fsplit_window): Remove. Windows are split in window.el. + (save_restore_action, save_restore_orig_size) + (shrink_window_lowest_first, save_restore_orig_size): Remove. + Resize mini windows in window.el. + (grow_mini_window, shrink_mini_window): Implement by calling + Qresize_root_window_vertically, resize_window_check and + resize_window_apply. + (saved_window, Fset_window_configuration, save_window_save): Do + not handle orig_top_line, orig_total_lines, and + resize_proportionally. + (window_min_height, window_min_width): Move to window.el. + (keys_of_window): Move bindings for delete-other-windows, + split-window, delete-window and enlarge-window to window.el. + + * buffer.c: Temporarily extern Qdelete_window. + (Fbury_buffer): Temporarily call Qdelete_window instead of + Fdelete_window (Fbury_buffer will move to window.el soon). + + * frame.c (set_menu_bar_lines_1): Remove code handling + orig_top_line and orig_total_lines. + + * dispnew.c (adjust_frame_glyphs_initially): Don't use + set_window_height but set heights directly. + (change_frame_size_1): Use resize_frame_windows. + + * xdisp.c (init_xdisp): Don't use set_window_height but set + heights directly. + + * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use + resize_frame_windows instead of change_window_heights and run + run_window_configuration_change_hook. + + * w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows + instead of change_window_heights and run + run_window_configuration_change_hook. + 2011-06-09 Martin Rudalics * window.c (replace_window): Rename second argument REPLACEMENT to === modified file 'src/buffer.c' --- src/buffer.c 2011-05-30 16:47:35 +0000 +++ src/buffer.c 2011-06-10 06:55:18 +0000 @@ -1938,6 +1938,8 @@ return Qnil; } +extern Lisp_Object Qdelete_window; + DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "", doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers. There it is the least likely candidate for `other-buffer' to return; @@ -1969,7 +1971,7 @@ else if (NILP (XWINDOW (selected_window)->parent)) Ficonify_frame (Fwindow_frame (selected_window)); else - Fdelete_window (selected_window); + call1 (Qdelete_window, selected_window); } } else === modified file 'src/dispnew.c' --- src/dispnew.c 2011-05-31 14:52:10 +0000 +++ src/dispnew.c 2011-06-10 06:55:18 +0000 @@ -1933,13 +1933,13 @@ /* Do it for the root window. */ XSETFASTINT (root->top_line, top_margin); + XSETFASTINT (root->total_lines, frame_lines - 1 - top_margin); XSETFASTINT (root->total_cols, frame_cols); - set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0); /* Do it for the mini-buffer window. */ XSETFASTINT (mini->top_line, frame_lines - 1); + XSETFASTINT (mini->total_lines, 1); XSETFASTINT (mini->total_cols, frame_cols); - set_window_height (root->next, 1, 0); adjust_frame_glyphs (sf); glyphs_initialized_initially_p = 1; @@ -5715,24 +5715,7 @@ if (newheight != FRAME_LINES (f)) { - if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) - { - /* Frame has both root and mini-buffer. */ - XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line, - FRAME_TOP_MARGIN (f)); - set_window_height (FRAME_ROOT_WINDOW (f), - (newheight - - 1 - - FRAME_TOP_MARGIN (f)), - 2); - XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line, - newheight - 1); - set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0); - } - else - /* Frame has just one top-level window. */ - set_window_height (FRAME_ROOT_WINDOW (f), - newheight - FRAME_TOP_MARGIN (f), 2); + resize_frame_windows (f, newheight, 0); /* MSDOS frames cannot PRETEND, as they change frame size by manipulating video hardware. */ @@ -5742,9 +5725,7 @@ if (new_frame_total_cols != FRAME_TOTAL_COLS (f)) { - set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2); - if (FRAME_HAS_MINIBUF_P (f)) - set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0); + resize_frame_windows (f, new_frame_total_cols, 1); /* MSDOS frames cannot PRETEND, as they change frame size by manipulating video hardware. */ === modified file 'src/frame.c' --- src/frame.c 2011-06-07 12:51:07 +0000 +++ src/frame.c 2011-06-10 06:55:18 +0000 @@ -135,11 +135,6 @@ XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); - if (INTEGERP (w->orig_top_line)) - XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n); - if (INTEGERP (w->orig_total_lines)) - XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n); - /* Handle just the top child in a vertical split. */ if (!NILP (w->vchild)) set_menu_bar_lines_1 (w->vchild, n); === modified file 'src/w32fns.c' --- src/w32fns.c 2011-04-28 02:01:33 +0000 +++ src/w32fns.c 2011-06-10 06:55:18 +0000 @@ -1596,7 +1596,7 @@ } FRAME_TOOL_BAR_LINES (f) = nlines; - change_window_heights (root_window, delta); + resize_frame_windows (f, FRAME_LINES (f), 0); adjust_glyphs (f); /* We also have to make sure that the internal border at the top of @@ -1631,6 +1631,9 @@ if (WINDOWP (f->tool_bar_window)) clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); } + + run_window_configuration_change_hook (f); + } @@ -5822,8 +5825,6 @@ UNGCPRO; return unbind_to (count, deleted); } - - /*********************************************************************** File selection dialog === modified file 'src/window.c' --- src/window.c 2011-06-09 06:35:02 +0000 +++ src/window.c 2011-06-10 06:55:18 +0000 @@ -50,17 +50,15 @@ #include "nsterm.h" #endif -Lisp_Object Qwindowp, Qwindow_live_p; +Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window; static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; -static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; +static Lisp_Object Qwindow_deletable_p, Qdisplay_buffer; static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; static Lisp_Object Qsafe, Qabove, Qbelow; static Lisp_Object Qauto_buffer_name; -static Lisp_Object Qwindow_size_fixed; - static int displayed_window_lines (struct window *); static struct window *decode_window (Lisp_Object); static int count_windows (struct window *); @@ -68,13 +66,7 @@ static void window_scroll (Lisp_Object, int, int, int); static void window_scroll_pixel_based (Lisp_Object, int, int, int); static void window_scroll_line_based (Lisp_Object, int, int, int); -static int window_min_size_1 (struct window *, int, int); -static int window_min_size_2 (struct window *, int, int); -static int window_min_size (struct window *, int, int, int, int *); -static void size_window (Lisp_Object, int, int, int, int, int); static int freeze_window_start (struct window *, void *); -static int window_fixed_size_p (struct window *, int, int); -static void enlarge_window (Lisp_Object, int, int); static Lisp_Object window_list (void); static int add_window_to_list (struct window *, void *); static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, @@ -1803,9 +1795,7 @@ return table; } -static void delete_window (Lisp_Object); - -/* Record info on buffer window w is displaying +/* Record info on buffer window W is displaying when it is about to cease to display that buffer. */ static void unshow_buffer (register struct window *w) @@ -1891,7 +1881,6 @@ XSETFASTINT (n->window_end_pos, 0); n->window_end_valid = Qnil; n->frozen_window_start_p = 0; - n->orig_top_line = n->orig_total_lines = Qnil; } n->next = tem = o->next; @@ -1994,232 +1983,6 @@ call1 (Qdelete_window, window); } -DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", - doc: /* Remove WINDOW from its frame. -WINDOW defaults to the selected window. Return nil. -Signal an error when WINDOW is the only window on its frame. */) - (register Lisp_Object window) -{ - struct frame *f; - if (NILP (window)) - window = selected_window; - else - CHECK_LIVE_WINDOW (window); - - f = XFRAME (WINDOW_FRAME (XWINDOW (window))); - delete_window (window); - - run_window_configuration_change_hook (f); - - return Qnil; -} - -static void -delete_window (register Lisp_Object window) -{ - register Lisp_Object tem, parent, sib; - register struct window *p; - register struct window *par; - struct frame *f; - - /* Because this function is called by other C code on non-leaf - windows, the CHECK_LIVE_WINDOW macro would choke inappropriately, - so we can't decode_window here. */ - CHECK_WINDOW (window); - p = XWINDOW (window); - - /* It's a no-op to delete an already-deleted window. */ - if (NILP (p->buffer) - && NILP (p->hchild) - && NILP (p->vchild)) - return; - - parent = p->parent; - if (NILP (parent)) - error ("Attempt to delete minibuffer or sole ordinary window"); - par = XWINDOW (parent); - - windows_or_buffers_changed++; - Vwindow_list = Qnil; - f = XFRAME (WINDOW_FRAME (p)); - FRAME_WINDOW_SIZES_CHANGED (f) = 1; - - /* Are we trying to delete any frame's selected window? */ - { - Lisp_Object swindow, pwindow; - - /* See if the frame's selected window is either WINDOW - or any subwindow of it, by finding all that window's parents - and comparing each one with WINDOW. */ - swindow = FRAME_SELECTED_WINDOW (f); - - while (1) - { - pwindow = swindow; - while (!NILP (pwindow)) - { - if (EQ (window, pwindow)) - break; - pwindow = XWINDOW (pwindow)->parent; - } - - /* If the window being deleted is not a parent of SWINDOW, - then SWINDOW is ok as the new selected window. */ - if (!EQ (window, pwindow)) - break; - /* Otherwise, try another window for SWINDOW. */ - swindow = Fnext_window (swindow, Qlambda, Qnil); - - /* If we get back to the frame's selected window, - it means there was no acceptable alternative, - so we cannot delete. */ - if (EQ (swindow, FRAME_SELECTED_WINDOW (f))) - error ("Cannot delete window"); - } - - /* If we need to change SWINDOW, do it. */ - if (! EQ (swindow, FRAME_SELECTED_WINDOW (f))) - { - /* If we're about to delete the selected window on the - selected frame, then we should use Fselect_window to select - the new window. On the other hand, if we're about to - delete the selected window on any other frame, we shouldn't do - anything but set the frame's selected_window slot. */ - if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) - Fselect_window (swindow, Qnil); - else - FRAME_SELECTED_WINDOW (f) = swindow; - } - } - - /* Now we know we can delete this one. */ - window_deletion_count++; - - tem = p->buffer; - /* tem is null for dummy parent windows - (which have inferiors but not any contents themselves) */ - if (!NILP (tem)) - { - unshow_buffer (p); - unchain_marker (XMARKER (p->pointm)); - unchain_marker (XMARKER (p->start)); - } - - /* Free window glyph matrices. It is sure that they are allocated - again when ADJUST_GLYPHS is called. Block input so that expose - events and other events that access glyph matrices are not - processed while we are changing them. */ - BLOCK_INPUT; - free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f))); - - tem = p->next; - if (!NILP (tem)) - XWINDOW (tem)->prev = p->prev; - - tem = p->prev; - if (!NILP (tem)) - XWINDOW (tem)->next = p->next; - - if (EQ (window, par->hchild)) - par->hchild = p->next; - if (EQ (window, par->vchild)) - par->vchild = p->next; - - /* Find one of our siblings to give our space to. */ - sib = p->prev; - if (NILP (sib)) - { - /* If p gives its space to its next sibling, that sibling needs - to have its top/left side pulled back to where p's is. - set_window_{height,width} will re-position the sibling's - children. */ - sib = p->next; - XWINDOW (sib)->top_line = p->top_line; - XWINDOW (sib)->left_col = p->left_col; - } - - /* Stretch that sibling. */ - if (!NILP (par->vchild)) - set_window_height (sib, - XFASTINT (XWINDOW (sib)->total_lines) + XFASTINT (p->total_lines), - 1); - if (!NILP (par->hchild)) - set_window_width (sib, - XFASTINT (XWINDOW (sib)->total_cols) + XFASTINT (p->total_cols), - 1); - - /* If parent now has only one child, - put the child into the parent's place. */ - tem = par->hchild; - if (NILP (tem)) - tem = par->vchild; - if (NILP (XWINDOW (tem)->next)) { - replace_window (parent, tem, 1); - par = XWINDOW (tem); - } - - /* Since we may be deleting combination windows, we must make sure that - not only p but all its children have been marked as deleted. */ - if (! NILP (p->hchild)) - delete_all_subwindows (p->hchild); - else if (! NILP (p->vchild)) - delete_all_subwindows (p->vchild); - - /* Mark this window as deleted. */ - p->buffer = p->hchild = p->vchild = Qnil; - - if (! NILP (par->parent)) - par = XWINDOW (par->parent); - - /* Check if we have a v/hchild with a v/hchild. In that case remove - one of them. */ - - if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild)) - { - p = XWINDOW (par->vchild); - par->vchild = p->vchild; - tem = p->vchild; - } - else if (! NILP (par->hchild) && ! NILP (XWINDOW (par->hchild)->hchild)) - { - p = XWINDOW (par->hchild); - par->hchild = p->hchild; - tem = p->hchild; - } - else - p = 0; - - if (p) - { - while (! NILP (tem)) { - XWINDOW (tem)->parent = p->parent; - if (NILP (XWINDOW (tem)->next)) - break; - tem = XWINDOW (tem)->next; - } - if (! NILP (tem)) { - /* The next of the v/hchild we are removing is now the next of the - last child for the v/hchild: - Before v/hchild -> v/hchild -> next1 -> next2 - | - -> next3 - After: v/hchild -> next1 -> next2 -> next3 - */ - XWINDOW (tem)->next = p->next; - if (! NILP (p->next)) - XWINDOW (p->next)->prev = tem; - } - p->next = p->prev = p->vchild = p->hchild = p->buffer = Qnil; - } - - - /* Adjust glyph matrices. */ - adjust_glyphs (f); - UNBLOCK_INPUT; -} - - - /*********************************************************************** Window List ***********************************************************************/ @@ -2645,7 +2408,6 @@ { WINDOW_LOOP_UNUSED, GET_BUFFER_WINDOW, /* Arg is buffer */ - DELETE_OTHER_WINDOWS, /* Arg is window not to delete */ DELETE_BUFFER_WINDOWS, /* Arg is buffer */ UNSHOW_BUFFER, /* Arg is buffer */ REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ @@ -2729,11 +2491,6 @@ } break; - case DELETE_OTHER_WINDOWS: - if (!EQ (window, obj)) - Fdelete_window (window); - break; - case DELETE_BUFFER_WINDOWS: if (EQ (w->buffer, obj)) { @@ -2769,7 +2526,7 @@ Fset_buffer (w->buffer); } else - Fdelete_window (window); + call1 (Qdelete_window, window); } break; @@ -2804,7 +2561,7 @@ XSETWINDOW (window_to_delete, w); /* If this window is dedicated and not the only window in its frame, then kill it. */ - Fdelete_window (window_to_delete); + call1 (Qdelete_window, window_to_delete); } else { @@ -3128,68 +2885,6 @@ } -DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, - 0, 1, "", - doc: /* Make WINDOW (or the selected window) fill its frame. -Only the frame WINDOW is on is affected. -This function tries to reduce display jumps by keeping the text -previously visible in WINDOW in the same place on the frame. Doing this -depends on the value of (window-start WINDOW), so if calling this -function in a program gives strange scrolling, make sure the -window-start value is reasonable when this function is called. */) - (Lisp_Object window) -{ - struct window *w; - EMACS_INT startpos; - int top, new_top; - - if (NILP (window)) - window = selected_window; - else - CHECK_LIVE_WINDOW (window); - w = XWINDOW (window); - - startpos = marker_position (w->start); - top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); - - if (MINI_WINDOW_P (w) && top > 0) - error ("Can't expand minibuffer to full frame"); - - window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w)); - - /* Try to minimize scrolling, by setting the window start to the point - will cause the text at the old window start to be at the same place - on the frame. But don't try to do this if the window start is - outside the visible portion (as might happen when the display is - not current, due to typeahead). */ - new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); - if (new_top != top - && startpos >= BUF_BEGV (XBUFFER (w->buffer)) - && startpos <= BUF_ZV (XBUFFER (w->buffer))) - { - struct position pos; - struct buffer *obuf = current_buffer; - - Fset_buffer (w->buffer); - /* This computation used to temporarily move point, but that can - have unwanted side effects due to text properties. */ - pos = *vmotion (startpos, -top, w); - - set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); - w->window_end_valid = Qnil; - w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE - || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt - : Qnil); - /* We need to do this, so that the window-scroll-functions - get called. */ - w->optional_new_start = Qt; - - set_buffer_internal (obuf); - } - - return Qnil; -} - DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, 0, 2, "bDelete windows on (buffer): ", doc: /* Delete all windows showing BUFFER-OR-NAME. @@ -3271,8 +2966,6 @@ window_loop (UNSHOW_BUFFER, buffer, 1, frame); } -/* Set the height of WINDOW and all its inferiors. */ - /* If *ROWS or *COLS are too small a size for FRAME, set them to the minimum allowable size. */ @@ -3296,243 +2989,6 @@ *cols = MIN_SAFE_WINDOW_WIDTH; } -/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means - check if W's width can be changed, otherwise check W's height. - CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's - siblings, too. If none of the siblings is resizable, WINDOW isn't - either. */ - -static int -window_fixed_size_p (struct window *w, int width_p, int check_siblings_p) -{ - int fixed_p; - struct window *c; - - if (!NILP (w->hchild)) - { - c = XWINDOW (w->hchild); - - if (width_p) - { - /* A horizontal combination is fixed-width if all of if its - children are. */ - while (c && window_fixed_size_p (c, width_p, 0)) - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - fixed_p = c == NULL; - } - else - { - /* A horizontal combination is fixed-height if one of if its - children is. */ - while (c && !window_fixed_size_p (c, width_p, 0)) - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - fixed_p = c != NULL; - } - } - else if (!NILP (w->vchild)) - { - c = XWINDOW (w->vchild); - - if (width_p) - { - /* A vertical combination is fixed-width if one of if its - children is. */ - while (c && !window_fixed_size_p (c, width_p, 0)) - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - fixed_p = c != NULL; - } - else - { - /* A vertical combination is fixed-height if all of if its - children are. */ - while (c && window_fixed_size_p (c, width_p, 0)) - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - fixed_p = c == NULL; - } - } - else if (BUFFERP (w->buffer)) - { - struct buffer *old = current_buffer; - Lisp_Object val; - - current_buffer = XBUFFER (w->buffer); - val = find_symbol_value (Qwindow_size_fixed); - current_buffer = old; - - fixed_p = 0; - if (!EQ (val, Qunbound)) - { - fixed_p = !NILP (val); - - if (fixed_p - && ((EQ (val, Qheight) && width_p) - || (EQ (val, Qwidth) && !width_p))) - fixed_p = 0; - } - - /* Can't tell if this one is resizable without looking at - siblings. If all siblings are fixed-size this one is too. */ - if (!fixed_p && check_siblings_p && WINDOWP (w->parent)) - { - Lisp_Object child; - - for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev) - if (!window_fixed_size_p (XWINDOW (child), width_p, 0)) - break; - - if (NILP (child)) - for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next) - if (!window_fixed_size_p (XWINDOW (child), width_p, 0)) - break; - - if (NILP (child)) - fixed_p = 1; - } - } - else - fixed_p = 1; - - return fixed_p; -} - -/* Return minimum size of leaf window W. WIDTH_P non-zero means return - the minimum width of W, WIDTH_P zero means return the minimum height - of W. SAFE_P non-zero means ignore window-min-height|width but just - return values that won't crash Emacs and don't hide components like - fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the - minibuffer window, always return 1. */ - -static int -window_min_size_2 (struct window *w, int width_p, int safe_p) -{ - /* We should consider buffer-local values of window_min_height and - window_min_width here. */ - if (width_p) - { - int safe_size = (MIN_SAFE_WINDOW_WIDTH - + WINDOW_FRINGE_COLS (w) - + WINDOW_SCROLL_BAR_COLS (w)); - - return safe_p ? safe_size : max (window_min_width, safe_size); - } - else if (MINI_WINDOW_P (w)) - return 1; - else - { - int safe_size = (MIN_SAFE_WINDOW_HEIGHT - + ((BUFFERP (w->buffer) - && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format))) - ? 1 : 0)); - - return safe_p ? safe_size : max (window_min_height, safe_size); - } -} - -/* Return minimum size of window W, not taking fixed-width windows into - account. WIDTH_P non-zero means return the minimum width, otherwise - return the minimum height. SAFE_P non-zero means ignore - window-min-height|width but just return values that won't crash Emacs - and don't hide components like fringes, scrollbars, or modelines. If - W is a combination window, compute the minimum size from the minimum - sizes of W's children. */ - -static int -window_min_size_1 (struct window *w, int width_p, int safe_p) -{ - struct window *c; - int size; - - if (!NILP (w->hchild)) - { - /* W is a horizontal combination. */ - c = XWINDOW (w->hchild); - size = 0; - - if (width_p) - { - /* The minimum width of a horizontal combination is the sum of - the minimum widths of its children. */ - while (c) - { - size += window_min_size_1 (c, 1, safe_p); - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - } - } - else - { - /* The minimum height of a horizontal combination is the - maximum of the minimum heights of its children. */ - while (c) - { - size = max (window_min_size_1 (c, 0, safe_p), size); - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - } - } - } - else if (!NILP (w->vchild)) - { - /* W is a vertical combination. */ - c = XWINDOW (w->vchild); - size = 0; - - if (width_p) - { - /* The minimum width of a vertical combination is the maximum - of the minimum widths of its children. */ - while (c) - { - size = max (window_min_size_1 (c, 1, safe_p), size); - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - } - } - else - { - /* The minimum height of a vertical combination is the sum of - the minimum height of its children. */ - while (c) - { - size += window_min_size_1 (c, 0, safe_p); - c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; - } - } - } - else - /* W is a leaf window. */ - size = window_min_size_2 (w, width_p, safe_p); - - return size; -} - -/* Return the minimum size of window W, taking fixed-size windows into - account. WIDTH_P non-zero means return the minimum width, otherwise - return the minimum height. SAFE_P non-zero means ignore - window-min-height|width but just return values that won't crash Emacs - and don't hide components like fringes, scrollbars, or modelines. - IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED - to 1 if W is fixed-size unless FIXED is null. */ - -static int -window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed) -{ - int size, fixed_p; - - if (ignore_fixed_p) - fixed_p = 0; - else - fixed_p = window_fixed_size_p (w, width_p, 1); - - if (fixed) - *fixed = fixed_p; - - if (fixed_p) - size = WINDOW_TOTAL_SIZE (w, width_p); - else - size = window_min_size_1 (w, width_p, safe_p); - - return size; -} - - /* Adjust the margins of window W if text area is too small. Return 1 if window width is ok after adjustment; 0 if window is still too narrow. */ @@ -3567,410 +3023,6 @@ w->left_margin_cols = make_number (margin_cols); return 1; } - -/* Calculate new sizes for windows in the list FORWARD when their - compound size goes from TOTAL to SIZE. TOTAL must be greater than - SIZE. The number of windows in FORWARD is NCHILDREN, and the number - that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if - and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means - shrink columns, otherwise shrink lines. - - SAFE_P zero means windows may be sized down to window-min-height - lines (window-min-window columns for WIDTH_P non-zero). SAFE_P - non-zero means windows may be sized down to their minimum safe sizes - taking into account the space needed to display modelines, fringes, - and scrollbars. - - This function returns an allocated array of new sizes that the caller - must free. A size -1 means the window is fixed and RESIZE_FIXED_P is - zero. A size zero means the window shall be deleted. Array index 0 - refers to the first window in FORWARD, 1 to the second, and so on. - - This function resizes windows proportionally to their size. It also - tries to preserve smaller windows by resizing larger windows before - resizing any window to zero. If resize_proportionally is non-nil for - a specific window, it will attempt to strictly resize that window - proportionally, even at the expense of deleting smaller windows. */ -static int * -shrink_windows (int total, int size, int nchildren, int shrinkable, - int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p) -{ - int available_resize = 0; - int *new_sizes, *min_sizes; - struct window *c; - Lisp_Object child; - int smallest = total; - int total_removed = 0; - int total_shrink = total - size; - int i; - - new_sizes = xmalloc (sizeof (*new_sizes) * nchildren); - min_sizes = xmalloc (sizeof (*min_sizes) * nchildren); - - for (i = 0, child = forward; !NILP (child); child = c->next, ++i) - { - int child_size; - - c = XWINDOW (child); - child_size = WINDOW_TOTAL_SIZE (c, width_p); - - if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0)) - new_sizes[i] = -1; - else - { - new_sizes[i] = child_size; - min_sizes[i] = window_min_size_1 (c, width_p, safe_p); - if (child_size > min_sizes[i] - && NILP (c->resize_proportionally)) - available_resize += child_size - min_sizes[i]; - } - } - /* We might need to shrink some windows to zero. Find the smallest - windows and set them to 0 until we can fulfil the new size. */ - - while (shrinkable > 1 && size + available_resize < total) - { - for (i = 0; i < nchildren; ++i) - if (new_sizes[i] > 0 && smallest > new_sizes[i]) - smallest = new_sizes[i]; - - for (i = 0; i < nchildren; ++i) - if (new_sizes[i] == smallest) - { - /* Resize this window down to zero. */ - new_sizes[i] = 0; - if (smallest > min_sizes[i]) - available_resize -= smallest - min_sizes[i]; - available_resize += smallest; - --shrinkable; - total_removed += smallest; - - /* We don't know what the smallest is now. */ - smallest = total; - - /* Out of for, just remove one window at the time and - check again if we have enough space. */ - break; - } - } - - /* Now, calculate the new sizes. Try to shrink each window - proportional to its size. */ - for (i = 0; i < nchildren; ++i) - { - if (new_sizes[i] > min_sizes[i]) - { - int to_shrink = total_shrink * new_sizes[i] / total; - - if (new_sizes[i] - to_shrink < min_sizes[i]) - to_shrink = new_sizes[i] - min_sizes[i]; - new_sizes[i] -= to_shrink; - total_removed += to_shrink; - } - } - - /* Any reminder due to rounding, we just subtract from windows - that are left and still can be shrunk. */ - while (total_shrink > total_removed) - { - int nonzero_sizes = 0; - - for (i = 0; i < nchildren; ++i) - if (new_sizes[i] > 0) - ++nonzero_sizes; - - for (i = 0; i < nchildren; ++i) - if (new_sizes[i] > min_sizes[i]) - { - --new_sizes[i]; - ++total_removed; - - /* Out of for, just shrink one window at the time and - check again if we have enough space. */ - break; - } - - /* Special case, only one window left. */ - if (nonzero_sizes == 1) - break; - } - - /* Any surplus due to rounding, we add to windows that are left. */ - while (total_shrink < total_removed) - { - for (i = 0; i < nchildren; ++i) - { - if (new_sizes[i] != 0 && total_shrink < total_removed) - { - ++new_sizes[i]; - --total_removed; - break; - } - } - } - - xfree (min_sizes); - - return new_sizes; -} - -/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set - WINDOW's width. Resize WINDOW's children, if any, so that they keep - their proportionate size relative to WINDOW. - - If FIRST_ONLY is 1, change only the first of WINDOW's children when - they are in series. If LAST_ONLY is 1, change only the last of - WINDOW's children when they are in series. - - Propagate WINDOW's top or left edge position to children. Delete - windows that become too small unless NODELETE_P is 1. When - NODELETE_P equals 2 do not honor settings for window-min-height and - window-min-width when resizing windows but use safe defaults instead. - This should give better behavior when resizing frames. */ - -static void -size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only) -{ - struct window *w = XWINDOW (window); - struct window *c; - Lisp_Object child, *forward, *sideward; - int old_size = WINDOW_TOTAL_SIZE (w, width_p); - - size = max (0, size); - - /* Delete WINDOW if it's too small. */ - if (nodelete_p != 1 && !NILP (w->parent) - && size < window_min_size_1 (w, width_p, nodelete_p == 2)) - { - delete_window (window); - return; - } - - /* Set redisplay hints. */ - w->last_modified = make_number (0); - w->last_overlay_modified = make_number (0); - windows_or_buffers_changed++; - FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1; - - if (width_p) - { - sideward = &w->vchild; - forward = &w->hchild; - w->total_cols = make_number (size); - adjust_window_margins (w); - } - else - { - sideward = &w->hchild; - forward = &w->vchild; - w->total_lines = make_number (size); - w->orig_total_lines = Qnil; - } - - if (!NILP (*sideward)) - { - /* We have a chain of parallel siblings whose size should all change. */ - for (child = *sideward; !NILP (child); child = c->next) - { - c = XWINDOW (child); - if (width_p) - c->left_col = w->left_col; - else - c->top_line = w->top_line; - size_window (child, size, width_p, nodelete_p, - first_only, last_only); - } - } - else if (!NILP (*forward) && last_only) - { - /* Change the last in a series of siblings. */ - Lisp_Object last_child; - int child_size; - - child = *forward; - do - { - c = XWINDOW (child); - last_child = child; - child = c->next; - } - while (!NILP (child)); - - child_size = WINDOW_TOTAL_SIZE (c, width_p); - size_window (last_child, size - old_size + child_size, - width_p, nodelete_p, first_only, last_only); - } - else if (!NILP (*forward) && first_only) - { - /* Change the first in a series of siblings. */ - int child_size; - - child = *forward; - c = XWINDOW (child); - - if (width_p) - c->left_col = w->left_col; - else - c->top_line = w->top_line; - - child_size = WINDOW_TOTAL_SIZE (c, width_p); - size_window (child, size - old_size + child_size, - width_p, nodelete_p, first_only, last_only); - } - else if (!NILP (*forward)) - { - int fixed_size, each IF_LINT (= 0), extra IF_LINT (= 0), n; - int resize_fixed_p, nfixed; - int last_pos, first_pos, nchildren, total; - int *new_sizes = NULL; - - /* Determine the fixed-size portion of this window, and the - number of child windows. */ - fixed_size = nchildren = nfixed = total = 0; - for (child = *forward; !NILP (child); child = c->next, ++nchildren) - { - int child_size; - - c = XWINDOW (child); - child_size = WINDOW_TOTAL_SIZE (c, width_p); - total += child_size; - - if (window_fixed_size_p (c, width_p, 0)) - { - fixed_size += child_size; - ++nfixed; - } - } - - /* If the new size is smaller than fixed_size, or if there - aren't any resizable windows, allow resizing fixed-size - windows. */ - resize_fixed_p = nfixed == nchildren || size < fixed_size; - - /* Compute how many lines/columns to add/remove to each child. The - value of extra takes care of rounding errors. */ - n = resize_fixed_p ? nchildren : nchildren - nfixed; - if (size < total && n > 1) - new_sizes = shrink_windows (total, size, nchildren, n, - resize_fixed_p, *forward, width_p, - nodelete_p == 2); - else - { - each = (size - total) / n; - extra = (size - total) - n * each; - } - - /* Compute new children heights and edge positions. */ - first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line); - last_pos = first_pos; - for (n = 0, child = *forward; !NILP (child); child = c->next, ++n) - { - int new_child_size, old_child_size; - - c = XWINDOW (child); - old_child_size = WINDOW_TOTAL_SIZE (c, width_p); - new_child_size = old_child_size; - - /* The top or left edge position of this child equals the - bottom or right edge of its predecessor. */ - if (width_p) - c->left_col = make_number (last_pos); - else - c->top_line = make_number (last_pos); - - /* If this child can be resized, do it. */ - if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0)) - { - new_child_size = - new_sizes ? new_sizes[n] : old_child_size + each + extra; - extra = 0; - } - - /* Set new size. Note that size_window also propagates - edge positions to children, so it's not a no-op if we - didn't change the child's size. */ - size_window (child, new_child_size, width_p, 1, - first_only, last_only); - - /* Remember the bottom/right edge position of this child; it - will be used to set the top/left edge of the next child. */ - last_pos += new_child_size; - } - - xfree (new_sizes); - - /* We should have covered the parent exactly with child windows. */ - xassert (size == last_pos - first_pos); - - /* Now delete any children that became too small. */ - if (nodelete_p != 1) - for (child = *forward; !NILP (child); child = c->next) - { - int child_size; - - c = XWINDOW (child); - child_size = WINDOW_TOTAL_SIZE (c, width_p); - size_window (child, child_size, width_p, nodelete_p, - first_only, last_only); - } - } -} - -/* Set WINDOW's height to HEIGHT, and recursively change the height of - WINDOW's children. NODELETE zero means windows that have become - smaller than window-min-height in the process may be deleted. - NODELETE 1 means never delete windows that become too small in the - process. (The caller should check later and do so if appropriate.) - NODELETE 2 means delete only windows that have become too small to be - displayed correctly. */ - -void -set_window_height (Lisp_Object window, int height, int nodelete) -{ - size_window (window, height, 0, nodelete, 0, 0); -} - -/* Set WINDOW's width to WIDTH, and recursively change the width of - WINDOW's children. NODELETE zero means windows that have become - smaller than window-min-width in the process may be deleted. - NODELETE 1 means never delete windows that become too small in the - process. (The caller should check later and do so if appropriate.) - NODELETE 2 means delete only windows that have become too small to be - displayed correctly. */ - -void -set_window_width (Lisp_Object window, int width, int nodelete) -{ - size_window (window, width, 1, nodelete, 0, 0); -} - -/* Change window heights in windows rooted in WINDOW by N lines. */ - -void -change_window_heights (Lisp_Object window, int n) -{ - struct window *w = XWINDOW (window); - - XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); - XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); - - if (INTEGERP (w->orig_top_line)) - XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n); - if (INTEGERP (w->orig_total_lines)) - XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n); - - /* Handle just the top child in a vertical split. */ - if (!NILP (w->vchild)) - change_window_heights (w->vchild, n); - - /* Adjust all children in a horizontal split. */ - for (window = w->hchild; !NILP (window); window = w->next) - { - w = XWINDOW (window); - change_window_heights (window, n); - } -} - int window_select_count; @@ -4337,43 +3389,6 @@ return Qnil; } -static void -make_dummy_parent (Lisp_Object window) -{ - Lisp_Object new; - register struct window *o, *p; - int i; - - o = XWINDOW (window); - p = allocate_window (); - for (i = 0; i < VECSIZE (struct window); ++i) - ((struct Lisp_Vector *) p)->contents[i] - = ((struct Lisp_Vector *)o)->contents[i]; - XSETWINDOW (new, p); - - ++sequence_number; - XSETFASTINT (p->sequence_number, sequence_number); - XSETFASTINT (p->clone_number, sequence_number); - - /* Put new into window structure in place of window */ - replace_window (window, new, 1); - - o->next = Qnil; - o->prev = Qnil; - o->vchild = Qnil; - o->hchild = Qnil; - o->parent = new; - - p->start = Qnil; - p->pointm = Qnil; - p->buffer = Qnil; - - p->splits = Qnil; - p->nest = Qnil; - p->window_parameters = Qnil; - -} - /* Make new window, have it replace WINDOW in window-tree, and make WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only horizontal child). */ @@ -4470,7 +3485,6 @@ w->pseudo_window_p = 0; w->frozen_window_start_p = 0; w->vscroll = 0; - w->resize_proportionally = Qnil; /* Reset window_list. */ Vwindow_list = Qnil; /* Return window. */ @@ -5159,147 +4173,81 @@ return Qnil; } - -DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", - doc: /* Split WINDOW, putting SIZE lines in the first of the pair. -WINDOW defaults to selected one and SIZE to half its size. -If optional third arg HORIZONTAL is non-nil, split side by side and put -SIZE columns in the first of the pair. In that case, SIZE includes that -window's scroll bar, or the divider column to its right. -Interactively, all arguments are nil. -Returns the newly created window (which is the lower or rightmost one). -The upper or leftmost window is the original one, and remains selected -if it was selected before. - -See Info node `(elisp)Splitting Windows' for more details and examples. */) - (Lisp_Object window, Lisp_Object size, Lisp_Object horizontal) -{ - register Lisp_Object new; - register struct window *o, *p; - FRAME_PTR fo; - register int size_int; - - if (NILP (window)) - window = selected_window; - else - CHECK_LIVE_WINDOW (window); - - o = XWINDOW (window); - fo = XFRAME (WINDOW_FRAME (o)); - - if (NILP (size)) - { - if (!NILP (horizontal)) - /* Calculate the size of the left-hand window, by dividing - the usable space in columns by two. - We round up, since the left-hand window may include - a dividing line, while the right-hand may not. */ - size_int = (XFASTINT (o->total_cols) + 1) >> 1; - else - size_int = XFASTINT (o->total_lines) >> 1; - } - else - { - CHECK_NUMBER (size); - size_int = XINT (size); - } - - if (MINI_WINDOW_P (o)) - error ("Attempt to split minibuffer window"); - else if (window_fixed_size_p (o, !NILP (horizontal), 0)) - error ("Attempt to split fixed-size window"); - - if (NILP (horizontal)) - { - int window_safe_height = window_min_size_2 (o, 0, 0); - - if (size_int < window_safe_height) - error ("Window height %d too small (after splitting)", size_int); - if (size_int + window_safe_height > XFASTINT (o->total_lines)) - error ("Window height %d too small (after splitting)", - (int) (XFASTINT (o->total_lines) - size_int)); - if (NILP (o->parent) - || NILP (XWINDOW (o->parent)->vchild)) - { - make_dummy_parent (window); - new = o->parent; - XWINDOW (new)->vchild = window; - } - } - else - { - int window_safe_width = window_min_size_2 (o, 1, 0); - - if (size_int < window_safe_width) - error ("Window width %d too small (after splitting)", size_int); - if (size_int + window_safe_width > XFASTINT (o->total_cols)) - error ("Window width %d too small (after splitting)", - (int) (XFASTINT (o->total_cols) - size_int)); - if (NILP (o->parent) - || NILP (XWINDOW (o->parent)->hchild)) - { - make_dummy_parent (window); - new = o->parent; - XWINDOW (new)->hchild = window; - } - } - - /* Now we know that window's parent is a vertical combination - if we are dividing vertically, or a horizontal combination - if we are making side-by-side windows */ - - windows_or_buffers_changed++; - FRAME_WINDOW_SIZES_CHANGED (fo) = 1; - new = make_window (); - p = XWINDOW (new); - - p->frame = o->frame; - p->next = o->next; - if (!NILP (p->next)) - XWINDOW (p->next)->prev = new; - p->prev = window; - o->next = new; - p->parent = o->parent; - p->buffer = Qt; - p->window_end_valid = Qnil; - memset (&p->last_cursor, 0, sizeof p->last_cursor); - - /* Duplicate special geometry settings. */ - - p->left_margin_cols = o->left_margin_cols; - p->right_margin_cols = o->right_margin_cols; - p->left_fringe_width = o->left_fringe_width; - p->right_fringe_width = o->right_fringe_width; - p->fringes_outside_margins = o->fringes_outside_margins; - p->scroll_bar_width = o->scroll_bar_width; - p->vertical_scroll_bar_type = o->vertical_scroll_bar_type; - - /* Apportion the available frame space among the two new windows */ - - if (!NILP (horizontal)) - { - p->total_lines = o->total_lines; - p->top_line = o->top_line; - XSETFASTINT (p->total_cols, XFASTINT (o->total_cols) - size_int); - XSETFASTINT (o->total_cols, size_int); - XSETFASTINT (p->left_col, XFASTINT (o->left_col) + size_int); - adjust_window_margins (p); - adjust_window_margins (o); - } - else - { - p->left_col = o->left_col; - p->total_cols = o->total_cols; - XSETFASTINT (p->total_lines, XFASTINT (o->total_lines) - size_int); - XSETFASTINT (o->total_lines, size_int); - XSETFASTINT (p->top_line, XFASTINT (o->top_line) + size_int); - } - - /* Adjust glyph matrices. */ - adjust_glyphs (fo); - - Fset_window_buffer (new, o->buffer, Qt); - return new; + +/*********************************************************************** + Resizing Mini-Windows + ***********************************************************************/ + +/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we + can. */ +void +grow_mini_window (struct window *w, int delta) +{ + struct frame *f = XFRAME (w->frame); + struct window *r; + Lisp_Object root, value; + + xassert (MINI_WINDOW_P (w)); + xassert (delta >= 0); + + root = FRAME_ROOT_WINDOW (f); + r = XWINDOW (root); + value = call2 (Qresize_root_window_vertically, root, make_number (- delta)); + if (INTEGERP (value) && resize_window_check (r, 0)) + { + BLOCK_INPUT; + resize_window_apply (r, 0); + + /* Grow the mini-window. */ + XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines)); + XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value)); + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + + adjust_glyphs (f); + UNBLOCK_INPUT; + } +} + + +/* Shrink mini-window W. */ +void +shrink_mini_window (struct window *w) +{ + struct frame *f = XFRAME (w->frame); + struct window *r; + Lisp_Object root, value; + EMACS_INT size; + + xassert (MINI_WINDOW_P (w)); + + size = XINT (w->total_lines); + if (size > 1) + { + root = FRAME_ROOT_WINDOW (f); + r = XWINDOW (root); + value = call2 (Qresize_root_window_vertically, + root, make_number (size - 1)); + if (INTEGERP (value) && resize_window_check (r, 0)) + { + BLOCK_INPUT; + resize_window_apply (r, 0); + + /* Shrink the mini-window. */ + XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines)); + XSETFASTINT (w->total_lines, 1); + + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + + adjust_glyphs (f); + UNBLOCK_INPUT; + } + /* If the above failed for whatever strange reason we must make a + one window frame here. The same routine will be needed when + shrinking the frame (and probably when making the initial + *scratch* window). For the moment leave things as they are. */ + } } DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0, @@ -5342,730 +4290,6 @@ else error ("Failed to resize minibuffer window"); } -DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", - doc: /* Make selected window SIZE lines taller. -Interactively, if no argument is given, make the selected window one -line taller. If optional argument HORIZONTAL is non-nil, make selected -window wider by SIZE columns. If SIZE is negative, shrink the window by --SIZE lines or columns. Return nil. - -This function can delete windows if they get too small. The size of -fixed size windows is not altered by this function. */) - (Lisp_Object size, Lisp_Object horizontal) -{ - CHECK_NUMBER (size); - enlarge_window (selected_window, XINT (size), !NILP (horizontal)); - - run_window_configuration_change_hook (SELECTED_FRAME ()); - - return Qnil; -} - -DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p", - doc: /* Make selected window SIZE lines smaller. -Interactively, if no argument is given, make the selected window one -line smaller. If optional argument HORIZONTAL is non-nil, make the -window narrower by SIZE columns. If SIZE is negative, enlarge selected -window by -SIZE lines or columns. Return nil. - -This function can delete windows if they get too small. The size of -fixed size windows is not altered by this function. */) - (Lisp_Object size, Lisp_Object horizontal) -{ - CHECK_NUMBER (size); - enlarge_window (selected_window, -XINT (size), !NILP (horizontal)); - - run_window_configuration_change_hook (SELECTED_FRAME ()); - - return Qnil; -} - -static int -window_height (Lisp_Object window) -{ - register struct window *p = XWINDOW (window); - return WINDOW_TOTAL_LINES (p); -} - -static int -window_width (Lisp_Object window) -{ - register struct window *p = XWINDOW (window); - return WINDOW_TOTAL_COLS (p); -} - - -#define CURBEG(w) \ - *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line)) - -#define CURSIZE(w) \ - *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines)) - - -/* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it - horizontally; zero means do it vertically. - - Siblings of the selected window are resized to fulfill the size - request. If they become too small in the process, they may be - deleted. */ - -static void -enlarge_window (Lisp_Object window, int delta, int horiz_flag) -{ - Lisp_Object parent, next, prev; - struct window *p; - Lisp_Object *sizep; - int maximum; - int (*sizefun) (Lisp_Object) - = horiz_flag ? window_width : window_height; - void (*setsizefun) (Lisp_Object, int, int) - = (horiz_flag ? set_window_width : set_window_height); - - /* Give up if this window cannot be resized. */ - if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) - error ("Window is not resizable"); - - /* Find the parent of the selected window. */ - while (1) - { - p = XWINDOW (window); - parent = p->parent; - - if (NILP (parent)) - { - if (horiz_flag) - error ("No other window to side of this one"); - break; - } - - if (horiz_flag - ? !NILP (XWINDOW (parent)->hchild) - : !NILP (XWINDOW (parent)->vchild)) - break; - - window = parent; - } - - sizep = &CURSIZE (window); - - { - register int maxdelta; - - /* Compute the maximum size increment this window can have. */ - - maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep) - /* This is a main window followed by a minibuffer. */ - : !NILP (p->next) ? ((*sizefun) (p->next) - - window_min_size (XWINDOW (p->next), - horiz_flag, 0, 0, 0)) - /* This is a minibuffer following a main window. */ - : !NILP (p->prev) ? ((*sizefun) (p->prev) - - window_min_size (XWINDOW (p->prev), - horiz_flag, 0, 0, 0)) - /* This is a frame with only one window, a minibuffer-only - or a minibufferless frame. */ - : (delta = 0)); - - if (delta > maxdelta) - /* This case traps trying to make the minibuffer - the full frame, or make the only window aside from the - minibuffer the full frame. */ - delta = maxdelta; - } - - if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), - horiz_flag, 0, 0, 0)) - { - delete_window (window); - return; - } - - if (delta == 0) - return; - - /* Find the total we can get from other siblings without deleting them. */ - maximum = 0; - for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next) - maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), - horiz_flag, 0, 0, 0); - for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev) - maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev), - horiz_flag, 0, 0, 0); - - /* If we can get it all from them without deleting them, do so. */ - if (delta <= maximum) - { - Lisp_Object first_unaffected; - Lisp_Object first_affected; - int fixed_p; - - next = p->next; - prev = p->prev; - first_affected = window; - /* Look at one sibling at a time, - moving away from this window in both directions alternately, - and take as much as we can get without deleting that sibling. */ - while (delta != 0 - && (!NILP (next) || !NILP (prev))) - { - if (! NILP (next)) - { - int this_one = ((*sizefun) (next) - - window_min_size (XWINDOW (next), horiz_flag, - 0, 0, &fixed_p)); - if (!fixed_p) - { - if (this_one > delta) - this_one = delta; - - (*setsizefun) (next, (*sizefun) (next) - this_one, 0); - (*setsizefun) (window, XINT (*sizep) + this_one, 0); - - delta -= this_one; - } - - next = XWINDOW (next)->next; - } - - if (delta == 0) - break; - - if (! NILP (prev)) - { - int this_one = ((*sizefun) (prev) - - window_min_size (XWINDOW (prev), horiz_flag, - 0, 0, &fixed_p)); - if (!fixed_p) - { - if (this_one > delta) - this_one = delta; - - first_affected = prev; - - (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0); - (*setsizefun) (window, XINT (*sizep) + this_one, 0); - - delta -= this_one; - } - - prev = XWINDOW (prev)->prev; - } - } - - xassert (delta == 0); - - /* Now recalculate the edge positions of all the windows affected, - based on the new sizes. */ - first_unaffected = next; - prev = first_affected; - for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected); - prev = next, next = XWINDOW (next)->next) - { - XSETINT (CURBEG (next), XINT (CURBEG (prev)) + (*sizefun) (prev)); - /* This does not change size of NEXT, - but it propagates the new top edge to its children */ - (*setsizefun) (next, (*sizefun) (next), 0); - } - } - else - { - register int delta1; - register int opht = (*sizefun) (parent); - - if (opht <= XINT (*sizep) + delta) - { - /* If trying to grow this window to or beyond size of the parent, - just delete all the sibling windows. */ - Lisp_Object start, tem; - - start = XWINDOW (parent)->vchild; - if (NILP (start)) - start = XWINDOW (parent)->hchild; - - /* Delete any siblings that come after WINDOW. */ - tem = XWINDOW (window)->next; - while (! NILP (tem)) - { - Lisp_Object next1 = XWINDOW (tem)->next; - delete_window (tem); - tem = next1; - } - - /* Delete any siblings that come after WINDOW. - Note that if START is not WINDOW, then WINDOW still - has siblings, so WINDOW has not yet replaced its parent. */ - tem = start; - while (! EQ (tem, window)) - { - Lisp_Object next1 = XWINDOW (tem)->next; - delete_window (tem); - tem = next1; - } - } - else - { - /* Otherwise, make delta1 just right so that if we add - delta1 lines to this window and to the parent, and then - shrink the parent back to its original size, the new - proportional size of this window will increase by delta. - - The function size_window will compute the new height h' - of the window from delta1 as: - - e = delta1/n - x = delta1 - delta1/n * n for the 1st resizable child - h' = h + e + x - - where n is the number of children that can be resized. - We can ignore x by choosing a delta1 that is a multiple of - n. We want the height of this window to come out as - - h' = h + delta - - So, delta1 must be - - h + e = h + delta - delta1/n = delta - delta1 = n * delta. - - The number of children n equals the number of resizable - children of this window + 1 because we know window itself - is resizable (otherwise we would have signaled an error). - - This reasoning is not correct when other windows become too - small and shrink_windows refuses to delete them. Below we - use resize_proportionally to work around this problem. */ - - struct window *w = XWINDOW (window); - Lisp_Object s; - int n = 1; - - for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next) - if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0)) - ++n; - for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev) - if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0)) - ++n; - - delta1 = n * delta; - - /* Add delta1 lines or columns to this window, and to the parent, - keeping things consistent while not affecting siblings. */ - XSETINT (CURSIZE (parent), opht + delta1); - (*setsizefun) (window, XINT (*sizep) + delta1, 0); - - /* Squeeze out delta1 lines or columns from our parent, - shrinking this window and siblings proportionately. This - brings parent back to correct size. Delta1 was calculated - so this makes this window the desired size, taking it all - out of the siblings. - - Temporarily set resize_proportionally to Qt to assure that, - if necessary, shrink_windows deletes smaller windows rather - than shrink this window. */ - w->resize_proportionally = Qt; - (*setsizefun) (parent, opht, 0); - w->resize_proportionally = Qnil; - } - } - - XSETFASTINT (p->last_modified, 0); - XSETFASTINT (p->last_overlay_modified, 0); - - /* Adjust glyph matrices. */ - adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); -} - - -/* Adjust the size of WINDOW by DELTA, moving only its trailing edge. - HORIZ_FLAG nonzero means adjust the width, moving the right edge. - zero means adjust the height, moving the bottom edge. - - Following siblings of the selected window are resized to fulfill - the size request. If they become too small in the process, they - are not deleted; instead, we signal an error. */ - -static void -adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag) -{ - Lisp_Object parent, child; - struct window *p; - Lisp_Object old_config = Fcurrent_window_configuration (Qnil); - int delcount = window_deletion_count; - - CHECK_WINDOW (window); - - /* Give up if this window cannot be resized. */ - if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) - error ("Window is not resizable"); - - while (1) - { - Lisp_Object first_parallel = Qnil; - - if (NILP (window)) - { - /* This happens if WINDOW on the previous iteration was - at top level of the window tree. */ - Fset_window_configuration (old_config); - error ("Specified window edge is fixed"); - } - - p = XWINDOW (window); - parent = p->parent; - - /* See if this level has windows in parallel in the specified - direction. If so, set FIRST_PARALLEL to the first one. */ - if (horiz_flag) - { - if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild)) - first_parallel = XWINDOW (parent)->vchild; - else if (NILP (parent) && !NILP (p->next)) - { - /* Handle the vertical chain of main window and minibuffer - which has no parent. */ - first_parallel = window; - while (! NILP (XWINDOW (first_parallel)->prev)) - first_parallel = XWINDOW (first_parallel)->prev; - } - } - else - { - if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild)) - first_parallel = XWINDOW (parent)->hchild; - } - - /* If this level's succession is in the desired dimension, - and this window is the last one, and there is no higher level, - its trailing edge is fixed. */ - if (NILP (XWINDOW (window)->next) && NILP (first_parallel) - && NILP (parent)) - { - Fset_window_configuration (old_config); - error ("Specified window edge is fixed"); - } - - /* Don't make this window too small. */ - if (XINT (CURSIZE (window)) + delta - < window_min_size_2 (XWINDOW (window), horiz_flag, 0)) - { - Fset_window_configuration (old_config); - error ("Cannot adjust window size as specified"); - } - - /* Clear out some redisplay caches. */ - XSETFASTINT (p->last_modified, 0); - XSETFASTINT (p->last_overlay_modified, 0); - - /* Adjust this window's edge. */ - XSETINT (CURSIZE (window), - XINT (CURSIZE (window)) + delta); - - /* If this window has following siblings in the desired dimension, - make them smaller, and exit the loop. - - (If we reach the top of the tree and can never do this, - we will fail and report an error, above.) */ - if (NILP (first_parallel)) - { - if (!NILP (p->next)) - { - /* This may happen for the minibuffer. In that case - the window_deletion_count check below does not work. */ - if (XINT (CURSIZE (p->next)) - delta <= 0) - { - Fset_window_configuration (old_config); - error ("Cannot adjust window size as specified"); - } - - XSETINT (CURBEG (p->next), - XINT (CURBEG (p->next)) + delta); - size_window (p->next, XINT (CURSIZE (p->next)) - delta, - horiz_flag, 0, 1, 0); - break; - } - } - else - /* Here we have a chain of parallel siblings, in the other dimension. - Change the size of the other siblings. */ - for (child = first_parallel; - ! NILP (child); - child = XWINDOW (child)->next) - if (! EQ (child, window)) - size_window (child, XINT (CURSIZE (child)) + delta, - horiz_flag, 0, 0, 1); - - window = parent; - } - - /* If we made a window so small it got deleted, - we failed. Report failure. */ - if (delcount != window_deletion_count) - { - Fset_window_configuration (old_config); - error ("Cannot adjust window size as specified"); - } - - /* Adjust glyph matrices. */ - adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); -} - -#undef CURBEG -#undef CURSIZE - -DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge, - Sadjust_window_trailing_edge, 3, 3, 0, - doc: /* Adjust the bottom or right edge of WINDOW by DELTA. -If HORIZONTAL is non-nil, that means adjust the width, moving the right edge. -Otherwise, adjust the height, moving the bottom edge. - -Following siblings of the selected window are resized to fulfill -the size request. If they become too small in the process, they -are not deleted; instead, we signal an error. */) - (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal) -{ - CHECK_NUMBER (delta); - if (NILP (window)) - window = selected_window; - adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal)); - - run_window_configuration_change_hook - (XFRAME (WINDOW_FRAME (XWINDOW (window)))); - - return Qnil; -} - - - -/*********************************************************************** - Resizing Mini-Windows - ***********************************************************************/ - -static void shrink_window_lowest_first (struct window *, int); - -enum save_restore_action -{ - CHECK_ORIG_SIZES, - SAVE_ORIG_SIZES, - RESTORE_ORIG_SIZES -}; - -static int save_restore_orig_size (struct window *, - enum save_restore_action); - -/* Shrink windows rooted in window W to HEIGHT. Take the space needed - from lowest windows first. */ - -static void -shrink_window_lowest_first (struct window *w, int height) -{ - struct window *c; - Lisp_Object child; - int old_height; - - xassert (!MINI_WINDOW_P (w)); - - /* Set redisplay hints. */ - XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->last_overlay_modified, 0); - windows_or_buffers_changed++; - FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1; - - old_height = XFASTINT (w->total_lines); - XSETFASTINT (w->total_lines, height); - - if (!NILP (w->hchild)) - { - for (child = w->hchild; !NILP (child); child = c->next) - { - c = XWINDOW (child); - c->top_line = w->top_line; - shrink_window_lowest_first (c, height); - } - } - else if (!NILP (w->vchild)) - { - Lisp_Object last_child; - int delta = old_height - height; - int last_top; - - last_child = Qnil; - - /* Find the last child. We are taking space from lowest windows - first, so we iterate over children from the last child - backwards. */ - for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next) - last_child = child; - - /* Size children down to their safe heights. */ - for (child = last_child; delta && !NILP (child); child = c->prev) - { - int this_one; - - c = XWINDOW (child); - this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1); - - if (this_one > delta) - this_one = delta; - - shrink_window_lowest_first (c, XFASTINT (c->total_lines) - this_one); - delta -= this_one; - } - - /* Compute new positions. */ - last_top = XINT (w->top_line); - for (child = w->vchild; !NILP (child); child = c->next) - { - c = XWINDOW (child); - c->top_line = make_number (last_top); - shrink_window_lowest_first (c, XFASTINT (c->total_lines)); - last_top += XFASTINT (c->total_lines); - } - } -} - - -/* Save, restore, or check positions and sizes in the window tree - rooted at W. ACTION says what to do. - - If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and - orig_total_lines members are valid for all windows in the window - tree. Value is non-zero if they are valid. - - If ACTION is SAVE_ORIG_SIZES, save members top and height in - orig_top_line and orig_total_lines for all windows in the tree. - - If ACTION is RESTORE_ORIG_SIZES, restore top and height from values - stored in orig_top_line and orig_total_lines for all windows. */ - -static int -save_restore_orig_size (struct window *w, enum save_restore_action action) -{ - int success_p = 1; - - while (w) - { - if (!NILP (w->hchild)) - { - if (!save_restore_orig_size (XWINDOW (w->hchild), action)) - success_p = 0; - } - else if (!NILP (w->vchild)) - { - if (!save_restore_orig_size (XWINDOW (w->vchild), action)) - success_p = 0; - } - - switch (action) - { - case CHECK_ORIG_SIZES: - if (!INTEGERP (w->orig_top_line) || !INTEGERP (w->orig_total_lines)) - return 0; - break; - - case SAVE_ORIG_SIZES: - w->orig_top_line = w->top_line; - w->orig_total_lines = w->total_lines; - XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->last_overlay_modified, 0); - break; - - case RESTORE_ORIG_SIZES: - xassert (INTEGERP (w->orig_top_line) && INTEGERP (w->orig_total_lines)); - w->top_line = w->orig_top_line; - w->total_lines = w->orig_total_lines; - w->orig_total_lines = w->orig_top_line = Qnil; - XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->last_overlay_modified, 0); - break; - - default: - abort (); - } - - w = NILP (w->next) ? NULL : XWINDOW (w->next); - } - - return success_p; -} - - -/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can - without deleting other windows. */ - -void -grow_mini_window (struct window *w, int delta) -{ - struct frame *f = XFRAME (w->frame); - struct window *root; - - xassert (MINI_WINDOW_P (w)); - /* Commenting out the following assertion goes against the stated interface - of the function, but it currently does not seem to do anything useful. - See discussion of this issue in the thread for bug#4534. - xassert (delta >= 0); */ - - /* Compute how much we can enlarge the mini-window without deleting - other windows. */ - root = XWINDOW (FRAME_ROOT_WINDOW (f)); - if (delta > 0) - { - int min_height = window_min_size (root, 0, 0, 0, 0); - if (XFASTINT (root->total_lines) - delta < min_height) - /* Note that the root window may already be smaller than - min_height. */ - delta = max (0, XFASTINT (root->total_lines) - min_height); - } - - if (delta) - { - /* Save original window sizes and positions, if not already done. */ - if (!save_restore_orig_size (root, CHECK_ORIG_SIZES)) - save_restore_orig_size (root, SAVE_ORIG_SIZES); - - /* Shrink other windows. */ - shrink_window_lowest_first (root, XFASTINT (root->total_lines) - delta); - - /* Grow the mini-window. */ - w->top_line = make_number (XFASTINT (root->top_line) + XFASTINT (root->total_lines)); - w->total_lines = make_number (XFASTINT (w->total_lines) + delta); - XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->last_overlay_modified, 0); - - adjust_glyphs (f); - } -} - - -/* Shrink mini-window W. If there is recorded info about window sizes - before a call to grow_mini_window, restore recorded window sizes. - Otherwise, if the mini-window is higher than 1 line, resize it to 1 - line. */ - -void -shrink_mini_window (struct window *w) -{ - struct frame *f = XFRAME (w->frame); - struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); - - if (save_restore_orig_size (root, CHECK_ORIG_SIZES)) - { - save_restore_orig_size (root, RESTORE_ORIG_SIZES); - adjust_glyphs (f); - FRAME_WINDOW_SIZES_CHANGED (f) = 1; - windows_or_buffers_changed = 1; - } - else if (XFASTINT (w->total_lines) > 1) - { - /* Distribute the additional lines of the mini-window - among the other windows. */ - Lisp_Object window; - XSETWINDOW (window, w); - enlarge_window (window, 1 - XFASTINT (w->total_lines), 0); - } -} - - /* Mark window cursors off for all windows in the window tree rooted at W by setting their phys_cursor_on_p flag to zero. Called from @@ -7252,11 +5476,9 @@ Lisp_Object parent, prev; Lisp_Object start_at_line_beg; Lisp_Object display_table; - Lisp_Object orig_top_line, orig_total_lines; Lisp_Object left_margin_cols, right_margin_cols; Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; - Lisp_Object scroll_bar_width, vertical_scroll_bar_type; - Lisp_Object dedicated, resize_proportionally; + Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated; Lisp_Object splits, nest, window_parameters; }; @@ -7476,8 +5698,6 @@ w->hscroll = p->hscroll; w->min_hscroll = p->min_hscroll; w->display_table = p->display_table; - w->orig_top_line = p->orig_top_line; - w->orig_total_lines = p->orig_total_lines; w->left_margin_cols = p->left_margin_cols; w->right_margin_cols = p->right_margin_cols; w->left_fringe_width = p->left_fringe_width; @@ -7489,7 +5709,6 @@ w->splits = p->splits; w->nest = p->nest; w->window_parameters = p->window_parameters; - w->resize_proportionally = p->resize_proportionally; XSETFASTINT (w->last_modified, 0); XSETFASTINT (w->last_overlay_modified, 0); @@ -7618,6 +5837,7 @@ return (FRAME_LIVE_P (f) ? Qt : Qnil); } + /* Delete all subwindows reachable via the next, vchild, and hchild slots of WINDOW. */ void @@ -7670,7 +5890,6 @@ /* Fill vector FLAT with leaf windows under W, starting at index I. Value is last index + 1. */ - static int get_leaf_windows (struct window *w, struct window **flat, int i) { @@ -7693,7 +5912,6 @@ /* Return a pointer to the glyph W's physical cursor is on. Value is null if W's current matrix is invalid, so that no meaningfull glyph can be returned. */ - struct glyph * get_phys_cursor_glyph (struct window *w) { @@ -7738,8 +5956,6 @@ p->hscroll = w->hscroll; p->min_hscroll = w->min_hscroll; p->display_table = w->display_table; - p->orig_top_line = w->orig_top_line; - p->orig_total_lines = w->orig_total_lines; p->left_margin_cols = w->left_margin_cols; p->right_margin_cols = w->right_margin_cols; p->left_fringe_width = w->left_fringe_width; @@ -7750,7 +5966,6 @@ p->dedicated = w->dedicated; p->splits = w->splits; p->nest = w->nest; - p->resize_proportionally = w->resize_proportionally; p->window_parameters = w->window_parameters; if (!NILP (w->buffer)) { @@ -8444,10 +6659,6 @@ Fput (Qscroll_up, Qscroll_command, Qt); Fput (Qscroll_down, Qscroll_command, Qt); - Qwindow_size_fixed = intern_c_string ("window-size-fixed"); - staticpro (&Qwindow_size_fixed); - Fset (Qwindow_size_fixed, Qnil); - staticpro (&Qwindow_configuration_change_hook); Qwindow_configuration_change_hook = intern_c_string ("window-configuration-change-hook"); @@ -8540,24 +6751,6 @@ doc: /* *Number of lines of continuity when scrolling by screenfuls. */); next_screen_context_lines = 2; - DEFVAR_INT ("window-min-height", window_min_height, - doc: /* Allow deleting windows less than this tall. -The value is measured in line units. If a window wants a modeline it -is counted as one line. - -Emacs honors settings of this variable when enlarging or shrinking -windows vertically. A value less than 1 is invalid. */); - window_min_height = 4; - - DEFVAR_INT ("window-min-width", window_min_width, - doc: /* Allow deleting windows less than this wide. -The value is measured in characters and includes any fringes or -the scrollbar. - -Emacs honors settings of this variable when enlarging or shrinking -windows horizontally. A value less than 2 is invalid. */); - window_min_width = 10; - DEFVAR_LISP ("scroll-preserve-screen-position", Vscroll_preserve_screen_position, doc: /* *Controls if scroll commands move point to keep its screen position unchanged. @@ -8684,10 +6877,8 @@ defsubr (&Sprevious_window); defsubr (&Sother_window); defsubr (&Sget_buffer_window); - defsubr (&Sdelete_other_windows); defsubr (&Sdelete_windows_on); defsubr (&Sreplace_buffer_in_windows); - defsubr (&Sdelete_window); defsubr (&Sdelete_other_windows_internal); defsubr (&Sdelete_window_internal); defsubr (&Sresize_mini_window_internal); @@ -8697,11 +6888,7 @@ defsubr (&Sselect_window); defsubr (&Sforce_window_update); defsubr (&Stemp_output_buffer_show); - defsubr (&Ssplit_window); defsubr (&Ssplit_window_internal); - defsubr (&Senlarge_window); - defsubr (&Sshrink_window); - defsubr (&Sadjust_window_trailing_edge); defsubr (&Sscroll_up); defsubr (&Sscroll_down); defsubr (&Sscroll_left); @@ -8740,11 +6927,7 @@ void keys_of_window (void) { - initial_define_key (control_x_map, '1', "delete-other-windows"); - initial_define_key (control_x_map, '2', "split-window"); - initial_define_key (control_x_map, '0', "delete-window"); initial_define_key (control_x_map, 'o', "other-window"); - initial_define_key (control_x_map, '^', "enlarge-window"); initial_define_key (control_x_map, '<', "scroll-left"); initial_define_key (control_x_map, '>', "scroll-right"); === modified file 'src/xdisp.c' --- src/xdisp.c 2011-06-05 00:14:08 +0000 +++ src/xdisp.c 2011-06-10 06:55:18 +0000 @@ -27115,31 +27115,27 @@ void init_xdisp (void) { - Lisp_Object root_window; - struct window *mini_w; - current_header_line_height = current_mode_line_height = -1; CHARPOS (this_line_start_pos) = 0; - mini_w = XWINDOW (minibuf_window); - root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w))); - echo_area_window = minibuf_window; - if (!noninteractive) { - struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); + struct window *m = XWINDOW (minibuf_window); + Lisp_Object frame = m->frame; + struct frame *f = XFRAME (frame); + Lisp_Object root = FRAME_ROOT_WINDOW (f); + struct window *r = XWINDOW (root); int i; - XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f)); - set_window_height (root_window, - FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f), - 0); - mini_w->top_line = make_number (FRAME_LINES (f) - 1); - set_window_height (minibuf_window, 1, 0); + echo_area_window = minibuf_window; - XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f)); - mini_w->total_cols = make_number (FRAME_COLS (f)); + XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f)); + XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)); + XSETFASTINT (r->total_cols, FRAME_COLS (f)); + XSETFASTINT (m->top_line, FRAME_LINES (f) - 1); + XSETFASTINT (m->total_lines, 1); + XSETFASTINT (m->total_cols, FRAME_COLS (f)); scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; scratch_glyph_row.glyphs[TEXT_AREA + 1] === modified file 'src/xfns.c' --- src/xfns.c 2011-06-06 19:43:39 +0000 +++ src/xfns.c 2011-06-10 06:55:18 +0000 @@ -1227,7 +1227,7 @@ } #else /* not USE_X_TOOLKIT && not USE_GTK */ FRAME_MENU_BAR_LINES (f) = nlines; - change_window_heights (f->root_window, nlines - olines); + resize_frame_windows (f, FRAME_LINES (f), 0); /* If the menu bar height gets changed, the internal border below the top margin has to be cleared. Also, if the menu bar gets @@ -1266,6 +1266,7 @@ } #endif /* not USE_X_TOOLKIT && not USE_GTK */ adjust_glyphs (f); + run_window_configuration_change_hook (f); } @@ -1326,7 +1327,7 @@ } FRAME_TOOL_BAR_LINES (f) = nlines; - change_window_heights (root_window, delta); + resize_frame_windows (f, FRAME_LINES (f), 0); adjust_glyphs (f); /* We also have to make sure that the internal border at the top of @@ -1362,6 +1363,9 @@ if (WINDOWP (f->tool_bar_window)) clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); } + + run_window_configuration_change_hook (f); + } ------------------------------------------------------------ revno: 104550 committer: Katsumi Yamaoka branch nick: trunk timestamp: Fri 2011-06-10 00:10:24 +0000 message: Improve Gnus' dribble data handling. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2011-06-01 22:35:26 +0000 +++ lisp/gnus/ChangeLog 2011-06-10 00:10:24 +0000 @@ -1,3 +1,24 @@ +2011-06-10 Katsumi Yamaoka + + * gnus-group.el (gnus-group-update-group): Add new argument + `info-unchanged' that stops updating dribble buffer. + + * gnus-start.el (gnus-dribble-enter): Add new argument `regexp' that + deletes lines matching to it in dribble buffer. + + * gnus-agent.el (gnus-agent-fetch-group-1): + * gnus-group.el (gnus-group-update-group-line, gnus-group-make-group): + * gnus-srvr.el (gnus-server-update-server, gnus-server-set-info): + * gnus-start.el (gnus-group-change-level): + * gnus-sum.el (gnus-summary-move-article): Delete old dribble entry. + + * gnus-sum.el (gnus-summary-update-info): Don't update dribble buffer + if newsgroup info is not changed. + + * gnus-group.el (gnus-group-get-new-news-this-group): + * gnus-sum.el (gnus-summary-read-group-1, gnus-summary-exit-no-update): + Don't update dribble buffer. + 2011-06-01 Teodor Zlatanov * gnus-registry.el (gnus-registry-remove-ignored): New function to === modified file 'lisp/gnus/gnus-agent.el' --- lisp/gnus/gnus-agent.el 2011-05-02 22:41:38 +0000 +++ lisp/gnus/gnus-agent.el 2011-06-10 00:10:24 +0000 @@ -2614,7 +2614,9 @@ (gnus-dribble-enter (concat "(gnus-group-set-info '" (gnus-prin1-to-string info) - ")")))))))))))) + ")") + (concat "^(gnus-group-set-info '(\"" + (regexp-quote group) "\"")))))))))))) ;;; ;;; Agent Category Mode === modified file 'lisp/gnus/gnus-group.el' --- lisp/gnus/gnus-group.el 2011-05-30 22:11:52 +0000 +++ lisp/gnus/gnus-group.el 2011-06-10 00:10:24 +0000 @@ -1437,7 +1437,8 @@ (gnus-dribble-enter (concat "(gnus-group-set-info '" (gnus-prin1-to-string (nth 2 entry)) - ")"))) + ")") + (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\""))) (setq gnus-group-indentation (gnus-group-group-indentation)) (gnus-delete-line) (gnus-group-insert-group-line-info group) @@ -1685,10 +1686,11 @@ (gnus-active group)) (gnus-group-update-group group)) -(defun gnus-group-update-group (group &optional visible-only) +(defun gnus-group-update-group (group &optional visible-only + info-unchanged) "Update all lines where GROUP appear. If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't -already." +already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated." (with-current-buffer gnus-group-buffer (save-excursion ;; The buffer may be narrowed. @@ -1697,14 +1699,17 @@ (let ((ident (gnus-intern-safe group gnus-active-hashtb)) (loc (point-min)) found buffer-read-only) - ;; Enter the current status into the dribble buffer. - (let ((entry (gnus-group-entry group))) - (when (and entry - (not (gnus-ephemeral-group-p group))) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (nth 2 entry)) - ")")))) + (unless info-unchanged + ;; Enter the current status into the dribble buffer. + (let ((entry (gnus-group-entry group))) + (when (and entry + (not (gnus-ephemeral-group-p group))) + (gnus-dribble-enter + (concat "(gnus-group-set-info '" + (gnus-prin1-to-string (nth 2 entry)) + ")") + (concat "^(gnus-group-set-info '(\"" + (regexp-quote group) "\""))))) ;; Find all group instances. If topics are in use, each group ;; may be listed in more than once. (while (setq loc (text-property-any @@ -2715,7 +2720,8 @@ (unless (gnus-ephemeral-group-p name) (gnus-dribble-enter (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (cdr info)) ")"))) + (gnus-prin1-to-string (cdr info)) ")") + (concat "^(gnus-group-set-info '(\"" (regexp-quote name) "\""))) ;; Insert the line. (gnus-group-insert-group-line-info nname) (forward-line -1) @@ -4032,7 +4038,7 @@ (when gnus-agent (gnus-agent-save-group-info method (gnus-group-real-name group) active)) - (gnus-group-update-group group)) + (gnus-group-update-group group nil t)) (if (eq (gnus-server-status (gnus-find-method-for-group group)) 'denied) (gnus-error 3 "Server denied access") === modified file 'lisp/gnus/gnus-srvr.el' --- lisp/gnus/gnus-srvr.el 2011-01-25 04:08:28 +0000 +++ lisp/gnus/gnus-srvr.el 2011-06-10 00:10:24 +0000 @@ -362,7 +362,8 @@ (when entry (gnus-dribble-enter (concat "(gnus-server-set-info \"" server "\" '" - (gnus-prin1-to-string (cdr entry)) ")\n"))) + (gnus-prin1-to-string (cdr entry)) ")\n") + (concat "^(gnus-server-set-info \"" (regexp-quote server) "\""))) (when (or entry oentry) ;; Buffer may be narrowed. (save-restriction @@ -381,7 +382,8 @@ (when (and server info) (gnus-dribble-enter (concat "(gnus-server-set-info \"" server "\" '" - (gnus-prin1-to-string info) ")")) + (gnus-prin1-to-string info) ")") + (concat "^(gnus-server-set-info \"" (regexp-quote server) "\"")) (let* ((server (nth 1 info)) (entry (assoc server gnus-server-alist)) (cached (assoc server gnus-server-method-cache))) === modified file 'lisp/gnus/gnus-start.el' --- lisp/gnus/gnus-start.el 2011-05-05 06:56:54 +0000 +++ lisp/gnus/gnus-start.el 2011-06-10 00:10:24 +0000 @@ -832,13 +832,22 @@ gnus-current-startup-file) "-dribble")) -(defun gnus-dribble-enter (string) - "Enter STRING into the dribble buffer." +(defun gnus-dribble-enter (string &optional regexp) + "Enter STRING into the dribble buffer. +If REGEXP is given, lines that match it will be deleted." (when (and (not gnus-dribble-ignore) gnus-dribble-buffer (buffer-name gnus-dribble-buffer)) (let ((obuf (current-buffer))) (set-buffer gnus-dribble-buffer) + (when regexp + (goto-char (point-min)) + (let (end) + (while (re-search-forward regexp nil t) + (unless (bolp) (forward-line 1)) + (setq end (point)) + (goto-char (match-beginning 0)) + (delete-region (point-at-bol) end)))) (goto-char (point-max)) (insert string "\n") ;; This has been commented by Josh Huber @@ -1354,8 +1363,8 @@ (when (cdr entry) (setcdr (gnus-group-entry (caadr entry)) entry)) (gnus-dribble-enter - (format - "(gnus-group-set-info '%S)" info))))) + (format "(gnus-group-set-info '%S)" info) + (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\""))))) (when gnus-group-change-level-function (funcall gnus-group-change-level-function group level oldlevel previous))))) === modified file 'lisp/gnus/gnus-sum.el' --- lisp/gnus/gnus-sum.el 2011-05-31 10:37:35 +0000 +++ lisp/gnus/gnus-sum.el 2011-06-10 00:10:24 +0000 @@ -4098,7 +4098,7 @@ (setq gnus-newsgroup-prepared t) (gnus-run-hooks 'gnus-summary-prepared-hook) (unless (gnus-ephemeral-group-p group) - (gnus-group-update-group group)) + (gnus-group-update-group group nil t)) t))))) (defun gnus-summary-auto-select-subject () @@ -7140,7 +7140,12 @@ t))) (unless (listp (cdr gnus-newsgroup-killed)) (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) - (let ((headers gnus-newsgroup-headers)) + (let ((headers gnus-newsgroup-headers) + (ephemeral-p (gnus-ephemeral-group-p group)) + info) + (unless ephemeral-p + (setq info (copy-sequence (gnus-get-info group)) + info (delq (gnus-info-params info) info))) ;; Set the new ranges of read articles. (with-current-buffer gnus-group-buffer (gnus-undo-force-boundary)) @@ -7160,8 +7165,12 @@ (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads)) ;; Do not switch windows but change the buffer to work. (set-buffer gnus-group-buffer) - (unless (gnus-ephemeral-group-p group) - (gnus-group-update-group group))))))) + (unless ephemeral-p + (gnus-group-update-group + group nil + (equal info + (setq info (copy-sequence (gnus-get-info group)) + info (delq (gnus-info-params info) info)))))))))) (defun gnus-summary-save-newsrc (&optional force) "Save the current number of read/marked articles in the dribble buffer. @@ -7314,7 +7323,7 @@ ;; Clear the current group name. (setq gnus-newsgroup-name nil) (unless (gnus-ephemeral-group-p group) - (gnus-group-update-group group)) + (gnus-group-update-group group nil t)) (when (equal (gnus-group-group-name) group) (gnus-group-next-unread-group 1)) (when quit-config @@ -9994,7 +10003,9 @@ (gnus-dribble-enter (concat "(gnus-group-set-info '" (gnus-prin1-to-string (gnus-get-info to-group)) - ")")))) + ")") + (concat "^(gnus-group-set-info '(\"" + (regexp-quote to-group) "\"")))) ;; Update the Xref header in this article to point to ;; the new crossposted article we have just created. ------------------------------------------------------------ revno: 104549 committer: Glenn Morris branch nick: trunk timestamp: Thu 2011-06-09 16:36:04 -0400 message: * lisp/calendar/appt.el (appt-mode-line): Eliminate one local variable. diff: === modified file 'lisp/calendar/appt.el' --- lisp/calendar/appt.el 2011-06-09 20:25:34 +0000 +++ lisp/calendar/appt.el 2011-06-09 20:36:04 +0000 @@ -257,9 +257,9 @@ If ABBREV is non-nil, abbreviates some text." ;; All this silliness is just to make the formatting slightly nicer. (let* ((multiple (> (length min-to-app) 1)) - (sametime (or (not multiple) - (not (delete (car min-to-app) min-to-app)))) - (imin (if sametime (car min-to-app)))) + (imin (if (or (not multiple) + (not (delete (car min-to-app) min-to-app))) + (car min-to-app)))) (format "%s%s %s" (if abbrev "App't" "Appointment") (if multiple "s" "") ------------------------------------------------------------ revno: 104548 committer: Glenn Morris branch nick: trunk timestamp: Thu 2011-06-09 16:25:34 -0400 message: Eliminate some code duplication in appt.el. * lisp/calendar/appt.el (appt-mode-line): New function. (appt-check, appt-disp-window): Use it. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-09 20:22:06 +0000 +++ lisp/ChangeLog 2011-06-09 20:25:34 +0000 @@ -1,5 +1,8 @@ 2011-06-09 Glenn Morris + * calendar/appt.el (appt-mode-line): New function. + (appt-check, appt-disp-window): Use it. + * files.el (hack-one-local-variable-eval-safep): Allow minor-modes with explicit +/-1 arguments. === modified file 'lisp/calendar/appt.el' --- lisp/calendar/appt.el 2011-06-09 05:08:11 +0000 +++ lisp/calendar/appt.el 2011-06-09 20:25:34 +0000 @@ -251,6 +251,23 @@ (mapconcat 'identity string "\n") string))))) +(defun appt-mode-line (min-to-app &optional abbrev) + "Return an appointment string suitable for use in the mode-line. +MIN-TO-APP is a list of minutes, as strings. +If ABBREV is non-nil, abbreviates some text." + ;; All this silliness is just to make the formatting slightly nicer. + (let* ((multiple (> (length min-to-app) 1)) + (sametime (or (not multiple) + (not (delete (car min-to-app) min-to-app)))) + (imin (if sametime (car min-to-app)))) + (format "%s%s %s" + (if abbrev "App't" "Appointment") + (if multiple "s" "") + (if (equal imin "0") "now" + (format "in %s %s" + (or imin (mapconcat 'identity min-to-app ",")) + (if abbrev "min." + (format "minute%s" (if (equal imin "1") "" "s")))))))) (defun appt-check (&optional force) "Check for an appointment and update any reminder display. @@ -373,9 +390,8 @@ (when appt-display-mode-line (setq appt-mode-string (concat " " (propertize - (format "App't %s" - (if (zerop min-to-app) "NOW" - (format "in %s min." min-to-app))) + (appt-mode-line (mapcar 'number-to-string + (list min-to-app)) t) 'face 'mode-line-emphasis)))) ;; When an appointment is reached, delete it from the ;; list. Reset the count to 0 in case we display another @@ -428,31 +444,20 @@ ;; Let's allow it to be a list or not independent of the other elements. (or (listp new-time) (setq new-time (list new-time))) - ;; All this silliness is just to make the formatting slightly nicer. - (let* ((multiple (> (length min-to-app) 1)) - (sametime (or (not multiple) - (not (delete (car min-to-app) min-to-app)))) - (imin (if sametime (car min-to-app)))) - ;; FIXME Link to diary entry? - (calendar-set-mode-line - (format " Appointment%s %s. %s " - (if multiple "s" "") - (if (equal imin "0") - "now" - (format "in %s minute%s" - (or imin (mapconcat 'identity min-to-app ",")) - (if (equal imin "1") - "" "s"))) - (mapconcat 'identity new-time ", "))) - (setq buffer-read-only nil - buffer-undo-list t) - (erase-buffer) - ;; If we have appointments at different times, prepend the times. - (if sametime - (insert (mapconcat 'identity appt-msg "\n")) - (dotimes (i (length appt-msg)) - (insert (format "%s%sm: %s" (if (> i 0) "\n" "") - (nth i min-to-app) (nth i appt-msg)))))) + ;; FIXME Link to diary entry? + (calendar-set-mode-line + (format " %s. %s" (appt-mode-line min-to-app) + (mapconcat 'identity new-time ", "))) + (setq buffer-read-only nil + buffer-undo-list t) + (erase-buffer) + ;; If we have appointments at different times, prepend the times. + (if (or (= 1 (length min-to-app)) + (not (delete (car min-to-app) min-to-app))) + (insert (mapconcat 'identity appt-msg "\n")) + (dotimes (i (length appt-msg)) + (insert (format "%s%sm: %s" (if (> i 0) "\n" "") + (nth i min-to-app) (nth i appt-msg))))) (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t)) (set-buffer-modified-p nil) (setq buffer-read-only t) ------------------------------------------------------------ revno: 104547 committer: Glenn Morris branch nick: trunk timestamp: Thu 2011-06-09 16:22:06 -0400 message: Allow/recommend explicit args for minor-modes in file local eval:s. * lisp/files.el (hack-one-local-variable-eval-safep): Allow minor-modes with explicit +/-1 arguments. * doc/emacs/custom.texi (Specifying File Variables): Recommend explicit arguments for minor modes. * etc/NEWS: Likewise. * lisp/doc-view.el, lisp/net/soap-client.el: Update file locals. diff: === modified file 'doc/emacs/ChangeLog' --- doc/emacs/ChangeLog 2011-06-06 19:43:39 +0000 +++ doc/emacs/ChangeLog 2011-06-09 20:22:06 +0000 @@ -1,3 +1,8 @@ +2011-06-09 Glenn Morris + + * custom.texi (Specifying File Variables): + Recommend explicit arguments for minor modes. + 2011-06-02 Paul Eggert Document wide integers better. === modified file 'doc/emacs/custom.texi' --- doc/emacs/custom.texi 2011-05-28 18:22:08 +0000 +++ doc/emacs/custom.texi 2011-06-09 20:22:06 +0000 @@ -1215,7 +1215,7 @@ well as the major modes; in fact, you can use it more than once, first to set the major mode and then to enable minor modes which are specific to particular buffers. Using @code{mode} for minor modes -is deprecated, though---instead, use @code{eval: (minor-mode)}. +is deprecated, though---instead, use @code{eval: (minor-mode 1)}. Often, however, it is a mistake to enable minor modes in file local variables. Most minor modes, like Auto Fill mode, represent individual user === modified file 'etc/NEWS' --- etc/NEWS 2011-06-07 18:32:12 +0000 +++ etc/NEWS 2011-06-09 20:22:06 +0000 @@ -294,7 +294,7 @@ +++ ** The use of a "mode: minor" specification in a file local variables section -to enable a minor-mode is deprecated. Instead, use "eval: (minor-mode)". +to enable a minor-mode is deprecated. Instead, use "eval: (minor-mode 1)". ** The standalone programs lib-src/digest-doc and sorted-doc have been replaced with Lisp commands `doc-file-to-man' and `doc-file-to-info'. === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-09 16:58:18 +0000 +++ lisp/ChangeLog 2011-06-09 20:22:06 +0000 @@ -1,3 +1,8 @@ +2011-06-09 Glenn Morris + + * files.el (hack-one-local-variable-eval-safep): + Allow minor-modes with explicit +/-1 arguments. + 2011-06-09 Teodor Zlatanov * term/xterm.el (xterm): Add defgroup. === modified file 'lisp/doc-view.el' --- lisp/doc-view.el 2011-06-05 00:18:46 +0000 +++ lisp/doc-view.el 2011-06-09 20:22:06 +0000 @@ -1550,7 +1550,7 @@ (provide 'doc-view) ;; Local Variables: -;; eval: (outline-minor-mode) +;; eval: (outline-minor-mode 1) ;; End: ;;; doc-view.el ends here === modified file 'lisp/files.el' --- lisp/files.el 2011-06-09 05:33:26 +0000 +++ lisp/files.el 2011-06-09 20:22:06 +0000 @@ -2635,7 +2635,7 @@ ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*- (let (end done mode modes) ;; Once we drop the deprecated feature where mode: is also allowed to - ;; specify minor-modes (ie, there can be more than one "mode:), we can + ;; specify minor-modes (ie, there can be more than one "mode:"), we can ;; remove this section and just let (hack-local-variables t) handle it. ;; Find a -*- mode tag. (save-excursion @@ -3367,7 +3367,7 @@ (and (symbolp (car exp)) ;; Allow (minor)-modes calls with no arguments. ;; This obsoletes the use of "mode:" for such things. (Bug#8613) - (or (and (null (cdr exp)) + (or (and (member (cdr exp) '(nil (1) (-1))) (string-match "-mode\\'" (symbol-name (car exp)))) (let ((prop (get (car exp) 'safe-local-eval-function))) (cond ((eq prop t) === modified file 'lisp/net/soap-client.el' --- lisp/net/soap-client.el 2011-05-10 02:31:42 +0000 +++ lisp/net/soap-client.el 2011-06-09 20:22:06 +0000 @@ -1745,7 +1745,7 @@ ;;; Local Variables: -;;; eval: (outline-minor-mode) +;;; eval: (outline-minor-mode 1) ;;; outline-regexp: ";;;;+" ;;; End: ------------------------------------------------------------ revno: 104546 committer: Ted Zlatanov branch nick: quickfixes timestamp: Thu 2011-06-09 11:58:18 -0500 message: Add `xterm-extra-capabilities' defcustom for terminals where the xterm capabilities query is not needed or wanted. * term/xterm.el (xterm): Add defgroup. (xterm-extra-capabilities): Add defcustom to supply known xterm capabilities, skip querying them, or query them (default). (terminal-init-xterm): Use it. (terminal-init-xterm-modify-other-keys): New function to set up modifyOtherKeys support to simplify `terminal-init-xterm'. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-09 08:41:36 +0000 +++ lisp/ChangeLog 2011-06-09 16:58:18 +0000 @@ -1,3 +1,12 @@ +2011-06-09 Teodor Zlatanov + + * term/xterm.el (xterm): Add defgroup. + (xterm-extra-capabilities): Add defcustom to supply known xterm + capabilities, skip querying them, or query them (default). + (terminal-init-xterm): Use it. + (terminal-init-xterm-modify-other-keys): New function to set up + modifyOtherKeys support to simplify `terminal-init-xterm'. + 2011-06-09 Martin Rudalics * window.el (resize-window-reset, resize-window-reset-1) === modified file 'lisp/term/xterm.el' --- lisp/term/xterm.el 2011-01-25 04:08:28 +0000 +++ lisp/term/xterm.el 2011-06-09 16:58:18 +0000 @@ -24,6 +24,23 @@ ;;; Code: +(defgroup xterm nil + "XTerm support." + :version "24.1" + :group 'emacs) + +(defcustom xterm-extra-capabilities 'check + "Set to a list if the XTerm supports modifyOtherKeys or +reporting the background color. Set to 'check to check for those +features. Set to nil to skip the checks." + :group 'xterm + :type '(choice (const :tag "No" nil) + (const :tag "Check" check) + ;; NOTE: If you add entries here, make sure to update + ;; `tocheck-capabilities' in `terminal-init-xterm' as well. + (set (const :tag "modifyOtherKeys support" modifyOtherKeys) + (const :tag "report background" reportBackground)))) + (defvar xterm-function-map (let ((map (make-sparse-keymap))) @@ -460,81 +477,116 @@ (set-keymap-parent map (keymap-parent input-decode-map)) (set-keymap-parent input-decode-map map))) - (xterm-register-default-colors) - (tty-set-up-initial-frame-faces) + (xterm-register-default-colors) + (tty-set-up-initial-frame-faces) - ;; Try to turn on the modifyOtherKeys feature on modern xterms. - ;; When it is turned on many more key bindings work: things like - ;; C-. C-, etc. - ;; To do that we need to find out if the current terminal supports - ;; modifyOtherKeys. At this time only xterm does. + ;; Try to turn on the modifyOtherKeys feature on modern xterms. + ;; When it is turned on many more key bindings work: things like + ;; C-. C-, etc. + ;; To do that we need to find out if the current terminal supports + ;; modifyOtherKeys. At this time only xterm does. + (when xterm-extra-capabilities (let ((coding-system-for-read 'binary) - (chr nil) - (str nil) - (recompute-faces nil) - version) - ;; Pending input can be mistakenly returned by the calls to - ;; read-event below. Discard it. - (discard-input) - ;; Try to find out the type of terminal by sending a "Secondary - ;; Device Attributes (DA)" query. - (send-string-to-terminal "\e[>0c") - - ;; The reply should be of the form: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c - ;; If the timeout is completely removed for read-event, this - ;; might hang for terminals that pretend to be xterm, but don't - ;; respond to this escape sequence. RMS' opinion was to remove - ;; it completely. That might be right, but let's first try to - ;; see if by using a longer timeout we get rid of most issues. - (when (equal (read-event nil nil 2) ?\e) - (when (equal (read-event nil nil 2) ?\[) - (while (not (equal (setq chr (read-event nil nil 2)) ?c)) - (setq str (concat str (string chr)))) - (when (string-match ">0;\\([0-9]+\\);0" str) - (setq version (string-to-number - (substring str (match-beginning 1) (match-end 1)))) - ;; xterm version 242 supports reporting the background - ;; color, maybe earlier versions do too... - (when (>= version 242) - (send-string-to-terminal "\e]11;?\e\\") - (when (equal (read-event nil nil 2) ?\e) - (when (equal (read-event nil nil 2) ?\]) - (setq str "") - (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) - (setq str (concat str (string chr)))) - (when (string-match "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) - (setq recompute-faces - (xterm-maybe-set-dark-background-mode - (string-to-number (match-string 1 str) 16) - (string-to-number (match-string 2 str) 16) - (string-to-number (match-string 3 str) 16))))))) - ;; NUMBER2 is the xterm version number, look for something - ;; greater than 216, the version when modifyOtherKeys was - ;; introduced. - (when (>= version 216) - ;; Make sure that the modifyOtherKeys state is restored when - ;; suspending, resuming and exiting. - (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys) - (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys) - (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys) - (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) - ;; Add the selected frame to the list of frames that - ;; need to deal with modify-other-keys. - (push (frame-terminal (selected-frame)) - xterm-modify-other-keys-terminal-list) - (xterm-turn-on-modify-other-keys)) - - ;; Recompute faces here in case the background mode was - ;; set to dark. We used to call - ;; `tty-set-up-initial-frame-faces' only once, but that - ;; caused the light background faces to be computed - ;; incorrectly. See: - ;; http://permalink.gmane.org/gmane.emacs.devel/119627 - (when recompute-faces - (tty-set-up-initial-frame-faces)))))) + (chr nil) + (str nil) + (background-regex + "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)") + (recompute-faces nil) + ;; If `xterm-extra-capabilities' is 'check, we don't know + ;; the capabilities. We need to check for those defined + ;; as `xterm-extra-capabilities' set options. Otherwise, + ;; we don't need to check for any capabilities because + ;; they are given by setting `xterm-extra-capabilities' to + ;; a list (which could be empty). + (tocheck-capabilities (when (eq 'check xterm-extra-capabilities) + '(modifyOtherKeys reportBackground))) + ;; The given capabilities are either the contents of + ;; `xterm-extra-capabilities', if it's a list, or an empty + ;; list. + (given-capabilities (when (consp xterm-extra-capabilities) + xterm-extra-capabilities)) + version) + + ;; Do the following if `xterm-extra-capabilities' is anything but nil. + (when xterm-extra-capabilities + ;; 1. Set `version' + + ;; Pending input can be mistakenly returned by the calls to + ;; read-event below. Discard it. + (discard-input) + ;; Try to find out the type of terminal by sending a "Secondary + ;; Device Attributes (DA)" query. + (send-string-to-terminal "\e[>0c") + + ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c + ;; If the timeout is completely removed for read-event, this + ;; might hang for terminals that pretend to be xterm, but don't + ;; respond to this escape sequence. RMS' opinion was to remove + ;; it completely. That might be right, but let's first try to + ;; see if by using a longer timeout we get rid of most issues. + (when (equal (read-event nil nil 2) ?\e) + (when (equal (read-event nil nil 2) ?\[) + (while (not (equal (setq chr (read-event nil nil 2)) ?c)) + (setq str (concat str (string chr)))) + (when (string-match ">0;\\([0-9]+\\);0" str) + (setq version + (string-to-number + (substring str (match-beginning 1) (match-end 1))))))) + + ;; 2. If reportBackground is known to be supported, or the + ;; version is 242 or higher, assume the xterm supports + ;; reporting the background color (TODO: maybe earlier + ;; versions do too...) + (when (or (memq 'reportBackground given-capabilities) + (and (memq 'reportBackground tocheck-capabilities) + (>= version 242))) + (send-string-to-terminal "\e]11;?\e\\") + (when (equal (read-event nil nil 2) ?\e) + (when (equal (read-event nil nil 2) ?\]) + (setq str "") + (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) + (setq str (concat str (string chr)))) + (when (string-match background-regex str) + (setq recompute-faces + (xterm-maybe-set-dark-background-mode + (string-to-number (match-string 1 str) 16) + (string-to-number (match-string 2 str) 16) + (string-to-number (match-string 3 str) 16))))))) + + ;; 3. If modifyOtherKeys is known to be supported or the + ;; version is 216 (the version when modifyOtherKeys was + ;; introduced) or higher, initialize the modifyOtherKeys + ;; support. + (when (or (memq 'modifyOtherKeys given-capabilities) + (and (memq 'modifyOtherKeys tocheck-capabilities) + (>= version 216))) + (terminal-init-xterm-modify-other-keys)) + + ;; Recompute faces here in case the background mode was + ;; set to dark. We used to call + ;; `tty-set-up-initial-frame-faces' only once, but that + ;; caused the light background faces to be computed + ;; incorrectly. See: + ;; http://permalink.gmane.org/gmane.emacs.devel/119627 + (when recompute-faces + (tty-set-up-initial-frame-faces))))) (run-hooks 'terminal-init-xterm-hook)) +(defun terminal-init-xterm-modify-other-keys () + "Terminal initialization for xterm's modifyOtherKeys support." + ;; Make sure that the modifyOtherKeys state is restored when + ;; suspending, resuming and exiting. + (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys) + (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys) + (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys) + (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) + ;; Add the selected frame to the list of frames that + ;; need to deal with modify-other-keys. + (push (frame-terminal (selected-frame)) + xterm-modify-other-keys-terminal-list) + (xterm-turn-on-modify-other-keys)) + ;; Set up colors, for those versions of xterm that support it. (defvar xterm-standard-colors ;; The names in the comments taken from XTerm-col.ad in the xterm ------------------------------------------------------------ revno: 104545 committer: Glenn Morris branch nick: trunk timestamp: Thu 2011-06-09 06:18:21 -0400 message: Auto-commit of generated files. diff: === modified file 'autogen/Makefile.in' --- autogen/Makefile.in 2011-05-30 10:18:40 +0000 +++ autogen/Makefile.in 2011-06-09 10:18:21 +0000 @@ -1207,58 +1207,58 @@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ - -e 's|@''GNULIB_DPRINTF''@|$(GNULIB_DPRINTF)|g' \ - -e 's|@''GNULIB_FCLOSE''@|$(GNULIB_FCLOSE)|g' \ - -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ - -e 's|@''GNULIB_FGETC''@|$(GNULIB_FGETC)|g' \ - -e 's|@''GNULIB_FGETS''@|$(GNULIB_FGETS)|g' \ - -e 's|@''GNULIB_FOPEN''@|$(GNULIB_FOPEN)|g' \ - -e 's|@''GNULIB_FPRINTF''@|$(GNULIB_FPRINTF)|g' \ - -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_FPURGE''@|$(GNULIB_FPURGE)|g' \ - -e 's|@''GNULIB_FPUTC''@|$(GNULIB_FPUTC)|g' \ - -e 's|@''GNULIB_FPUTS''@|$(GNULIB_FPUTS)|g' \ - -e 's|@''GNULIB_FREAD''@|$(GNULIB_FREAD)|g' \ - -e 's|@''GNULIB_FREOPEN''@|$(GNULIB_FREOPEN)|g' \ - -e 's|@''GNULIB_FSCANF''@|$(GNULIB_FSCANF)|g' \ - -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ - -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ - -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ - -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ - -e 's|@''GNULIB_FWRITE''@|$(GNULIB_FWRITE)|g' \ - -e 's|@''GNULIB_GETC''@|$(GNULIB_GETC)|g' \ - -e 's|@''GNULIB_GETCHAR''@|$(GNULIB_GETCHAR)|g' \ - -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ - -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ - -e 's|@''GNULIB_GETS''@|$(GNULIB_GETS)|g' \ - -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ - -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \ - -e 's|@''GNULIB_PERROR''@|$(GNULIB_PERROR)|g' \ - -e 's|@''GNULIB_POPEN''@|$(GNULIB_POPEN)|g' \ - -e 's|@''GNULIB_PRINTF''@|$(GNULIB_PRINTF)|g' \ - -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ - -e 's|@''GNULIB_PUTC''@|$(GNULIB_PUTC)|g' \ - -e 's|@''GNULIB_PUTCHAR''@|$(GNULIB_PUTCHAR)|g' \ - -e 's|@''GNULIB_PUTS''@|$(GNULIB_PUTS)|g' \ - -e 's|@''GNULIB_REMOVE''@|$(GNULIB_REMOVE)|g' \ - -e 's|@''GNULIB_RENAME''@|$(GNULIB_RENAME)|g' \ - -e 's|@''GNULIB_RENAMEAT''@|$(GNULIB_RENAMEAT)|g' \ - -e 's|@''GNULIB_SCANF''@|$(GNULIB_SCANF)|g' \ - -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ - -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_STDIO_H_NONBLOCKING''@|$(GNULIB_STDIO_H_NONBLOCKING)|g' \ - -e 's|@''GNULIB_STDIO_H_SIGPIPE''@|$(GNULIB_STDIO_H_SIGPIPE)|g' \ - -e 's|@''GNULIB_TMPFILE''@|$(GNULIB_TMPFILE)|g' \ - -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ - -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ - -e 's|@''GNULIB_VFPRINTF''@|$(GNULIB_VFPRINTF)|g' \ - -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VFSCANF''@|$(GNULIB_VFSCANF)|g' \ - -e 's|@''GNULIB_VSCANF''@|$(GNULIB_VSCANF)|g' \ - -e 's|@''GNULIB_VPRINTF''@|$(GNULIB_VPRINTF)|g' \ - -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ - -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ + -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ + -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ + -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ + -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ + -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ + -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \ + -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \ + -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \ + -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \ + -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \ + -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \ + -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \ + -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \ + -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \ + -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \ + -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \ + -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \ + -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \ + -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \ + -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ + -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ + -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ + -e 's/@''GNULIB_GETS''@/$(GNULIB_GETS)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \ + -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \ + -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \ + -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \ + -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \ + -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \ + -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \ + -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \ + -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ + -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ + -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ + -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ + -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ + -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ + -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \ + -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ + -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ + -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ < $(srcdir)/stdio.in.h | \ sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ -e 's|@''HAVE_DECL_FSEEKO''@|$(HAVE_DECL_FSEEKO)|g' \ @@ -1322,34 +1322,34 @@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ - -e 's|@''GNULIB__EXIT''@|$(GNULIB__EXIT)|g' \ - -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \ - -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ - -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \ - -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ - -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ - -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \ - -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ - -e 's|@''GNULIB_MBTOWC''@|$(GNULIB_MBTOWC)|g' \ - -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ - -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \ - -e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \ - -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ - -e 's|@''GNULIB_MKSTEMPS''@|$(GNULIB_MKSTEMPS)|g' \ - -e 's|@''GNULIB_PTSNAME''@|$(GNULIB_PTSNAME)|g' \ - -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \ - -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \ - -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ - -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \ - -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \ - -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \ - -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \ - -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \ - -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \ - -e 's|@''GNULIB_SYSTEM_POSIX''@|$(GNULIB_SYSTEM_POSIX)|g' \ - -e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \ - -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \ - -e 's|@''GNULIB_WCTOMB''@|$(GNULIB_WCTOMB)|g' \ + -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ + -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ + -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ + -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ + -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ + -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ + -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ + -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ + -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ + -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ + -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ + -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ + -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ + -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ + -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ + -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ + -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ + -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ + -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ + -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ + -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ + -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ + -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ + -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ + -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ + -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ < $(srcdir)/stdlib.in.h | \ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ @@ -1404,18 +1404,18 @@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ - -e 's|@''GNULIB_FCHMODAT''@|$(GNULIB_FCHMODAT)|g' \ - -e 's|@''GNULIB_FSTATAT''@|$(GNULIB_FSTATAT)|g' \ - -e 's|@''GNULIB_FUTIMENS''@|$(GNULIB_FUTIMENS)|g' \ - -e 's|@''GNULIB_LCHMOD''@|$(GNULIB_LCHMOD)|g' \ - -e 's|@''GNULIB_LSTAT''@|$(GNULIB_LSTAT)|g' \ - -e 's|@''GNULIB_MKDIRAT''@|$(GNULIB_MKDIRAT)|g' \ - -e 's|@''GNULIB_MKFIFO''@|$(GNULIB_MKFIFO)|g' \ - -e 's|@''GNULIB_MKFIFOAT''@|$(GNULIB_MKFIFOAT)|g' \ - -e 's|@''GNULIB_MKNOD''@|$(GNULIB_MKNOD)|g' \ - -e 's|@''GNULIB_MKNODAT''@|$(GNULIB_MKNODAT)|g' \ - -e 's|@''GNULIB_STAT''@|$(GNULIB_STAT)|g' \ - -e 's|@''GNULIB_UTIMENSAT''@|$(GNULIB_UTIMENSAT)|g' \ + -e 's/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \ + -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \ + -e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \ + -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ + -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ + -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ + -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \ + -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \ + -e 's/@''GNULIB_MKNOD''@/$(GNULIB_MKNOD)/g' \ + -e 's/@''GNULIB_MKNODAT''@/$(GNULIB_MKNODAT)/g' \ + -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \ + -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \ -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \ @@ -1453,11 +1453,11 @@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ - -e 's|@''GNULIB_MKTIME''@|$(GNULIB_MKTIME)|g' \ - -e 's|@''GNULIB_NANOSLEEP''@|$(GNULIB_NANOSLEEP)|g' \ - -e 's|@''GNULIB_STRPTIME''@|$(GNULIB_STRPTIME)|g' \ - -e 's|@''GNULIB_TIMEGM''@|$(GNULIB_TIMEGM)|g' \ - -e 's|@''GNULIB_TIME_R''@|$(GNULIB_TIME_R)|g' \ + -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \ + -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \ + -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ + -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ + -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \ -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ @@ -1487,50 +1487,50 @@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ - -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ - -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|g' \ - -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ - -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \ - -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \ - -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \ - -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \ - -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ - -e 's|@''GNULIB_FCHOWNAT''@|$(GNULIB_FCHOWNAT)|g' \ - -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \ - -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ - -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ - -e 's|@''GNULIB_GETDOMAINNAME''@|$(GNULIB_GETDOMAINNAME)|g' \ - -e 's|@''GNULIB_GETDTABLESIZE''@|$(GNULIB_GETDTABLESIZE)|g' \ - -e 's|@''GNULIB_GETGROUPS''@|$(GNULIB_GETGROUPS)|g' \ - -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \ - -e 's|@''GNULIB_GETLOGIN''@|$(GNULIB_GETLOGIN)|g' \ - -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ - -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \ - -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \ - -e 's|@''GNULIB_GROUP_MEMBER''@|$(GNULIB_GROUP_MEMBER)|g' \ - -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ - -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \ - -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \ - -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ - -e 's|@''GNULIB_PIPE''@|$(GNULIB_PIPE)|g' \ - -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \ - -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \ - -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \ - -e 's|@''GNULIB_READ''@|$(GNULIB_READ)|g' \ - -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ - -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \ - -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \ - -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ - -e 's|@''GNULIB_SYMLINK''@|$(GNULIB_SYMLINK)|g' \ - -e 's|@''GNULIB_SYMLINKAT''@|$(GNULIB_SYMLINKAT)|g' \ - -e 's|@''GNULIB_TTYNAME_R''@|$(GNULIB_TTYNAME_R)|g' \ - -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \ - -e 's|@''GNULIB_UNISTD_H_NONBLOCKING''@|$(GNULIB_UNISTD_H_NONBLOCKING)|g' \ - -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \ - -e 's|@''GNULIB_UNLINK''@|$(GNULIB_UNLINK)|g' \ - -e 's|@''GNULIB_UNLINKAT''@|$(GNULIB_UNLINKAT)|g' \ - -e 's|@''GNULIB_USLEEP''@|$(GNULIB_USLEEP)|g' \ - -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \ + -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ + -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ + -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ + -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ + -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ + -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ + -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ + -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ + -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ + -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ + -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ + -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ + -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ + -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ + -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ + -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ + -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ + -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \ + -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \ + -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \ + -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \ + -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \ + -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \ + -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \ + -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \ + -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \ + -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \ + -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \ + -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \ + -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \ + -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \ + -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \ + -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \ + -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ + -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ + -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ + -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ + -e 's/@''GNULIB_UNISTD_H_GETOPT''@/$(GNULIB_UNISTD_H_GETOPT)/g' \ + -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \ + -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ + -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ + -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ < $(srcdir)/unistd.in.h | \ sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ === modified file 'autogen/configure' --- autogen/configure 2011-06-07 10:18:29 +0000 +++ autogen/configure 2011-06-09 10:18:21 +0000 @@ -17242,7 +17242,11 @@ - GNULIB_GETLOADAVG=1 + + + GNULIB_GETLOADAVG=1 + + @@ -17315,7 +17319,11 @@ - GNULIB_LSTAT=1 + + + GNULIB_LSTAT=1 + + @@ -17569,7 +17577,11 @@ - GNULIB_MKTIME=1 + + + GNULIB_MKTIME=1 + + @@ -17690,7 +17702,11 @@ - GNULIB_READLINK=1 + + + GNULIB_READLINK=1 + + @@ -18304,7 +18320,11 @@ - GNULIB_STRTOUMAX=1 + + + GNULIB_STRTOUMAX=1 + + @@ -18382,7 +18402,11 @@ - GNULIB_SYMLINK=1 + + + GNULIB_SYMLINK=1 + + @@ -18547,7 +18571,11 @@ - GNULIB_TIME_R=1 + + + GNULIB_TIME_R=1 + + @@ -18760,7 +18788,11 @@ - GNULIB_STAT=1 + + + GNULIB_STAT=1 + + @@ -18812,7 +18844,11 @@ - GNULIB_STRTOULL=1 + + + GNULIB_STRTOULL=1 + + ------------------------------------------------------------ revno: 104544 committer: martin rudalics branch nick: trunk timestamp: Thu 2011-06-09 10:41:36 +0200 message: Final preparations in window.el for new window resize code. * window.el (resize-window-reset, resize-window-reset-1) (resize-subwindows-skip-p, resize-subwindows-normal) (resize-subwindows, resize-other-windows, resize-this-window) (resize-root-window, resize-root-window-vertically) (window-deletable-p, window-or-subwindow-p) (frame-root-window-p): New functions. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-09 06:07:11 +0000 +++ lisp/ChangeLog 2011-06-09 08:41:36 +0000 @@ -1,3 +1,12 @@ +2011-06-09 Martin Rudalics + + * window.el (resize-window-reset, resize-window-reset-1) + (resize-subwindows-skip-p, resize-subwindows-normal) + (resize-subwindows, resize-other-windows, resize-this-window) + (resize-root-window, resize-root-window-vertically) + (window-deletable-p, window-or-subwindow-p) + (frame-root-window-p): New functions. + 2011-06-09 Glenn Morris * net/ange-ftp.el (ange-ftp-switches-ok): New function. === modified file 'lisp/window.el' --- lisp/window.el 2011-06-08 09:13:43 +0000 +++ lisp/window.el 2011-06-09 08:41:36 +0000 @@ -1312,7 +1312,503 @@ window shall be counted. See `walk-windows' for the precise meaning of this argument." (length (window-list-1 nil minibuf))) - + +;;; Resizing windows. +(defun resize-window-reset (&optional frame horizontal) + "Reset resize values for all windows on FRAME. +FRAME defaults to the selected frame. + +This function stores the current value of `window-total-size' applied +with argument HORIZONTAL in the new total size of all windows on +FRAME. It also resets the new normal size of each of these +windows." + (resize-window-reset-1 + (frame-root-window (normalize-live-frame frame)) horizontal)) + +(defun resize-window-reset-1 (window horizontal) + "Internal function of `resize-window-reset'." + ;; Register old size in the new total size. + (set-window-new-total window (window-total-size window horizontal)) + ;; Reset new normal size. + (set-window-new-normal window) + (when (window-child window) + (resize-window-reset-1 (window-child window) horizontal)) + (when (window-right window) + (resize-window-reset-1 (window-right window) horizontal))) + +(defsubst resize-subwindows-skip-p (window) + "Return non-nil if WINDOW shall be skipped by resizing routines." + (memq (window-new-normal window) '(ignore stuck skip))) + +(defun resize-subwindows-normal (parent horizontal window this-delta &optional trail other-delta) + "Set the new normal height of subwindows of window PARENT. +HORIZONTAL non-nil means set the new normal width of these +windows. WINDOW specifies a subwindow of PARENT that has been +resized by THIS-DELTA lines \(columns). + +Optional argument TRAIL either 'before or 'after means set values +for windows before or after WINDOW only. Optional argument +OTHER-DELTA a number specifies that this many lines \(columns) +have been obtained from \(or returned to) an ancestor window of +PARENT in order to resize WINDOW." + (let* ((delta-normal + (if (and (= (- this-delta) (window-total-size window horizontal)) + (zerop other-delta)) + ;; When WINDOW gets deleted and we can return its entire + ;; space to its siblings, use WINDOW's normal size as the + ;; normal delta. + (- (window-normal-size window horizontal)) + ;; In any other case calculate the normal delta from the + ;; relation of THIS-DELTA to the total size of PARENT. + (/ (float this-delta) (window-total-size parent horizontal)))) + (sub (window-child parent)) + (parent-normal 0.0) + (skip (eq trail 'after))) + + ;; Set parent-normal to the sum of the normal sizes of all + ;; subwindows of PARENT that shall be resized, excluding only WINDOW + ;; and any windows specified by the optional TRAIL argument. + (while sub + (cond + ((eq sub window) + (setq skip (eq trail 'before))) + (skip) + (t + (setq parent-normal + (+ parent-normal (window-normal-size sub horizontal))))) + (setq sub (window-right sub))) + + ;; Set the new normal size of all subwindows of PARENT from what + ;; they should have contributed for recovering THIS-DELTA lines + ;; (columns). + (setq sub (window-child parent)) + (setq skip (eq trail 'after)) + (while sub + (cond + ((eq sub window) + (setq skip (eq trail 'before))) + (skip) + (t + (let ((old-normal (window-normal-size sub horizontal))) + (set-window-new-normal + sub (min 1.0 ; Don't get larger than 1. + (max (- old-normal + (* (/ old-normal parent-normal) + delta-normal)) + ;; Don't drop below 0. + 0.0)))))) + (setq sub (window-right sub))) + + (when (numberp other-delta) + ;; Set the new normal size of windows from what they should have + ;; contributed for recovering OTHER-DELTA lines (columns). + (setq delta-normal (/ (float (window-total-size parent horizontal)) + (+ (window-total-size parent horizontal) + other-delta))) + (setq sub (window-child parent)) + (setq skip (eq trail 'after)) + (while sub + (cond + ((eq sub window) + (setq skip (eq trail 'before))) + (skip) + (t + (set-window-new-normal + sub (min 1.0 ; Don't get larger than 1. + (max (* (window-new-normal sub) delta-normal) + ;; Don't drop below 0. + 0.0))))) + (setq sub (window-right sub)))) + + ;; Set the new normal size of WINDOW to what is left by the sum of + ;; the normal sizes of its siblings. + (set-window-new-normal + window + (let ((sum 0)) + (setq sub (window-child parent)) + (while sub + (cond + ((eq sub window)) + ((not (numberp (window-new-normal sub))) + (setq sum (+ sum (window-normal-size sub horizontal)))) + (t + (setq sum (+ sum (window-new-normal sub))))) + (setq sub (window-right sub))) + ;; Don't get larger than 1 or smaller than 0. + (min 1.0 (max (- 1.0 sum) 0.0)))))) + +(defun resize-subwindows (parent delta &optional horizontal window ignore trail edge) + "Resize subwindows of window PARENT vertically by DELTA lines. +PARENT must be a vertically combined internal window. + +Optional argument HORIZONTAL non-nil means resize subwindows of +PARENT horizontally by DELTA columns. In this case PARENT must +be a horizontally combined internal window. + +WINDOW, if specified, must denote a child window of PARENT that +is resized by DELTA lines. + +Optional argument IGNORE non-nil means ignore any restrictions +imposed by fixed size windows, `window-min-height' or +`window-min-width' settings. IGNORE equal `safe' means live +windows may get as small as `window-safe-min-height' lines and +`window-safe-min-width' columns. IGNORE any window means ignore +restrictions for that window only. + +Optional arguments TRAIL and EDGE, when non-nil, restrict the set +of windows that shall be resized. If TRAIL equals `before', +resize only windows on the left or above EDGE. If TRAIL equals +`after', resize only windows on the right or below EDGE. Also, +preferably only resize windows adjacent to EDGE. + +Return the symbol `normalized' if new normal sizes have been +already set by this routine." + (let* ((first (window-child parent)) + (sub first) + (parent-total (+ (window-total-size parent horizontal) delta)) + best-window best-value) + + (if (and edge (memq trail '(before after)) + (progn + (setq sub first) + (while (and (window-right sub) + (or (and (eq trail 'before) + (not (resize-subwindows-skip-p + (window-right sub)))) + (and (eq trail 'after) + (resize-subwindows-skip-p sub)))) + (setq sub (window-right sub))) + sub) + (if horizontal + (if (eq trail 'before) + (= (+ (window-left-column sub) + (window-total-size sub t)) + edge) + (= (window-left-column sub) edge)) + (if (eq trail 'before) + (= (+ (window-top-line sub) + (window-total-size sub)) + edge) + (= (window-top-line sub) edge))) + (window-sizable-p sub delta horizontal ignore)) + ;; Resize only windows adjacent to EDGE. + (progn + (resize-this-window sub delta horizontal ignore t trail edge) + (if (and window (eq (window-parent sub) parent)) + (progn + ;; Assign new normal sizes. + (set-window-new-normal + sub (/ (float (window-new-total sub)) parent-total)) + (set-window-new-normal + window (- (window-normal-size window horizontal) + (- (window-new-normal sub) + (window-normal-size sub horizontal))))) + (resize-subwindows-normal parent horizontal sub 0 trail delta)) + ;; Return 'normalized to notify `resize-other-windows' that + ;; normal sizes have been already set. + 'normalized) + ;; Resize all windows proportionally. + (setq sub first) + (while sub + (cond + ((or (resize-subwindows-skip-p sub) + ;; Ignore windows to skip and fixed-size subwindows - in + ;; the latter case make it a window to skip. + (and (not ignore) + (window-size-fixed-p sub horizontal) + (set-window-new-normal sub 'ignore)))) + ((< delta 0) + ;; When shrinking store the number of lines/cols we can get + ;; from this window here together with the total/normal size + ;; factor. + (set-window-new-normal + sub + (cons + ;; We used to call this with NODOWN t, "fixed" 2011-05-11. + (window-min-delta sub horizontal ignore trail t) ; t) + (- (/ (float (window-total-size sub horizontal)) + parent-total) + (window-normal-size sub horizontal))))) + ((> delta 0) + ;; When enlarging store the total/normal size factor only + (set-window-new-normal + sub + (- (/ (float (window-total-size sub horizontal)) + parent-total) + (window-normal-size sub horizontal))))) + + (setq sub (window-right sub))) + + (cond + ((< delta 0) + ;; Shrink windows by delta. + (setq best-window t) + (while (and best-window (not (zerop delta))) + (setq sub first) + (setq best-window nil) + (setq best-value most-negative-fixnum) + (while sub + (when (and (consp (window-new-normal sub)) + (not (zerop (car (window-new-normal sub)))) + (> (cdr (window-new-normal sub)) best-value)) + (setq best-window sub) + (setq best-value (cdr (window-new-normal sub)))) + + (setq sub (window-right sub))) + + (when best-window + (setq delta (1+ delta))) + (set-window-new-total best-window -1 t) + (set-window-new-normal + best-window + (if (= (car (window-new-normal best-window)) 1) + 'skip ; We can't shrink best-window any further. + (cons (1- (car (window-new-normal best-window))) + (- (/ (float (window-new-total best-window)) + parent-total) + (window-normal-size best-window horizontal))))))) + ((> delta 0) + ;; Enlarge windows by delta. + (setq best-window t) + (while (and best-window (not (zerop delta))) + (setq sub first) + (setq best-window nil) + (setq best-value most-positive-fixnum) + (while sub + (when (and (numberp (window-new-normal sub)) + (< (window-new-normal sub) best-value)) + (setq best-window sub) + (setq best-value (window-new-normal sub))) + + (setq sub (window-right sub))) + + (when best-window + (setq delta (1- delta))) + (set-window-new-total best-window 1 t) + (set-window-new-normal + best-window + (- (/ (float (window-new-total best-window)) + parent-total) + (window-normal-size best-window horizontal)))))) + + (when best-window + (setq sub first) + (while sub + (when (or (consp (window-new-normal sub)) + (numberp (window-new-normal sub))) + ;; Reset new normal size fields so `resize-window-apply' + ;; won't use them to apply new sizes. + (set-window-new-normal sub)) + + (unless (eq (window-new-normal sub) 'ignore) + ;; Resize this subwindow's subwindows (back-engineering + ;; delta from sub's old and new total sizes). + (let ((delta (- (window-new-total sub) + (window-total-size sub horizontal)))) + (unless (and (zerop delta) (not trail)) + ;; For the TRAIL non-nil case we have to resize SUB + ;; recursively even if it's size does not change. + (resize-this-window + sub delta horizontal ignore nil trail edge)))) + (setq sub (window-right sub))))))) + +(defun resize-other-windows (window delta &optional horizontal ignore trail edge) + "Resize other windows when WINDOW is resized vertically by DELTA lines. +Optional argument HORIZONTAL non-nil means resize other windows +when WINDOW is resized horizontally by DELTA columns. WINDOW +itself is not resized by this function. + +Optional argument IGNORE non-nil means ignore any restrictions +imposed by fixed size windows, `window-min-height' or +`window-min-width' settings. IGNORE equal `safe' means live +windows may get as small as `window-safe-min-height' lines and +`window-safe-min-width' columns. IGNORE any window means ignore +restrictions for that window only. + +Optional arguments TRAIL and EDGE, when non-nil, refine the set +of windows that shall be resized. If TRAIL equals `before', +resize only windows on the left or above EDGE. If TRAIL equals +`after', resize only windows on the right or below EDGE. Also, +preferably only resize windows adjacent to EDGE." + (when (window-parent window) + (let* ((parent (window-parent window)) + (sub (window-child parent))) + (if (window-iso-combined-p sub horizontal) + ;; In an iso-combination try to extract DELTA from WINDOW's + ;; siblings. + (let ((first sub) + (skip (eq trail 'after)) + this-delta other-delta) + ;; Decide which windows shall be left alone. + (while sub + (cond + ((eq sub window) + ;; Make sure WINDOW is left alone when + ;; resizing its siblings. + (set-window-new-normal sub 'ignore) + (setq skip (eq trail 'before))) + (skip + ;; Make sure this sibling is left alone when + ;; resizing its siblings. + (set-window-new-normal sub 'ignore)) + ((or (window-size-ignore sub ignore) + (not (window-size-fixed-p sub horizontal))) + ;; Set this-delta to t to signal that we found a sibling + ;; of WINDOW whose size is not fixed. + (setq this-delta t))) + + (setq sub (window-right sub))) + + ;; Set this-delta to what we can get from WINDOW's siblings. + (if (= (- delta) (window-total-size window horizontal)) + ;; A deletion, presumably. We must handle this case + ;; specially since `window-resizable' can't be used. + (if this-delta + ;; There's at least one resizable sibling we can + ;; give WINDOW's size to. + (setq this-delta delta) + ;; No resizable sibling exists. + (setq this-delta 0)) + ;; Any other form of resizing. + (setq this-delta + (window-resizable window delta horizontal ignore trail t))) + + ;; Set other-delta to what we still have to get from + ;; ancestor windows of parent. + (setq other-delta (- delta this-delta)) + (unless (zerop other-delta) + ;; Unless we got everything from WINDOW's siblings, PARENT + ;; must be resized by other-delta lines or columns. + (set-window-new-total parent other-delta 'add)) + + (if (zerop this-delta) + ;; We haven't got anything from WINDOW's siblings but we + ;; must update the normal sizes to respect other-delta. + (resize-subwindows-normal + parent horizontal window this-delta trail other-delta) + ;; We did get something from WINDOW's siblings which means + ;; we have to resize their subwindows. + (unless (eq (resize-subwindows parent (- this-delta) horizontal + window ignore trail edge) + ;; `resize-subwindows' returning 'normalized, + ;; means it has set the normal sizes already. + 'normalized) + ;; Set the normal sizes. + (resize-subwindows-normal + parent horizontal window this-delta trail other-delta)) + ;; Set DELTA to what we still have to get from ancestor + ;; windows. + (setq delta other-delta))) + + ;; In an ortho-combination all siblings of WINDOW must be + ;; resized by DELTA. + (set-window-new-total parent delta 'add) + (while sub + (unless (eq sub window) + (resize-this-window sub delta horizontal ignore t)) + (setq sub (window-right sub)))) + + (unless (zerop delta) + ;; "Go up." + (resize-other-windows parent delta horizontal ignore trail edge))))) + +(defun resize-this-window (window delta &optional horizontal ignore add trail edge) + "Resize WINDOW vertically by DELTA lines. +Optional argument HORIZONTAL non-nil means resize WINDOW +horizontally by DELTA columns. + +Optional argument IGNORE non-nil means ignore any restrictions +imposed by fixed size windows, `window-min-height' or +`window-min-width' settings. IGNORE equal `safe' means live +windows may get as small as `window-safe-min-height' lines and +`window-safe-min-width' columns. IGNORE any window means ignore +restrictions for that window only. + +Optional argument ADD non-nil means add DELTA to the new total +size of WINDOW. + +Optional arguments TRAIL and EDGE, when non-nil, refine the set +of windows that shall be resized. If TRAIL equals `before', +resize only windows on the left or above EDGE. If TRAIL equals +`after', resize only windows on the right or below EDGE. Also, +preferably only resize windows adjacent to EDGE. + +This function recursively resizes WINDOW's subwindows to fit the +new size. Make sure that WINDOW is `window-resizable' before +calling this function. Note that this function does not resize +siblings of WINDOW or WINDOW's parent window. You have to +eventually call `resize-window-apply' in order to make resizing +actually take effect." + (when add + ;; Add DELTA to the new total size of WINDOW. + (set-window-new-total window delta t)) + + (let ((sub (window-child window))) + (cond + ((not sub)) + ((window-iso-combined-p sub horizontal) + ;; In an iso-combination resize subwindows according to their + ;; normal sizes. + (resize-subwindows window delta horizontal nil ignore trail edge)) + ;; In an ortho-combination resize each subwindow by DELTA. + (t + (while sub + (resize-this-window sub delta horizontal ignore t trail edge) + (setq sub (window-right sub))))))) + +(defun resize-root-window (window delta horizontal ignore) + "Resize root window WINDOW vertically by DELTA lines. +HORIZONTAL non-nil means resize root window WINDOW horizontally +by DELTA columns. + +IGNORE non-nil means ignore any restrictions imposed by fixed +size windows, `window-min-height' or `window-min-width' settings. + +This function is only called by the frame resizing routines. It +resizes windows proportionally and never deletes any windows." + (when (and (windowp window) (numberp delta) + (window-sizable-p window delta horizontal ignore)) + (resize-window-reset (window-frame window) horizontal) + (resize-this-window window delta horizontal ignore t))) + +(defun resize-root-window-vertically (window delta) + "Resize root window WINDOW vertically by DELTA lines. +If DELTA is less than zero and we can't shrink WINDOW by DELTA +lines, shrink it as much as possible. If DELTA is greater than +zero, this function can resize fixed-size subwindows in order to +recover the necessary lines. + +Return the number of lines that were recovered. + +This function is only called by the minibuffer window resizing +routines. It resizes windows proportionally and never deletes +any windows." + (when (numberp delta) + (let (ignore) + (cond + ((< delta 0) + (setq delta (window-sizable window delta))) + ((> delta 0) + (unless (window-sizable window delta) + (setq ignore t)))) + + (resize-window-reset (window-frame window)) + ;; Ideally, we would resize just the last window in a combination + ;; but that's not feasible for the following reason: If we grow + ;; the minibuffer window and the last window cannot be shrunk any + ;; more, we shrink another window instead. But if we then shrink + ;; the minibuffer window again, the last window might get enlarged + ;; and the state after shrinking is not the state before growing. + ;; So, in practice, we'd need a history variable to record how to + ;; proceed. But I'm not sure how such a variable could work with + ;; repeated minibuffer window growing steps. + (resize-this-window window delta nil ignore t) + delta))) + +(defsubst frame-root-window-p (window) + "Return non-nil if WINDOW is the root window of its frame." + (eq window (frame-root-window window))) + ;; This should probably return non-nil when the selected window is part ;; of an atomic window whose root is the frame's root window. (defun one-window-p (&optional nomini all-frames) @@ -1347,6 +1843,49 @@ (eq base-window (next-window base-window (if nomini 'arg) all-frames)))) +;;; Deleting windows. +(defun window-deletable-p (&optional window) + "Return t if WINDOW can be safely deleted from its frame. +Return `frame' if deleting WINDOW should delete its frame +instead." + (setq window (normalize-any-window window)) + (unless ignore-window-parameters + ;; Handle atomicity. + (when (window-parameter window 'window-atom) + (setq window (window-atom-root window)))) + (let ((parent (window-parent window)) + (frame (window-frame window)) + (dedicated (and (window-buffer window) (window-dedicated-p window))) + (quit-restore (window-parameter window 'quit-restore))) + (cond + ((frame-root-window-p window) + (when (and (or dedicated + (and (eq (car-safe quit-restore) 'new-frame) + (eq (nth 1 quit-restore) (window-buffer window)))) + (other-visible-frames-p frame)) + ;; WINDOW is the root window of its frame. Return `frame' but + ;; only if WINDOW is (1) either dedicated or quit-restore's car + ;; is new-frame and the window still displays the same buffer + ;; and (2) there are other frames left. + 'frame)) + ((and (not ignore-window-parameters) + (eq (window-parameter window 'window-side) 'none) + (or (not parent) + (not (eq (window-parameter parent 'window-side) 'none)))) + ;; Can't delete last main window. + nil) + (t)))) + +(defun window-or-subwindow-p (subwindow window) + "Return t if SUBWINDOW is either WINDOW or a subwindow of WINDOW." + (or (eq subwindow window) + (let ((parent (window-parent subwindow))) + (catch 'done + (while parent + (if (eq parent window) + (throw 'done t) + (setq parent (window-parent parent)))))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; `balance-windows' subroutines using `window-tree' ------------------------------------------------------------ revno: 104543 committer: martin rudalics branch nick: trunk timestamp: Thu 2011-06-09 08:35:02 +0200 message: Final preparations for new window resize code. * window.c (replace_window): Rename second argument REPLACEMENT to NEW. New third argument SETFLAG. Rewrite. (delete_window, make_dummy_parent): Call replace_window with third argument 1. (window_list_1): Move down in code. (run_window_configuration_change_hook): Move set_buffer part before select_frame_norecord part in order to unwind correctly. Rename count1 to count. (recombine_windows, delete_deletable_window, resize_root_window) (Fdelete_other_windows_internal) (Frun_window_configuration_change_hook, make_parent_window) (resize_window_check, resize_window_apply, Fresize_window_apply) (resize_frame_windows, Fsplit_window_internal) (Fdelete_window_internal, Fresize_mini_window_internal): New functions. (syms_of_window): New variables Vwindow_splits and Vwindow_nest. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-06-08 13:00:51 +0000 +++ src/ChangeLog 2011-06-09 06:35:02 +0000 @@ -1,3 +1,22 @@ +2011-06-09 Martin Rudalics + + * window.c (replace_window): Rename second argument REPLACEMENT to + NEW. New third argument SETFLAG. Rewrite. + (delete_window, make_dummy_parent): Call replace_window with + third argument 1. + (window_list_1): Move down in code. + (run_window_configuration_change_hook): Move set_buffer part + before select_frame_norecord part in order to unwind correctly. + Rename count1 to count. + (recombine_windows, delete_deletable_window, resize_root_window) + (Fdelete_other_windows_internal) + (Frun_window_configuration_change_hook, make_parent_window) + (resize_window_check, resize_window_apply, Fresize_window_apply) + (resize_frame_windows, Fsplit_window_internal) + (Fdelete_window_internal, Fresize_mini_window_internal): New + functions. + (syms_of_window): New variables Vwindow_splits and Vwindow_nest. + 2011-06-08 Martin Rudalics * window.h (window): Add some new members to window structure - === modified file 'src/window.c' --- src/window.c 2011-06-08 13:00:51 +0000 +++ src/window.c 2011-06-09 06:35:02 +0000 @@ -90,6 +90,7 @@ int (* fn) (struct window *, void *), void *); static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); +static void resize_window_apply (struct window *, int); static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); /* This is the window in which the terminal's cursor should @@ -1853,60 +1854,146 @@ BVAR (b, last_selected_window) = Qnil; } -/* Put replacement into the window structure in place of old. */ +/* Put NEW into the window structure in place of OLD. SETFLAG zero + means change window structure only. Otherwise store geometry and + other settings as well. */ static void -replace_window (Lisp_Object old, Lisp_Object replacement) +replace_window (Lisp_Object old, Lisp_Object new, int setflag) { register Lisp_Object tem; - register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); - - /* If OLD is its frame's root_window, then replacement is the new - root_window for that frame. */ - + register struct window *o = XWINDOW (old), *n = XWINDOW (new); + + /* If OLD is its frame's root window, then NEW is the new + root window for that frame. */ if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) - FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; - - p->left_col = o->left_col; - p->top_line = o->top_line; - p->total_cols = o->total_cols; - p->total_lines = o->total_lines; - p->desired_matrix = p->current_matrix = 0; - p->vscroll = 0; - memset (&p->cursor, 0, sizeof (p->cursor)); - memset (&p->last_cursor, 0, sizeof (p->last_cursor)); - memset (&p->phys_cursor, 0, sizeof (p->phys_cursor)); - p->phys_cursor_type = -1; - p->phys_cursor_width = -1; - p->must_be_updated_p = 0; - p->pseudo_window_p = 0; - XSETFASTINT (p->window_end_vpos, 0); - XSETFASTINT (p->window_end_pos, 0); - p->window_end_valid = Qnil; - p->frozen_window_start_p = 0; - p->orig_top_line = p->orig_total_lines = Qnil; - - p->next = tem = o->next; - if (!NILP (tem)) - XWINDOW (tem)->prev = replacement; - - p->prev = tem = o->prev; - if (!NILP (tem)) - XWINDOW (tem)->next = replacement; - - p->parent = tem = o->parent; + FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new; + + if (setflag) + { + n->left_col = o->left_col; + n->top_line = o->top_line; + n->total_cols = o->total_cols; + n->total_lines = o->total_lines; + n->normal_cols = o->normal_cols; + o->normal_cols = make_float (1.0); + n->normal_lines = o->normal_lines; + o->normal_lines = make_float (1.0); + n->desired_matrix = n->current_matrix = 0; + n->vscroll = 0; + memset (&n->cursor, 0, sizeof (n->cursor)); + memset (&n->last_cursor, 0, sizeof (n->last_cursor)); + memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); + n->phys_cursor_type = -1; + n->phys_cursor_width = -1; + n->must_be_updated_p = 0; + n->pseudo_window_p = 0; + XSETFASTINT (n->window_end_vpos, 0); + XSETFASTINT (n->window_end_pos, 0); + n->window_end_valid = Qnil; + n->frozen_window_start_p = 0; + n->orig_top_line = n->orig_total_lines = Qnil; + } + + n->next = tem = o->next; + if (!NILP (tem)) + XWINDOW (tem)->prev = new; + + n->prev = tem = o->prev; + if (!NILP (tem)) + XWINDOW (tem)->next = new; + + n->parent = tem = o->parent; if (!NILP (tem)) { if (EQ (XWINDOW (tem)->vchild, old)) - XWINDOW (tem)->vchild = replacement; + XWINDOW (tem)->vchild = new; if (EQ (XWINDOW (tem)->hchild, old)) - XWINDOW (tem)->hchild = replacement; - } - -/*** Here, if replacement is a vertical combination -and so is its new parent, we should make replacement's -children be children of that parent instead. ***/ -} - + XWINDOW (tem)->hchild = new; + } +} + +/* If window WINDOW and its parent window are iso-combined, merge + WINDOW's children into those of its parent window and mark WINDOW as + deleted. */ + +static void +recombine_windows (Lisp_Object window) +{ + struct window *w, *p, *c; + Lisp_Object parent, child; + int horflag; + + w = XWINDOW (window); + parent = w->parent; + if (!NILP (parent) && NILP (w->nest)) + { + p = XWINDOW (parent); + if (((!NILP (p->vchild) && !NILP (w->vchild)) + || (!NILP (p->hchild) && !NILP (w->hchild)))) + /* WINDOW and PARENT are both either a vertical or a horizontal + combination. */ + { + horflag = NILP (w->vchild); + child = horflag ? w->hchild : w->vchild; + c = XWINDOW (child); + + /* Splice WINDOW's children into its parent's children and + assign new normal sizes. */ + if (NILP (w->prev)) + if (horflag) + p->hchild = child; + else + p->vchild = child; + else + { + c->prev = w->prev; + XWINDOW (w->prev)->next = child; + } + + while (c) + { + c->parent = parent; + + if (horflag) + c->normal_cols + = make_float (XFLOATINT (c->total_cols) + / XFLOATINT (p->total_cols)); + else + c->normal_lines + = make_float (XFLOATINT (c->total_lines) + / XFLOATINT (p->total_lines)); + + if (NILP (c->next)) + { + if (!NILP (w->next)) + { + c->next = w->next; + XWINDOW (c->next)->prev = child; + } + + c = 0; + } + else + { + child = c->next; + c = XWINDOW (child); + } + } + + /* WINDOW can be deleted now. */ + w->vchild = w->hchild = Qnil; + } + } +} + +/* If WINDOW can be deleted, delete it. */ +Lisp_Object +delete_deletable_window (Lisp_Object window) +{ + if (!NILP (call1 (Qwindow_deletable_p, window))) + call1 (Qdelete_window, window); +} + DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", doc: /* Remove WINDOW from its frame. WINDOW defaults to the selected window. Return nil. @@ -2067,7 +2154,7 @@ if (NILP (tem)) tem = par->vchild; if (NILP (XWINDOW (tem)->next)) { - replace_window (parent, tem); + replace_window (parent, tem, 1); par = XWINDOW (tem); } @@ -2427,43 +2514,6 @@ } -DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0, - doc: /* Return a list of all live windows. -WINDOW specifies the first window to list and defaults to the selected -window. - -Optional argument MINIBUF nil or omitted means consider the minibuffer -window only if the minibuffer is active. MINIBUF t means consider the -minibuffer window even if the minibuffer is not active. Any other value -means do not consider the minibuffer window even if the minibuffer is -active. - -Optional argument ALL-FRAMES nil or omitted means consider all windows -on WINDOW's frame, plus the minibuffer window if specified by the -MINIBUF argument. If the minibuffer counts, consider all windows on all -frames that share that minibuffer too. The following non-nil values of -ALL-FRAMES have special meanings: - -- t means consider all windows on all existing frames. - -- `visible' means consider all windows on all visible frames. - -- 0 (the number zero) means consider all windows on all visible and - iconified frames. - -- A frame means consider all windows on that frame only. - -Anything else means consider all windows on WINDOW's frame and no -others. - -If WINDOW is not on the list of windows returned, some other window will -be listed first but no error is signalled. */) - (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) -{ - return window_list_1 (window, minibuf, all_frames); -} - - DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", doc: /* Select another window in cyclic ordering of windows. COUNT specifies the number of windows to skip, starting with the @@ -2547,6 +2597,41 @@ } +DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0, + doc: /* Return a list of all live windows. +WINDOW specifies the first window to list and defaults to the selected +window. + +Optional argument MINIBUF nil or omitted means consider the minibuffer +window only if the minibuffer is active. MINIBUF t means consider the +minibuffer window even if the minibuffer is not active. Any other value +means do not consider the minibuffer window even if the minibuffer is +active. + +Optional argument ALL-FRAMES nil or omitted means consider all windows +on WINDOW's frame, plus the minibuffer window if specified by the +MINIBUF argument. If the minibuffer counts, consider all windows on all +frames that share that minibuffer too. The following non-nil values of +ALL-FRAMES have special meanings: + +- t means consider all windows on all existing frames. + +- `visible' means consider all windows on all visible frames. + +- 0 (the number zero) means consider all windows on all visible and + iconified frames. + +- A frame means consider all windows on that frame only. + +Anything else means consider all windows on WINDOW's frame and no +others. + +If WINDOW is not on the list of windows returned, some other window will +be listed first but no error is signalled. */) + (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) +{ + return window_list_1 (window, minibuf, all_frames); +} /* Look at all windows, performing an operation specified by TYPE with argument OBJ. @@ -2801,6 +2886,248 @@ return Qnil; } +Lisp_Object +resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) +{ + return call4 (Qresize_root_window, window, delta, horizontal, ignore); +} + + +DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal, + Sdelete_other_windows_internal, 0, 2, "", + doc: /* Make WINDOW fill its frame. +Only the frame WINDOW is on is affected. WINDOW may be any window and +defaults to the selected one. + +Optional argument ROOT, if non-nil, must specify an internal window +containing WINDOW as a subwindow. If this is the case, replace ROOT by +WINDOW and leave alone any windows not contained in ROOT. + +When WINDOW is live try to reduce display jumps by keeping the text +previously visible in WINDOW in the same place on the frame. Doing this +depends on the value of (window-start WINDOW), so if calling this +function in a program gives strange scrolling, make sure the +window-start value is reasonable when this function is called. */) + (Lisp_Object window, Lisp_Object root) +{ + struct window *w, *r, *s; + struct frame *f; + Lisp_Object sibling, pwindow, swindow, delta; + EMACS_INT startpos; + int top, new_top, resize_failed; + + w = decode_any_window (window); + XSETWINDOW (window, w); + f = XFRAME (w->frame); + + if (NILP (root)) + /* ROOT is the frame's root window. */ + { + root = FRAME_ROOT_WINDOW (f); + r = XWINDOW (root); + } + else + /* ROOT must be an ancestor of WINDOW. */ + { + r = decode_any_window (root); + pwindow = XWINDOW (window)->parent; + while (!NILP (pwindow)) + if (EQ (pwindow, root)) + break; + else + pwindow = XWINDOW (pwindow)->parent; + if (!EQ (pwindow, root)) + error ("Specified root is not an ancestor of specified window"); + } + + if (EQ (window, root)) + /* A noop. */ + return Qnil; + /* I don't understand the "top > 0" part below. If we deal with a + standalone minibuffer it would have been caught by the preceding + test. */ + else if (MINI_WINDOW_P (w)) /* && top > 0) */ + error ("Can't expand minibuffer to full frame"); + + if (!NILP (w->buffer)) + { + startpos = marker_position (w->start); + top = WINDOW_TOP_EDGE_LINE (w) + - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); + /* Make sure WINDOW is the frame's selected window. */ + if (!EQ (window, FRAME_SELECTED_WINDOW (f))) + { + if (EQ (selected_frame, w->frame)) + Fselect_window (window, Qnil); + else + FRAME_SELECTED_WINDOW (f) = window; + } + } + else + { + /* See if the frame's selected window is a subwindow of WINDOW, by + finding all the selected window's parents and comparing each + one with WINDOW. If it isn't we need a new selected window for + this frame. */ + swindow = FRAME_SELECTED_WINDOW (f); + while (1) + { + pwindow = swindow; + while (!NILP (pwindow) && !EQ (window, pwindow)) + pwindow = XWINDOW (pwindow)->parent; + + if (EQ (window, pwindow)) + /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok + as the new selected window. */ + break; + else + /* Else try the previous window of SWINDOW. */ + swindow = Fprevious_window (swindow, Qlambda, Qnil); + } + + if (!EQ (swindow, FRAME_SELECTED_WINDOW (f))) + { + if (EQ (selected_frame, w->frame)) + Fselect_window (swindow, Qnil); + else + FRAME_SELECTED_WINDOW (f) = swindow; + } + } + + BLOCK_INPUT; + free_window_matrices (r); + + windows_or_buffers_changed++; + Vwindow_list = Qnil; + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + + if (NILP (w->buffer)) + { + resize_failed = 0; + /* Resize subwindows vertically. */ + XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines)); + w->top_line = r->top_line; + resize_root_window (window, delta, Qnil, Qnil); + if (resize_window_check (w, 0)) + resize_window_apply (w, 0); + else + { + resize_root_window (window, delta, Qnil, Qt); + if (resize_window_check (w, 0)) + resize_window_apply (w, 0); + else + resize_failed = 1; + } + + /* Resize subwindows horizontally. */ + if (!resize_failed) + { + w->left_col = r->left_col; + XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols)); + w->left_col = r->left_col; + resize_root_window (window, delta, Qt, Qnil); + if (resize_window_check (w, 1)) + resize_window_apply (w, 1); + else + { + resize_root_window (window, delta, Qt, Qt); + if (resize_window_check (w, 1)) + resize_window_apply (w, 1); + else + resize_failed = 1; + } + } + + if (resize_failed) + /* Play safe, if we still can ... */ + { + window = swindow; + w = XWINDOW (window); + } + } + + /* Cleanly unlink WINDOW from window-tree. */ + if (!NILP (w->prev)) + /* Get SIBLING above (on the left of) WINDOW. */ + { + sibling = w->prev; + s = XWINDOW (sibling); + s->next = w->next; + if (!NILP (s->next)) + XWINDOW (s->next)->prev = sibling; + } + else + /* Get SIBLING below (on the right of) WINDOW. */ + { + sibling = w->next; + s = XWINDOW (sibling); + s->prev = Qnil; + if (!NILP (XWINDOW (w->parent)->vchild)) + XWINDOW (w->parent)->vchild = sibling; + else + XWINDOW (w->parent)->hchild = sibling; + } + + /* Delete ROOT and all subwindows of ROOT. */ + if (!NILP (r->vchild)) + { + delete_all_subwindows (r->vchild); + r->vchild = Qnil; + } + else if (!NILP (r->hchild)) + { + delete_all_subwindows (r->hchild); + r->hchild = Qnil; + } + + replace_window (root, window, 1); + + /* Reset WINDOW's splits status. */ + w->splits = Qnil; + + /* This must become SWINDOW anyway ....... */ + if (!NILP (w->buffer) && !resize_failed) + { + /* Try to minimize scrolling, by setting the window start to the + point will cause the text at the old window start to be at the + same place on the frame. But don't try to do this if the + window start is outside the visible portion (as might happen + when the display is not current, due to typeahead). */ + new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); + if (new_top != top + && startpos >= BUF_BEGV (XBUFFER (w->buffer)) + && startpos <= BUF_ZV (XBUFFER (w->buffer))) + { + struct position pos; + struct buffer *obuf = current_buffer; + + Fset_buffer (w->buffer); + /* This computation used to temporarily move point, but that + can have unwanted side effects due to text properties. */ + pos = *vmotion (startpos, -top, w); + + set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); + w->window_end_valid = Qnil; + w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE + || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt + : Qnil); + /* We need to do this, so that the window-scroll-functions + get called. */ + w->optional_new_start = Qt; + + set_buffer_internal (obuf); + } + } + + adjust_glyphs (f); + UNBLOCK_INPUT; + + run_window_configuration_change_hook (f); + + return Qnil; +} + + DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, 0, 1, "", doc: /* Make WINDOW (or the selected window) fill its frame. @@ -3676,12 +4003,6 @@ if (NILP (Vrun_hooks)) return; - if (SELECTED_FRAME () != f) - { - record_unwind_protect (select_frame_norecord, Fselected_frame ()); - Fselect_frame (frame, Qt); - } - /* Use the right buffer. Matters when running the local hooks. */ if (current_buffer != XBUFFER (Fwindow_buffer (Qnil))) { @@ -3689,6 +4010,12 @@ Fset_buffer (Fwindow_buffer (Qnil)); } + if (SELECTED_FRAME () != f) + { + record_unwind_protect (select_frame_norecord, Fselected_frame ()); + select_frame_norecord (frame); + } + /* Look for buffer-local values. */ { Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); @@ -3699,12 +4026,12 @@ if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook, buffer))) { - int count1 = SPECPDL_INDEX (); + int count = SPECPDL_INDEX (); record_unwind_protect (select_window_norecord, Fselected_window ()); select_window_norecord (window); run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, buffer)); - unbind_to (count1, Qnil); + unbind_to (count, Qnil); } } } @@ -3713,6 +4040,16 @@ unbind_to (count, Qnil); } +DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook, + Srun_window_configuration_change_hook, 1, 1, 0, + doc: /* Run `window-configuration-change-hook' for FRAME. */) + (Lisp_Object frame) +{ + CHECK_LIVE_FRAME (frame); + run_window_configuration_change_hook (XFRAME (frame)); + return Qnil; +} + /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero means it's allowed to run hooks. See make_frame for a case where it's not allowed. KEEP_MARGINS_P non-zero means that the current @@ -4019,7 +4356,7 @@ XSETFASTINT (p->clone_number, sequence_number); /* Put new into window structure in place of window */ - replace_window (window, new); + replace_window (window, new, 1); o->next = Qnil; o->prev = Qnil; @@ -4037,6 +4374,43 @@ } +/* Make new window, have it replace WINDOW in window-tree, and make + WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only + horizontal child). */ +static void +make_parent_window (Lisp_Object window, int horflag) +{ + Lisp_Object parent; + register struct window *o, *p; + int i; + + o = XWINDOW (window); + p = allocate_window (); + for (i = 0; i < VECSIZE (struct window); ++i) + ((struct Lisp_Vector *) p)->contents[i] + = ((struct Lisp_Vector *) o)->contents[i]; + XSETWINDOW (parent, p); + + ++sequence_number; + XSETFASTINT (p->sequence_number, sequence_number); + XSETFASTINT (p->clone_number, sequence_number); + + replace_window (window, parent, 1); + + o->next = Qnil; + o->prev = Qnil; + o->parent = parent; + + p->hchild = horflag ? window : Qnil; + p->vchild = horflag ? Qnil : window; + p->start = Qnil; + p->pointm = Qnil; + p->buffer = Qnil; + p->splits = Qnil; + p->nest = Qnil; + p->window_parameters = Qnil; +} + /* Make new window from scratch. */ Lisp_Object make_window (void) @@ -4138,6 +4512,654 @@ return w->new_normal; } +/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is + non-zero) to w->new_total would result in correct heights (widths) + for window W and recursively all subwindows of W. + + Note: This function does not check any of `window-fixed-size-p', + `window-min-height' or `window-min-width'. It does check that window + sizes do not drop below one line (two columns). */ +int +resize_window_check (struct window *w, int horflag) +{ + struct window *c; + + if (!NILP (w->vchild)) + /* W is a vertical combination. */ + { + c = XWINDOW (w->vchild); + if (horflag) + /* All subwindows of W must have the same width as W. */ + { + while (c) + { + if ((XINT (c->new_total) != XINT (w->new_total)) + || !resize_window_check (c, horflag)) + return 0; + c = NILP (c->next) ? 0 : XWINDOW (c->next); + } + return 1; + } + else + /* The sum of the heights of the subwindows of W must equal W's + height. */ + { + int sum_of_sizes = 0; + while (c) + { + if (!resize_window_check (c, horflag)) + return 0; + sum_of_sizes = sum_of_sizes + XINT (c->new_total); + c = NILP (c->next) ? 0 : XWINDOW (c->next); + } + return (sum_of_sizes == XINT (w->new_total)); + } + } + else if (!NILP (w->hchild)) + /* W is a horizontal combination. */ + { + c = XWINDOW (w->hchild); + if (horflag) + /* The sum of the widths of the subwindows of W must equal W's + width. */ + { + int sum_of_sizes = 0; + while (c) + { + if (!resize_window_check (c, horflag)) + return 0; + sum_of_sizes = sum_of_sizes + XINT (c->new_total); + c = NILP (c->next) ? 0 : XWINDOW (c->next); + } + return (sum_of_sizes == XINT (w->new_total)); + } + else + /* All subwindows of W must have the same height as W. */ + { + while (c) + { + if ((XINT (c->new_total) != XINT (w->new_total)) + || !resize_window_check (c, horflag)) + return 0; + c = NILP (c->next) ? 0 : XWINDOW (c->next); + } + return 1; + } + } + else + /* A leaf window. Make sure it's not too small. The following + hardcodes the values of `window-safe-min-width' (2) and + `window-safe-min-height' (1) which are defined in window.el. */ + return XINT (w->new_total) >= (horflag ? 2 : 1); +} + +/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to + w->new_total for window W and recursively all subwindows of W. Also + calculate and assign the new vertical (horizontal) start positions of + each of these windows. + + This function does not perform any error checks. Make sure you have + run resize_window_check on W before applying this function. */ +void +resize_window_apply (struct window *w, int horflag) +{ + struct window *c, *p; + int pos; + + /* Note: Assigning new_normal requires that the new total size of the + parent window has been set *before*. */ + if (horflag) + { + w->total_cols = w->new_total; + if (NUMBERP (w->new_normal)) + w->normal_cols = w->new_normal; + + pos = XINT (w->left_col); + } + else + { + w->total_lines = w->new_total; + if (NUMBERP (w->new_normal)) + w->normal_lines = w->new_normal; + + pos = XINT (w->top_line); + } + + if (!NILP (w->vchild)) + /* W is a vertical combination. */ + { + c = XWINDOW (w->vchild); + while (c) + { + if (horflag) + XSETFASTINT (c->left_col, pos); + else + XSETFASTINT (c->top_line, pos); + resize_window_apply (c, horflag); + if (!horflag) + pos = pos + XINT (c->total_lines); + c = NILP (c->next) ? 0 : XWINDOW (c->next); + } + } + else if (!NILP (w->hchild)) + /* W is a horizontal combination. */ + { + c = XWINDOW (w->hchild); + while (c) + { + if (horflag) + XSETFASTINT (c->left_col, pos); + else + XSETFASTINT (c->top_line, pos); + resize_window_apply (c, horflag); + if (horflag) + pos = pos + XINT (c->total_cols); + c = NILP (c->next) ? 0 : XWINDOW (c->next); + } + } + + /* Clear out some redisplay caches. */ + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); +} + + +DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0, + doc: /* Apply requested size values for window-tree of FRAME. +Optional argument HORIZONTAL omitted or nil means apply requested height +values. HORIZONTAL non-nil means apply requested width values. + +This function checks whether the requested values sum up to a valid +window layout, recursively assigns the new sizes of all subwindows and +calculates and assigns the new start positions of these windows. + +Note: This function does not check any of `window-fixed-size-p', +`window-min-height' or `window-min-width'. All these checks have to +be applied on the Elisp level. */) + (Lisp_Object frame, Lisp_Object horizontal) +{ + struct frame *f; + struct window *r; + int horflag = !NILP (horizontal); + + if (NILP (frame)) + frame = selected_frame; + CHECK_LIVE_FRAME (frame); + + f = XFRAME (frame); + r = XWINDOW (FRAME_ROOT_WINDOW (f)); + + if (!resize_window_check (r, horflag) + || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines))) + return Qnil; + + BLOCK_INPUT; + resize_window_apply (r, horflag); + + windows_or_buffers_changed++; + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + + adjust_glyphs (f); + UNBLOCK_INPUT; + + run_window_configuration_change_hook (f); + + return Qt; +} + + +/* Resize frame F's windows when number of lines of F is set to SIZE. + HORFLAG 1 means resize windows when number of columns of F is set to + SIZE. + + This function can delete all windows but the selected one in order to + satisfy the request. The result will be meaningful if and only if + F's windows have meaningful sizes when you call this. */ +void +resize_frame_windows (struct frame *f, int size, int horflag) +{ + Lisp_Object root = f->root_window; + struct window *r = XWINDOW (root); + Lisp_Object mini = f->minibuffer_window; + struct window *m; + /* new_size is the new size of the frame's root window. */ + int new_size = (horflag + ? size + : (size + - FRAME_TOP_MARGIN (f) + - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) + ? 1 : 0))); + + XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f)); + if (NILP (r->vchild) && NILP (r->hchild)) + /* For a leaf root window just set the size. */ + if (horflag) + XSETFASTINT (r->total_cols, new_size); + else + XSETFASTINT (r->total_lines, new_size); + else + { + /* old_size is the old size of the frame's root window. */ + int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines); + Lisp_Object delta; + + XSETINT (delta, new_size - old_size); + /* Try a "normal" resize first. */ + resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil); + if (resize_window_check (r, horflag) && new_size == XINT (r->new_total)) + resize_window_apply (r, horflag); + else + { + /* Try with "reasonable" minimum sizes next. */ + resize_root_window (root, delta, horflag ? Qt : Qnil, Qt); + if (resize_window_check (r, horflag) + && new_size == XINT (r->new_total)) + resize_window_apply (r, horflag); + else + { + /* Finally, try with "safe" minimum sizes. */ + resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe); + if (resize_window_check (r, horflag) + && new_size == XINT (r->new_total)) + resize_window_apply (r, horflag); + else + { + /* We lost. Delete all windows but the frame's + selected one. */ + root = f->selected_window; + Fdelete_other_windows_internal (root, Qnil); + if (horflag) + XSETFASTINT (XWINDOW (root)->total_cols, new_size); + else + XSETFASTINT (XWINDOW (root)->total_lines, new_size); + } + } + } + } + + if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) + { + m = XWINDOW (mini); + if (horflag) + XSETFASTINT (m->total_cols, size); + else + { + /* Are we sure we always want 1 line here? */ + XSETFASTINT (m->total_lines, 1); + XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines)); + } + } +} + + +DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, + doc: /* Split window OLD. +Second argument TOTAL-SIZE specifies the number of lines or columns of the +new window. In any case TOTAL-SIZE must be a positive integer + +Third argument SIDE nil (or `below') specifies that the new window shall +be located below WINDOW. SIDE `above' means the new window shall be +located above WINDOW. In both cases TOTAL-SIZE specifies the number of +lines of the new window including space reserved for the mode and/or +header line. + +SIDE t (or `right') specifies that the new window shall be located on +the right side of WINDOW. SIDE `left' means the new window shall be +located on the left of WINDOW. In both cases TOTAL-SIZE specifies the +number of columns of the new window including space reserved for fringes +and the scrollbar or a divider column. + +Fourth argument NORMAL-SIZE specifies the normal size of the new window +according to the SIDE argument. + +The new total and normal sizes of all involved windows must have been +set correctly. See the code of `split-window' for how this is done. */) + (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size) +{ + /* OLD (*o) is the window we have to split. (*p) is either OLD's + parent window or an internal window we have to install as OLD's new + parent. REFERENCE (*r) must denote a live window, or is set to OLD + provided OLD is a leaf window, or to the frame's selected window. + NEW (*n) is the new window created with some parameters taken from + REFERENCE (*r). */ + register Lisp_Object new, frame, reference; + register struct window *o, *p, *n, *r; + struct frame *f; + int horflag + /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ + = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); + int do_nest = 0; + + CHECK_WINDOW (old); + o = XWINDOW (old); + frame = WINDOW_FRAME (o); + f = XFRAME (frame); + + CHECK_NUMBER (total_size); + + /* Set do_nest to 1 if we have to make a new parent window. We do + that if either `window-nest' is non-nil, or OLD has no parent, or + OLD is ortho-combined. */ + do_nest = + !NILP (Vwindow_nest) + || NILP (o->parent) + || NILP (horflag + ? (XWINDOW (o->parent)->hchild) + : (XWINDOW (o->parent)->vchild)); + + /* We need a live reference window to initialize some parameters. */ + if (WINDOW_LIVE_P (old)) + /* OLD is live, use it as reference window. */ + reference = old; + else + /* Use the frame's selected window as reference window. */ + reference = FRAME_SELECTED_WINDOW (f); + r = XWINDOW (reference); + + /* The following bugs are caught by `split-window'. */ + if (MINI_WINDOW_P (o)) + error ("Attempt to split minibuffer window"); + else if (XINT (total_size) < (horflag ? 2 : 1)) + error ("Size of new window too small (after split)"); + else if (!do_nest && !NILP (Vwindow_splits)) + /* `window-splits' non-nil means try to resize OLD's siblings + proportionally. */ + { + p = XWINDOW (o->parent); + /* Temporarily pretend we split the parent window. */ + XSETINT (p->new_total, + XINT (horflag ? p->total_cols : p->total_lines) + - XINT (total_size)); + if (!resize_window_check (p, horflag)) + error ("Window sizes don't fit"); + else + /* Undo the temporary pretension. */ + p->new_total = horflag ? p->total_cols : p->total_lines; + } + else + { + if (!resize_window_check (o, horflag)) + error ("Resizing old window failed"); + else if (XINT (total_size) + XINT (o->new_total) + != XINT (horflag ? o->total_cols : o->total_lines)) + error ("Sum of sizes of old and new window don't fit"); + } + + /* This is our point of no return. */ + if (do_nest) + { + /* Save the old value of o->normal_cols/lines. It gets corrupted + by make_parent_window and we need it below for assigning it to + p->new_normal. */ + Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines; + + make_parent_window (old, horflag); + p = XWINDOW (o->parent); + /* Store value of `window-nest' in new parent's nest slot. */ + p->nest = Vwindow_nest; + /* Have PARENT inherit splits slot value from OLD. */ + p->splits = o->splits; + /* Store value of `window-splits' in OLD's splits slot. */ + o->splits = Vwindow_splits; + /* These get applied below. */ + p->new_total = horflag ? o->total_cols : o->total_lines; + p->new_normal = new_normal; + } + else + p = XWINDOW (o->parent); + + windows_or_buffers_changed++; + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + new = make_window (); + n = XWINDOW (new); + n->frame = frame; + n->parent = o->parent; + n->vchild = n->hchild = Qnil; + + if (EQ (side, Qabove) || EQ (side, Qleft)) + { + n->prev = o->prev; + if (NILP (n->prev)) + if (horflag) + p->hchild = new; + else + p->vchild = new; + else + XWINDOW (n->prev)->next = new; + n->next = old; + o->prev = new; + } + else + { + n->next = o->next; + if (!NILP (n->next)) + XWINDOW (n->next)->prev = new; + n->prev = old; + o->next = new; + } + + n->buffer = Qt; + n->window_end_valid = Qnil; + memset (&n->last_cursor, 0, sizeof n->last_cursor); + + /* Get special geometry settings from reference window. */ + n->left_margin_cols = r->left_margin_cols; + n->right_margin_cols = r->right_margin_cols; + n->left_fringe_width = r->left_fringe_width; + n->right_fringe_width = r->right_fringe_width; + n->fringes_outside_margins = r->fringes_outside_margins; + n->scroll_bar_width = r->scroll_bar_width; + n->vertical_scroll_bar_type = r->vertical_scroll_bar_type; + + /* Store `window-splits' in NEW's splits slot. */ + n->splits = Vwindow_splits; + + /* Directly assign orthogonal coordinates and sizes. */ + if (horflag) + { + n->top_line = o->top_line; + n->total_lines = o->total_lines; + } + else + { + n->left_col = o->left_col; + n->total_cols = o->total_cols; + } + + /* Iso-coordinates and sizes are assigned by resize_window_apply, + get them ready here. */ + n->new_total = total_size; + n->new_normal = normal_size; + + BLOCK_INPUT; + resize_window_apply (p, horflag); + adjust_glyphs (f); + /* Set buffer of NEW to buffer of reference window. Don't run + any hooks. */ + set_window_buffer (new, r->buffer, 0, 1); + UNBLOCK_INPUT; + + /* Maybe we should run the scroll functions in Elisp (which already + runs the configuration change hook). */ + if (! NILP (Vwindow_scroll_functions)) + run_hook_with_args_2 (Qwindow_scroll_functions, new, + Fmarker_position (n->start)); + /* Return NEW. */ + return new; +} + + +DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0, + doc: /* Remove WINDOW from its frame. +WINDOW defaults to the selected window. Return nil. Signal an error +when WINDOW is the only window on its frame. */) + (register Lisp_Object window) +{ + register Lisp_Object parent, sibling, frame, root; + struct window *w, *p, *s, *r; + struct frame *f; + int horflag; + int before_sibling = 0; + + w = decode_any_window (window); + XSETWINDOW (window, w); + if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild)) + /* It's a no-op to delete an already deleted window. */ + return Qnil; + + parent = w->parent; + if (NILP (parent)) + /* Never delete a minibuffer or frame root window. */ + error ("Attempt to delete minibuffer or sole ordinary window"); + else if (NILP (w->prev) && NILP (w->next)) + /* Rather bow out here, this case should be handled on the Elisp + level. */ + error ("Attempt to delete sole window of parent"); + + p = XWINDOW (parent); + horflag = NILP (p->vchild); + + frame = WINDOW_FRAME (w); + f = XFRAME (frame); + + root = FRAME_ROOT_WINDOW (f); + r = XWINDOW (root); + + /* Unlink WINDOW from window tree. */ + if (NILP (w->prev)) + /* Get SIBLING below (on the right of) WINDOW. */ + { + /* before_sibling 1 means WINDOW is the first child of its + parent and thus before the sibling. */ + before_sibling = 1; + sibling = w->next; + s = XWINDOW (sibling); + s->prev = Qnil; + if (horflag) + p->hchild = sibling; + else + p->vchild = sibling; + } + else + /* Get SIBLING above (on the left of) WINDOW. */ + { + sibling = w->prev; + s = XWINDOW (sibling); + s->next = w->next; + if (!NILP (s->next)) + XWINDOW (s->next)->prev = sibling; + } + + if (resize_window_check (r, horflag) + && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines))) + /* We can delete WINDOW now. */ + { + /* Block input. */ + BLOCK_INPUT; + resize_window_apply (p, horflag); + + windows_or_buffers_changed++; + Vwindow_list = Qnil; + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + + w->next = Qnil; /* Don't delete w->next too. */ + free_window_matrices (w); + + if (!NILP (w->vchild)) + { + delete_all_subwindows (w->vchild); + w->vchild = Qnil; + } + else if (!NILP (w->hchild)) + { + delete_all_subwindows (w->hchild); + w->hchild = Qnil; + } + else if (!NILP (w->buffer)) + { + unshow_buffer (w); + unchain_marker (XMARKER (w->pointm)); + unchain_marker (XMARKER (w->start)); + w->buffer = Qnil; + } + + if (NILP (s->prev) && NILP (s->next)) + /* A matrjoshka where SIBLING has become the only child of + PARENT. */ + { + /* Put SIBLING into PARENT's place. */ + replace_window (parent, sibling, 0); + /* Have SIBLING inherit the following three slot values from + PARENT (the nest slot is not inherited). */ + s->normal_cols = p->normal_cols; + s->normal_lines = p->normal_lines; + s->splits = p->splits; + /* Mark PARENT as deleted. */ + p->vchild = p->hchild = Qnil; + /* Try to merge SIBLING into its new parent. */ + recombine_windows (sibling); + } + + adjust_glyphs (f); + + if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f))) + /* We deleted the frame's selected window. */ + { + /* Use the frame's first window as fallback ... */ + Lisp_Object new_selected_window = Fframe_first_window (frame); + /* ... but preferably use its most recently used window. */ + Lisp_Object mru_window; + + /* `get-mru-window' might fail for some reason so play it safe + - promote the first window _without recording it_ first. */ + if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) + Fselect_window (new_selected_window, Qt); + else + FRAME_SELECTED_WINDOW (f) = new_selected_window; + + UNBLOCK_INPUT; + + /* Now look whether `get-mru-window' gets us something. */ + mru_window = call1 (Qget_mru_window, frame); + if (WINDOW_LIVE_P (mru_window) + && EQ (XWINDOW (mru_window)->frame, frame)) + new_selected_window = mru_window; + + /* If all ended up well, we now promote the mru window. */ + if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) + Fselect_window (new_selected_window, Qnil); + else + FRAME_SELECTED_WINDOW (f) = new_selected_window; + } + else + UNBLOCK_INPUT; + + /* Must be run by the caller: + run_window_configuration_change_hook (f); */ + } + else + /* We failed: Relink WINDOW into window tree. */ + { + if (before_sibling) + { + s->prev = window; + if (horflag) + p->hchild = window; + else + p->vchild = window; + } + else + { + s->next = window; + if (!NILP (w->next)) + XWINDOW (w->next)->prev = window; + } + error ("Deletion failed"); + } + + return Qnil; +} + DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", doc: /* Split WINDOW, putting SIZE lines in the first of the pair. WINDOW defaults to selected one and SIZE to half its size. @@ -4279,6 +5301,46 @@ Fset_window_buffer (new, o->buffer, Qt); return new; } + +DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0, + doc: /* Resize minibuffer window WINDOW. */) + (Lisp_Object window) +{ + struct window *w = XWINDOW (window); + struct window *r; + struct frame *f; + int height; + + CHECK_WINDOW (window); + f = XFRAME (w->frame); + + if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window)) + error ("Not a valid minibuffer window"); + else if (FRAME_MINIBUF_ONLY_P (f)) + error ("Cannot resize a minibuffer-only frame"); + + r = XWINDOW (FRAME_ROOT_WINDOW (f)); + height = XINT (r->total_lines) + XINT (w->total_lines); + if (resize_window_check (r, 0) + && XINT (w->new_total) > 0 + && height == XINT (r->new_total) + XINT (w->new_total)) + { + BLOCK_INPUT; + resize_window_apply (r, 0); + + w->total_lines = w->new_total; + XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines)); + + windows_or_buffers_changed++; + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + adjust_glyphs (f); + UNBLOCK_INPUT; + + run_window_configuration_change_hook (f); + return Qt; + } + else error ("Failed to resize minibuffer window"); +} DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", doc: /* Make selected window SIZE lines taller. @@ -7527,6 +8589,41 @@ frame to be redrawn only if it is a tty frame. */); Vrecenter_redisplay = Qtty; + DEFVAR_LISP ("window-splits", Vwindow_splits, + doc: /* Non-nil means splitting windows is handled specially. +If this variable is nil, splitting a window gets the entire screen space +for displaying the new window from the window to split. If this +variable is non-nil, splitting a window may resize all windows in the +same combination. This also allows to split a window that is otherwise +too small or of fixed size. + +The value of this variable is also assigned to the split status of the +new window and, provided the old and new window form a new combination, +to the window that was split as well. The split status of a window can +be retrieved with the function `window-splits' and altered by the +function `set-window-splits'. + +If the value of the variable `window-nest' is non-nil, the space for the +new window is exclusively taken from the window that shall be split, but +the split status of the window that is split as well as that of the new +window are still set to the value of this variable. */); + Vwindow_splits = Qnil; + + DEFVAR_LISP ("window-nest", Vwindow_nest, + doc: /* Non-nil means 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 it is part of. + +If this variable is non-nil, 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 nest status of the +new parent window. The nest status of a window can be retrieved via the +function `window-nest' and altered by the function `set-window-nest'. */); + Vwindow_nest = Qnil; defsubr (&Sselected_window); defsubr (&Sminibuffer_window); @@ -7560,6 +8657,7 @@ defsubr (&Swindow_new_normal); defsubr (&Sset_window_new_total); defsubr (&Sset_window_new_normal); + defsubr (&Sresize_window_apply); defsubr (&Swindow_body_size); defsubr (&Swindow_hscroll); defsubr (&Sset_window_hscroll); @@ -7590,12 +8688,17 @@ defsubr (&Sdelete_windows_on); defsubr (&Sreplace_buffer_in_windows); defsubr (&Sdelete_window); + defsubr (&Sdelete_other_windows_internal); + defsubr (&Sdelete_window_internal); + defsubr (&Sresize_mini_window_internal); defsubr (&Sset_window_buffer); defsubr (&Sset_window_clone_number); + defsubr (&Srun_window_configuration_change_hook); defsubr (&Sselect_window); defsubr (&Sforce_window_update); defsubr (&Stemp_output_buffer_show); defsubr (&Ssplit_window); + defsubr (&Ssplit_window_internal); defsubr (&Senlarge_window); defsubr (&Sshrink_window); defsubr (&Sadjust_window_trailing_edge);