Closed gcv closed 3 years ago
The issue with split window on find-file
can be reproduced like this in emacs -Q
:
M-x load-file mini-frame.el
Insert this code into *scratch*
buffer:
(mini-frame-read-from-minibuffer (lambda () (call-interactively 'find-file)))
M-x eval-buffer
Let's see what's happens here:
mini-frame-read-from-minibuffer
creates and shows the minibuffer-only frame.mini-frame-read-from-minibuffer
calls find-file
.find-file
calls find-file-read-args
to get filename using currently selected miniwindow.find-file
calls pop-to-buffer-same-window
to show the file. But pop-to-buffer-same-window
can't show the file in the current window:
Specifically, if the selected window is neither a minibuffer window (as reported by
window-minibuffer-p
), nor is dedicated to another buffer (seewindow-dedicated-p
), BUFFER will be displayed in the currently selected window; otherwise it will be displayed in another window.
So the new window on non minibuffer-only frame is created.
mini-frame-read-from-minibuffer
hides the minibuffer-only frame and selects the frame that was previously selected.Now, the normal behaviour, when we only advise read-from-minibuffer
and read-string
functions:
find-file
calls find-file-read-args
to get filename.find-file-read-args
somewhere down the stack calls read-from-minibuffer
.read-from-minibuffer
, mini-frame-read-from-minibuffer
kicks in.mini-frame-read-from-minibuffer
creates and shows the minibuffer-only frame.mini-frame-read-from-minibuffer
calls read-from-minibuffer
.mini-frame-read-from-minibuffer
hides the minibuffer-only frame and selects the frame that was previously selected.find-file
calls pop-to-buffer-same-window
to show the file.That's why the mini-frame-read-from-minibuffer
must be called with the function as close to actually read user input as possible.
I think one possible solution would be to modify /with-selectrum
like this:
(defun /with-selectrum (fn)
(let ((status-selectrum selectrum-mode))
(unwind-protect
(progn
(selectrum-mode 1)
(when window-system
(advice-add 'read-from-minibuffer :around #'mini-frame-read-from-minibuffer))
(call-interactively fn))
(advice-remove 'read-from-minibuffer #'mini-frame-read-from-minibuffer)
(unless status-selectrum (selectrum-mode -1)))))
Another solution would be to use the mini-frame-advise-functions
option (added recently ;)). If you interested to show mini-frame only on M-x
and find-file
:
(when window-system
(setq mini-frame-advice-functions '(find-file-read-args read-extended-command))
(mini-frame-mode))
(defun /with-selectrum (fn)
(let ((status-selectrum selectrum-mode))
(unwind-protect
(progn
(selectrum-mode 1)
(call-interactively fn))
(unless status-selectrum (selectrum-mode -1)))))
Hope it will help to make it work for you.
BTW from window-system
docstring:
Use of this function as a predicate is deprecated. Instead, use
display-graphic-p
or any of the otherdisplay-*-p
predicates which report frame's specific UI-related capabilities.
This is fantastic. Thank you so much for your time. With your hints, I achieved the exact effect I wanted. mini-frame-advice-functions
is a fantastic feature, also.
FYI mini-frame-read-from-minibuffer
is checking display-graphic-p
now so you can skip that check in your code.
Perfect. Thanks again!
I'm trying to selectively enable mini-frame for some commands, and it doesn't quite work as I'd like.
Specifically, I want to enable mini-frame with Selectrum for specific commands, rather than wholesale. Pretty sure my approach will generalize to, e.g., icomplete-vertical.
Consider the following code:
M-x
works fine, butC-x C-f
runs into a couple of kinds of trouble.The newly-visited file opens in a split window instead of the current window. At first, I thought I used
call-interactively
incorrectly, but the split doesn't happen if I change/with-selectrum
to not use mini-frame.When attempting to visit a file which is a symlink to a source-controlled file someplace else, i.e., behavior governed by
vc-follow-symlinks
, the prompt appears in the mini-frame instead of the minibuffer. When mini-frame-mode and selectrum-mode are enabled normally, this does not occur. Which led me to try just temporarily enabling mini-frame-mode along with selectrum-mode, but this had other problems (notably visibly worse performance, as the mini frame has to be recreated on each command).I'll be grateful for any guidance you might have on this.