Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window

From: Juri Linkov <[email-masked]>
Date: Tue, 30 Oct 2018 00:38:08 +0200

> Rather, the function on 'post-command-hook' would have to be more
> intelligent - check whether the minibuffer-window is selected and
> leave the overriding action untouched in that case.

It's possible to implement it with post-command-hook, but the
implementation will be more contorted - note that adding a hook
to post-command-hook by a command will run it immediately
at the end of this command and immediately remove the hook.

Whereas window-state-change-functions elegantly checks
if the window displays a new buffer.

> Moreover, using 'post-command-hook' would automatically fix any
> problems when quitting an S-M-up action.  I see no way to catch
> quitting via a state change of windows.

What do you mean by quitting an S-M-up action?  minibuffer-exit?

> I forgot to ask: If that ffap pops up completions, they will appear
> above the selected window.  Right?

Right.  Since I agree this is not an expected behavior, here is a better
version without this problem.  Instead of display-buffer-overriding-action,
it uses display-buffer-alist because only display-buffer-alist
supports a condition necessary to check for an active minibuffer.

(defun display-buffer-directionally ()
  "Specify in which direction the buffer should be displayed.
Arrows show the direction.  Mod-0 forces to display in the same window."
  (interactive)
  (let* ((dir (event-basic-type (aref (this-command-keys) 0)))
         (win (if (eq dir ?0)
		  (selected-window)
		(or (window-in-direction dir)
		    (split-window nil nil dir)))))
    (let ((hook (list 'lambda)))
      (setcdr hook `((window alist)
                     (when (and (eq window ,win)
                                (not (eq (nth 1 (assq 'buffer alist))
                                         (nth 2 (assq 'buffer alist)))))
                       (setq display-buffer-alist (cdr display-buffer-alist))
                       (remove-hook 'window-state-change-functions ',hook))))
      (add-hook 'window-state-change-functions hook))
    (setq display-buffer-alist
	  (cons `((lambda (_buffer-name _action) ; condition
		    (= (minibuffer-depth) 0))
		  (lambda (buffer alist)         ; action
		    (window--display-buffer buffer ,win 'reuse alist)))
		display-buffer-alist))))