X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c32cc606df56d6dd7b394c32b2d5599f12dfd20e..5deebc3c914c86e84d11661a7877c00b2d7fddd1:/lisp/window.el diff --git a/lisp/window.el b/lisp/window.el index e4669c1f6e..a0bdfeb672 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -1889,9 +1889,19 @@ the font." (ncols (/ window-width font-width))) (if (and (display-graphic-p) overflow-newline-into-fringe - (/= (frame-parameter nil 'left-fringe) 0) - (/= (frame-parameter nil 'right-fringe) 0)) + (not + (or (eq left-fringe-width 0) + (and (null left-fringe-width) + (= (frame-parameter nil 'left-fringe) 0)))) + (not + (or (eq right-fringe-width 0) + (and (null right-fringe-width) + (= (frame-parameter nil 'right-fringe) 0))))) ncols + ;; FIXME: This should remove 1 more column when there are no + ;; fringes, lines are truncated, and the window is hscrolled, + ;; but EOL is not in the view, because then there are 2 + ;; truncation glyphs, not one. (1- ncols))))) (defun window-current-scroll-bars (&optional window) @@ -2473,8 +2483,6 @@ windows." (when (window-right window) (window--resize-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 window--resize-mini-window (window delta) "Resize minibuffer window WINDOW by DELTA pixels. If WINDOW cannot be resized by DELTA pixels make it as large (or @@ -3241,9 +3249,9 @@ move it as far as possible in the desired direction." (setq ignore 'preserved) (setq right first-right) (while (and right - (or (window-size-fixed-p right horizontal 'preserved)) - (<= (window-size right horizontal t) - (window-min-size right horizontal 'preserved t))) + (or (window-size-fixed-p right horizontal 'preserved) + (<= (window-size right horizontal t) + (window-min-size right horizontal 'preserved t)))) (setq right (or (window-right right) (progn @@ -3338,20 +3346,29 @@ negative, shrink selected window by -DELTA lines or columns." (cond ((zerop delta)) ((window-size-fixed-p nil horizontal) - (error "Selected window has fixed size")) + (user-error "Selected window has fixed size")) ((window-minibuffer-p) (if horizontal - (error "Cannot resize minibuffer window horizontally") - (window--resize-mini-window (selected-window) delta))) + (user-error "Cannot resize minibuffer window horizontally") + (window--resize-mini-window + (selected-window) (* delta (frame-char-height))))) ((and (not horizontal) (window-full-height-p) (eq (window-frame minibuffer-window) (selected-frame)) (not resize-mini-windows)) ;; If the selected window is full height and `resize-mini-windows' ;; is nil, resize the minibuffer window. - (window--resize-mini-window minibuffer-window (- delta))) + (window--resize-mini-window + minibuffer-window (* (- delta) (frame-char-height)))) ((window--resizable-p nil delta horizontal) (window-resize nil delta horizontal)) + ((window--resizable-p nil delta horizontal 'preserved) + (window-resize nil delta horizontal 'preserved)) + ((eq this-command + (if horizontal 'enlarge-window-horizontally 'enlarge-window)) + ;; For backward compatibility don't signal an error unless this + ;; command is `enlarge-window(-horizontally)'. + (user-error "Cannot enlarge selected window")) (t (window-resize nil (if (> delta 0) @@ -3364,8 +3381,7 @@ negative, shrink selected window by -DELTA lines or columns." 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. -Also see the `window-min-height' variable." +negative, enlarge selected window by -DELTA lines or columns." (interactive "p") (let ((minibuffer-window (minibuffer-window))) (when (window-preserved-size nil horizontal) @@ -3373,20 +3389,29 @@ Also see the `window-min-height' variable." (cond ((zerop delta)) ((window-size-fixed-p nil horizontal) - (error "Selected window has fixed size")) + (user-error "Selected window has fixed size")) ((window-minibuffer-p) (if horizontal - (error "Cannot resize minibuffer window horizontally") - (window--resize-mini-window (selected-window) (- delta)))) + (user-error "Cannot resize minibuffer window horizontally") + (window--resize-mini-window + (selected-window) (* (- delta) (frame-char-height))))) ((and (not horizontal) (window-full-height-p) (eq (window-frame minibuffer-window) (selected-frame)) (not resize-mini-windows)) ;; If the selected window is full height and `resize-mini-windows' ;; is nil, resize the minibuffer window. - (window--resize-mini-window minibuffer-window delta)) + (window--resize-mini-window + minibuffer-window (* delta (frame-char-height)))) ((window--resizable-p nil (- delta) horizontal) (window-resize nil (- delta) horizontal)) + ((window--resizable-p nil (- delta) horizontal 'preserved) + (window-resize nil (- delta) horizontal 'preserved)) + ((eq this-command + (if horizontal 'shrink-window-horizontally 'shrink-window)) + ;; For backward compatibility don't signal an error unless this + ;; command is `shrink-window(-horizontally)'. + (user-error "Cannot shrink selected window")) (t (window-resize nil (if (> delta 0) @@ -6721,6 +6746,71 @@ that frame." (unless (cdr (assq 'inhibit-switch-frame alist)) (window--maybe-raise-frame (window-frame window))))))) +(defun display-buffer-reuse-mode-window (buffer alist) + "Return a window based on the mode of the buffer it displays. +Display BUFFER in the returned window. Return nil if no usable +window is found. + +If ALIST contains a `mode' entry, its value is a major mode (a +symbol) or a list of modes. A window is a candidate if it +displays a buffer that derives from one of the given modes. When +ALIST contains no `mode' entry, the current major mode of BUFFER +is used. + +The behaviour is also controlled by entries for +`inhibit-same-window', `reusable-frames' and +`inhibit-switch-frame' as is done in the function +`display-buffer-reuse-window'." + (let* ((alist-entry (assq 'reusable-frames alist)) + (alist-mode-entry (assq 'mode alist)) + (frames (cond (alist-entry (cdr alist-entry)) + ((if (eq pop-up-frames 'graphic-only) + (display-graphic-p) + pop-up-frames) + 0) + (display-buffer-reuse-frames 0) + (t (last-nonminibuffer-frame)))) + (inhibit-same-window-p (cdr (assq 'inhibit-same-window alist))) + (windows (window-list-1 nil 'nomini frames)) + (buffer-mode (with-current-buffer buffer major-mode)) + (allowed-modes (if alist-mode-entry + (cdr alist-mode-entry) + buffer-mode)) + (curwin (selected-window)) + (curframe (selected-frame))) + (unless (listp allowed-modes) + (setq allowed-modes (list allowed-modes))) + (let (same-mode-same-frame + same-mode-other-frame + derived-mode-same-frame + derived-mode-other-frame) + (dolist (window windows) + (let (mode? frame?) + (with-current-buffer (window-buffer window) + (setq mode? + (cond ((memq major-mode allowed-modes) + 'same) + ((derived-mode-p allowed-modes) + 'derived)))) + (when (and mode? + (not (and inhibit-same-window-p + (eq window curwin)))) + (if (eq curframe (window-frame window)) + (if (eq mode? 'same) + (push window same-mode-same-frame) + (push window derived-mode-same-frame)) + (if (eq mode? 'same) + (push window same-mode-other-frame) + (push window derived-mode-other-frame)))))) + (let ((window (car (nconc same-mode-same-frame + same-mode-other-frame + derived-mode-same-frame + derived-mode-other-frame)))) + (when (window-live-p window) + (prog1 (window--display-buffer buffer window 'reuse alist) + (unless (cdr (assq 'inhibit-switch-frame alist)) + (window--maybe-raise-frame (window-frame window))))))))) + (defun display-buffer--special-action (buffer) "Return special display action for BUFFER, if any. If `special-display-p' returns non-nil for BUFFER, return an @@ -7057,7 +7147,7 @@ buffer with the name BUFFER-OR-NAME and return that buffer." buffer)) (other-buffer))) -(defcustom switch-to-buffer-preserve-window-point nil +(defcustom switch-to-buffer-preserve-window-point t "If non-nil, `switch-to-buffer' tries to preserve `window-point'. If this is nil, `switch-to-buffer' displays the buffer at that buffer's `point'. If this is `already-displayed', it tries to @@ -7075,7 +7165,7 @@ the selected window or never appeared in it before, or if (const :tag "If already displayed elsewhere" already-displayed) (const :tag "Always" t)) :group 'windows - :version "24.3") + :version "25.2") (defcustom switch-to-buffer-in-dedicated-window nil "Allow switching to buffer in strongly dedicated windows. @@ -8470,10 +8560,10 @@ WINDOWS is a list of windows associated with PROCESS. REDUCER is a two-argument function used to combine the widths and heights of the given windows." (when windows - (let ((width (window-body-width (car windows))) + (let ((width (window-max-chars-per-line (car windows))) (height (window-body-height (car windows)))) (dolist (window (cdr windows)) - (setf width (funcall reducer width (window-body-width window))) + (setf width (funcall reducer width (window-max-chars-per-line window))) (setf height (funcall reducer height (window-body-height window)))) (cons width height)))) @@ -8495,38 +8585,40 @@ A window is associated with a process if that window is displaying that processes's buffer." (let ((processes (process-list)) (process-windows nil)) - (walk-windows - (lambda (window) - (let ((buffer (window-buffer window)) - (iter processes)) - (while (let ((process (car iter))) - (if (and (process-live-p process) - (eq buffer (process-buffer process))) - (let ((procwin (assq process process-windows))) - ;; Add this window to the list of windows - ;; displaying process. - (if procwin - (push window (cdr procwin)) - (push (list process window) process-windows)) - ;; We found our process for this window, so - ;; stop iterating over the process list. - nil) - (setf iter (cdr iter))))))) - 1 t) + (if processes + (walk-windows + (lambda (window) + (let ((buffer (window-buffer window)) + (iter processes)) + (while (let ((process (car iter))) + (if (and (process-live-p process) + (eq buffer (process-buffer process))) + (let ((procwin (assq process process-windows))) + ;; Add this window to the list of windows + ;; displaying process. + (if procwin + (push window (cdr procwin)) + (push (list process window) process-windows)) + ;; We found our process for this window, so + ;; stop iterating over the process list. + nil) + (setf iter (cdr iter))))))) + 1 t)) process-windows)) (defun window--adjust-process-windows () "Update process window sizes to match the current window configuration." - (dolist (procwin (window--process-window-list)) - (let ((process (car procwin))) - (with-demoted-errors "Error adjusting window size: %S" - (with-current-buffer (process-buffer process) - (let ((size (funcall - (or (process-get process 'adjust-window-size-function) - window-adjust-process-window-size-function) - process (cdr procwin)))) - (when size - (set-process-window-size process (cdr size) (car size))))))))) + (when (fboundp 'process-list) + (dolist (procwin (window--process-window-list)) + (let ((process (car procwin))) + (with-demoted-errors "Error adjusting window size: %S" + (with-current-buffer (process-buffer process) + (let ((size (funcall + (or (process-get process 'adjust-window-size-function) + window-adjust-process-window-size-function) + process (cdr procwin)))) + (when size + (set-process-window-size process (cdr size) (car size)))))))))) (add-hook 'window-configuration-change-hook 'window--adjust-process-windows)