Subject: bug#44932: 28.0.50; MINIBUF 'nomini' for window-in-direction

From: Juri Linkov <[email-masked]>
Date: Sat, 28 Nov 2020 22:40:20 +0200

I've lost all my changes in the edited file because of the wrong
input arguments for window-in-direction.  Here's is what happened:
I forgot that the minibuffer was activated, and in the buffer
called the command windmove-display-down.  But it displayed
the text buffer in the minibuffer window.  Then I noticed this
and exited the minibuffer.  But exiting the minibuffer wiped off
the contents of the minibuffer window, i.e. cleared the text buffer
that was displayed in the minibuffer window.  This is because
currently windmove-display-in-direction doesn't send the arg
'nomini' to window-in-direction.  And it can't send this arg,
because currently window-in-direction ignores the value 'nomini',
and doesn't send its MINIBUF arg to walk-window-tree unchanged.

So here is a patch to avoid such accidents.  It sends MINIBUF arg
from window-in-direction to MINIBUF arg of walk-window-tree:

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 6557960064..5db13cf6b3 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -485,7 +485,7 @@ windmove-display-in-direction
                        (t (window-in-direction
                            dir nil nil
                            (and arg (prefix-numeric-value arg))
-                           windmove-wrap-around)))))
+                           windmove-wrap-around 'nomini)))))
          (unless window
            (setq window (split-window nil nil dir) type 'window))
          (cons window type)))
@@ -569,7 +569,7 @@ windmove-delete-in-direction
 When `windmove-wrap-around' is non-nil, takes the window
 from the opposite side of the frame."
   (let ((other-window (window-in-direction dir nil nil arg
-                                           windmove-wrap-around t)))
+                                           windmove-wrap-around 'nomini)))
     (cond ((null other-window)
            (user-error "No window %s from selected window" dir))
           (t
@@ -637,7 +637,7 @@ windmove-swap-states-in-direction
 When `windmove-wrap-around' is non-nil, takes the window
 from the opposite side of the frame."
   (let ((other-window (window-in-direction dir nil nil nil
-                                           windmove-wrap-around t)))
+                                           windmove-wrap-around 'nomini)))
     (cond ((or (null other-window) (window-minibuffer-p other-window))
            (user-error "No window %s from selected window" dir))
           (t
diff --git a/lisp/window.el b/lisp/window.el
index d564ec5546..82976bf836 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2309,7 +2309,7 @@ window--in-direction-2
 ;; Neither of these allow one to selectively ignore specific windows
 ;; (windows whose `no-other-window' parameter is non-nil) as targets of
 ;; the movement.
-(defun window-in-direction (direction &optional window ignore sign wrap mini)
+(defun window-in-direction (direction &optional window ignore sign wrap minibuf)
   "Return window in DIRECTION as seen from WINDOW.
 More precisely, return the nearest window in direction DIRECTION
 as seen from the position of `window-point' in window WINDOW.
@@ -2332,10 +2332,11 @@ window-in-direction
 frame and DIRECTION `above' the minibuffer window if the frame
 has one, and a window at the bottom of the frame otherwise.
 
-Optional argument MINI nil means to return the minibuffer window
-if and only if it is currently active.  MINI non-nil means to
-return the minibuffer window even when it's not active.  However,
-if WRAP is non-nil, always act as if MINI were nil.
+Optional argument MINIBUF t means to return the minibuffer
+window even if it isn't active.  MINIBUF nil or omitted means
+to return the minibuffer window if and only if it is currently active.
+MINIBUF neither nil nor t means never return the minibuffer window.
+However, if WRAP is non-nil, always act as if MINIBUF were nil.
 
 Return nil if no suitable window can be found."
   (setq window (window-normalize-window window t))
@@ -2451,7 +2452,7 @@ window-in-direction
 	   (setq best-edge-2 w-top)
 	   (setq best-diff-2 best-diff-2-new)
 	   (setq best-2 w)))))
-     frame nil (and mini t))
+     frame nil minibuf)
     (or best best-2)))
 
 (defun get-window-with-predicate (predicate &optional minibuf all-frames default)