emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Select completions from the minibuffer


From: Ergus
Subject: Re: Select completions from the minibuffer
Date: Fri, 18 Mar 2022 12:53:36 +0100

On Fri, Mar 18, 2022 at 11:27:52AM +0200, Juri Linkov wrote:
Looking at the last line in `deactivate-mark` it seems like it is a
known issue and changing such optimization in the display engine may be
probably undesirable (Eli will confirm soon hopefully), so in your case
maybe is better to force the update on demand like in deactivate-mark:

```
(defmacro with-minibuffer-completions-window (&rest body)
   "Execute the forms in BODY from the minibuffer in its completions window.
When used in a minibuffer window, select the window with completions,
and execute the forms."
   (declare (indent 0) (debug t))
   `(let ((window (or (get-buffer-window "*Completions*" 0)
                      ;; Make sure we have a completions window.
                      (progn (minibuffer-completion-help)
                             (get-buffer-window "*Completions*" 0)))))
      (when window
        (with-selected-window window
          ,@body
          (redisplay--update-cursor-face-highlight window)))))
```

This seems to work.

Is it enough?

Thanks, I confirm such forcing the update fixes highlighting.

But still when cursor-face-highlight-nonselected-window is nil by default,
let-binding it to t has no effect:

```
(defun minibuffer-next-completion (&optional n)
 "Run `next-completion' from the minibuffer in its completions window."
 (interactive "p")
 (with-minibuffer-completions-window
   (let ((cursor-face-highlight-nonselected-window t))
     (next-completion n))))
```

Hi Juri:

This should be because when you force the
redisplay--update-cursor-face-highlight; then the display engine detects
that something more important than a point move changed (an overlay
moved) and it passes *Completions* to
redisplay--pre-redisplay-functions.

Then it calls redisplay--update-cursor-face-highlight once again (yes
now it calls redisplay--update-cursor-face-highlight 2 times instead of
none) but the second call is from outside of your function; so it gets
the buffer local value of cursor-face-highlight-nonselected-window.

In general (setq-local cursor-face-highlight-nonselected-window t)
should go into the completion-setup-function because you don't have a
full control for when the display engine calls
redisplay--pre-redisplay-functions for *Completions* window. For
example, in a resize the highlight may disappear too.

So you need:

(when completions-highlight-face
        (setq cursor-face-highlight-nonselected-window t)
        (cursor-face-highlight-mode 1))

in completion-setup-function OR add another function to
completion-setup-hook only to do the setq-local.

Eli:

If there is a way to force the display engine to detect a change in a
window and use it to pass *Completions* in the next call to
redisplay--pre-redisplay-functions? I mean to avoid the need to do a
redundant explicit call to redisplay--update-cursor-face-highlight which
doesn't really take effect?

Best,
Ergus


reply via email to

[Prev in Thread] Current Thread [Next in Thread]