mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Preserve selected candidate across *Completions* update
When *Completions* is updated and point was on some completion candidate, move point to the same candidate after the update. Also, a selected completion in *Completions* is now always highlighted, even if it was selected by the user or other code moving point rather than by minibuffer-next-completion, because cursor-face-highlight-nonselected-window is now set in completion-setup-function. Other completion UIs (e.g. ido, vertico, etc) effectively have this behavior: whenever they update the list of completions, they preserve whatever candidate is selected. This matters a lot when completions are auto-updated, but is still useful without auto-updating. Including this behavior is a step towards supporting auto-updating in the default completion UI. * lisp/minibuffer.el (minibuffer-completion-help): Preserve the selected completion candidate across updates. (bug#74019) (minibuffer-hide-completions): Move point to BOB. (minibuffer-next-completion): Don't set cursor-face-highlight-nonselected-window. * lisp/simple.el (completions--start-of-candidate-at) (choose-completion): Extract the current-completion-finding code into a separate function. (completion-setup-function): Set cursor-face-highlight-nonselected-window. * etc/NEWS: Announce new behavior.
This commit is contained in:
parent
32f070fa3d
commit
5b19ca56f1
3 changed files with 55 additions and 21 deletions
|
|
@ -10246,6 +10246,23 @@ Also see the `completion-auto-wrap' variable."
|
|||
|
||||
This makes `completions--deselect' effective.")
|
||||
|
||||
(defun completions--start-of-candidate-at (position)
|
||||
"Return the start position of the completion candidate at POSITION."
|
||||
(save-excursion
|
||||
(goto-char position)
|
||||
(let (beg)
|
||||
(cond
|
||||
((and (not (eobp))
|
||||
(get-text-property (point) 'completion--string))
|
||||
(setq beg (1+ (point))))
|
||||
((and (not (bobp))
|
||||
(get-text-property (1- (point)) 'completion--string))
|
||||
(setq beg (point))))
|
||||
(when beg
|
||||
(or (previous-single-property-change
|
||||
beg 'completion--string)
|
||||
beg)))))
|
||||
|
||||
(defun choose-completion (&optional event no-exit no-quit)
|
||||
"Choose the completion at point.
|
||||
If EVENT, use EVENT's position to determine the starting position.
|
||||
|
|
@ -10269,21 +10286,11 @@ minibuffer, but don't quit the completions window."
|
|||
(or (get-text-property (posn-point (event-start event))
|
||||
'completion--string)
|
||||
(error "No completion here"))
|
||||
(save-excursion
|
||||
(goto-char (posn-point (event-start event)))
|
||||
(let (beg)
|
||||
(cond
|
||||
((and (not (eobp))
|
||||
(get-text-property (point) 'completion--string))
|
||||
(setq beg (1+ (point))))
|
||||
((and (not (bobp))
|
||||
(get-text-property (1- (point)) 'completion--string))
|
||||
(setq beg (point)))
|
||||
(t (error "No completion here")))
|
||||
(setq beg (or (previous-single-property-change
|
||||
beg 'completion--string)
|
||||
beg))
|
||||
(get-text-property beg 'completion--string))))))
|
||||
(if-let* ((candidate-start
|
||||
(completions--start-of-candidate-at
|
||||
(posn-point (event-start event)))))
|
||||
(get-text-property candidate-start 'completion--string)
|
||||
(error "No completion here")))))
|
||||
|
||||
(unless (buffer-live-p buffer)
|
||||
(error "Destination buffer is dead"))
|
||||
|
|
@ -10451,6 +10458,8 @@ Called from `temp-buffer-show-hook'."
|
|||
(let ((base-position completion-base-position)
|
||||
(insert-fun completion-list-insert-choice-function))
|
||||
(completion-list-mode)
|
||||
(when completions-highlight-face
|
||||
(setq-local cursor-face-highlight-nonselected-window t))
|
||||
(setq-local completion-base-position base-position)
|
||||
(setq-local completion-list-insert-choice-function insert-fun))
|
||||
(setq-local completion-reference-buffer mainbuf)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue