Skip to content

Fixes for evil-want-minibuffer#2008

Open
real-or-random wants to merge 2 commits intoemacs-evil:masterfrom
real-or-random:202603-minibuffer-fixes
Open

Fixes for evil-want-minibuffer#2008
real-or-random wants to merge 2 commits intoemacs-evil:masterfrom
real-or-random:202603-minibuffer-fixes

Conversation

@real-or-random
Copy link
Copy Markdown

This fixes two issues with evil-want-minibuffer set to t:

The cursor is not refreshed after initializing evil in the minibuffer

This can be observed when the initial state in the minibuffer (defaults to insert state in the minibuffer) has a different cursor color than the cursor that was active previously. I don't observe the effect of this bug in every use of the minibuffer (because sometimes a refresh will be triggered by other events), but ironically, I observe it in evil-ex.

I tracked this down to the following series of events:

  1. evil-ex calls read-from-minibuffer
  2. read-from-minibuffer creates a fresh buffer (to become the minibuffer) and changes its major mode to minibuffer-mode
  3. This triggers after-change-major-mode-hook which calls evil-initialize
  4. evil-initialize does not abort even though (minibufferp) because evil-want-minibuffer is set, and so it calls evil-local-mode
  5. evil-local-mode skips evil-refresh-cursor because the currently selected window does not (yet) display the minibuffer. More precisely, (when (eq (window-buffer) (current-buffer)) is nil. (This check has been added in Fix cursor colour #1910, and it's correct.)
  6. read-from-minibuffer makes the minibuffer window the selected window. But because everything happens in C, this bypasses our advice for select-window that is supposed to refresh the cursor.
  7. (evil-initialize will be called again from minibuffer-setup-hooks but evil-change-state will correctly determine that we're already in the right state and skip further processing, including a potential cursor refresh.)

The first commit fixes this, at least in Emacs >= 27, by using the new window-*-change-function hooks instead of advice. This also makes it possible to handle the cursor refresh in evil-local-mode, which will disable it correctly when disabling evil. The latter fixes a FIXME.

evil-initialize is called twice in minibuffer

See item 7 above. This is fixed by the second commit. Afterward, the minibuffer will be treated like every other buffer for evil purposes (if evil-want-minibuffer is set).

This avoids the advice on select-window which is not removed even after
disabling Evil and which is not called when select-window is called
internally from C code, e.g., in read-from-minibuffer.
evil-initialize will be called earlier anyway, namely via
after-change-major-mode-hook when the major mode in the minibuffer
changes to minibuffer-mode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant