]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix display-buffer-override-next-command for no-select case (bug#49057)
authorJuri Linkov <juri@linkov.net>
Thu, 17 Jun 2021 19:53:57 +0000 (22:53 +0300)
committerJuri Linkov <juri@linkov.net>
Thu, 17 Jun 2021 19:53:57 +0000 (22:53 +0300)
* lisp/window.el (display-buffer-override-next-command):
Separate 'postfun' from 'clearfun', so 'clearfun' resets
'display-buffer-overriding-action', whereas 'postfun' calls
'post-function' that can select the right window in 'post-command-hook'.

* lisp/windmove.el (windmove-display-no-select): Add new choice 'ignore'.
Improve docstring.
(windmove-display-in-direction): Use new value 'ignore' of
'windmove-display-no-select'.  Improve docstring.
(windmove-display-left, windmove-display-up)
(windmove-display-right, windmove-display-down): Mention
'windmove-display-no-select' in docstrings.

lisp/windmove.el
lisp/window.el

index 3c1f20aa260179ffb6d72c09a58f045cbdeb9972..f747c409431bf9cb538857ed1a948f530a80f36c 100644 (file)
@@ -497,8 +497,20 @@ Default value of MODIFIERS is `shift'."
 ;;; Directional window display and selection
 
 (defcustom windmove-display-no-select nil
-  "Whether the window should be selected after displaying the buffer in it."
-  :type 'boolean
+  "Whether the window should be selected after displaying the buffer in it.
+If `nil', then the new window where the buffer is displayed will be selected.
+If `ignore', then don't select a window: neither the new nor the old window,
+thus allowing the next command to decide what window it selects.
+Other non-nil values will reselect the old window that was selected before.
+
+The value of this variable can be overridden by the prefix arg of the
+windmove-display-* commands that use `windmove-display-in-direction'.
+
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
+  :type '(choice (const :tag "Select new window" nil)
+                 (const :tag "Select old window" t)
+                 (const :tag "Don't select a window" ignore))
   :version "27.1")
 
 (defun windmove-display-in-direction (dir &optional arg)
@@ -506,11 +518,17 @@ Default value of MODIFIERS is `shift'."
 The next buffer is the buffer displayed by the next command invoked
 immediately after this command (ignoring reading from the minibuffer).
 Create a new window if there is no window in that direction.
-By default, select the window with a displayed buffer.
-If prefix ARG is `C-u', reselect a previously selected window.
-If `windmove-display-no-select' is non-nil, this command doesn't
-select the window with a displayed buffer, and the meaning of
-the prefix argument is reversed.
+
+By default, select the new window with a displayed buffer.
+If `windmove-display-no-select' is `ignore', then allow the next command
+to decide what window it selects.  With other non-nil values of
+`windmove-display-no-select', this function reselects
+a previously selected old window.
+
+If prefix ARG is `C-u', reselect a previously selected old window.
+If `windmove-display-no-select' is non-nil, the meaning of
+the prefix argument is reversed and it selects the new window.
+
 When `switch-to-buffer-obey-display-actions' is non-nil,
 `switch-to-buffer' commands are also supported."
   (let ((no-select (xor (consp arg) windmove-display-no-select)))
@@ -542,35 +560,40 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
            (setq window (split-window nil nil dir) type 'window))
          (cons window type)))
      (lambda (old-window new-window)
-       (when (window-live-p (if no-select old-window new-window))
+       (when (and (not (eq windmove-display-no-select 'ignore))
+                  (window-live-p (if no-select old-window new-window)))
          (select-window (if no-select old-window new-window))))
      (format "[display-%s]" dir))))
 
 ;;;###autoload
 (defun windmove-display-left (&optional arg)
   "Display the next buffer in window to the left of the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'left arg))
 
 ;;;###autoload
 (defun windmove-display-up (&optional arg)
   "Display the next buffer in window above the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'up arg))
 
 ;;;###autoload
 (defun windmove-display-right (&optional arg)
   "Display the next buffer in window to the right of the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'right arg))
 
 ;;;###autoload
 (defun windmove-display-down (&optional arg)
   "Display the next buffer in window below the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'down arg))
 
index 6afc519e2881edb20a8fe49a9b2f9b498e3f5f18..c0511bec4c49c03b1bc3ae3086428190d636e9c6 100644 (file)
@@ -8768,6 +8768,7 @@ to deactivate this overriding action."
          (new-window nil)
          (minibuffer-depth (minibuffer-depth))
          (clearfun (make-symbol "clear-display-buffer-overriding-action"))
+         (postfun (make-symbol "post-display-buffer-override-next-command"))
          (action (lambda (buffer alist)
                    (unless (> (minibuffer-depth) minibuffer-depth)
                      (let* ((ret (funcall pre-function buffer alist))
@@ -8776,21 +8777,23 @@ to deactivate this overriding action."
                        (setq new-window (window--display-buffer buffer window
                                                                 type alist))
                        ;; Reset display-buffer-overriding-action
-                       ;; after the first buffer display action
+                       ;; after the first display-buffer action (bug#39722).
                        (funcall clearfun)
-                       (setq post-function nil)
                        new-window))))
          (command this-command)
          (echofun (when echo (lambda () echo)))
          (exitfun
           (lambda ()
-            (setcar display-buffer-overriding-action
-                    (delq action (car display-buffer-overriding-action)))
-            (remove-hook 'post-command-hook clearfun)
+            (funcall clearfun)
+            (remove-hook 'post-command-hook postfun)
             (remove-hook 'prefix-command-echo-keystrokes-functions echofun)
             (when (functionp post-function)
               (funcall post-function old-window new-window)))))
     (fset clearfun
+          (lambda ()
+            (setcar display-buffer-overriding-action
+                    (delq action (car display-buffer-overriding-action)))))
+    (fset postfun
           (lambda ()
             (unless (or
                     ;; Remove the hook immediately
@@ -8800,9 +8803,8 @@ to deactivate this overriding action."
                     ;; adding the hook by the same command below.
                     (eq this-command command))
               (funcall exitfun))))
-    ;; Reset display-buffer-overriding-action
-    ;; after the next command finishes
-    (add-hook 'post-command-hook clearfun)
+    ;; Call post-function after the next command finishes (bug#49057).
+    (add-hook 'post-command-hook postfun)
     (when echofun
       (add-hook 'prefix-command-echo-keystrokes-functions echofun))
     (push action (car display-buffer-overriding-action))