mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-05 22:20:24 -08:00
Do eager display of *Completions* while idle
Don't block user input while rendering the *Completions* buffer due to eager-display. This allows eager-display to be used with larger and slower completion tables without interfering with the user. Like in eager-update, we use while-no-input and non-essential to ensure that eager-display happens without blocking the user. To support this, we remove the ability to set eager-display to a function. The only user was tmm.el, which nows sets eager-display to t and adds a completion-setup-hook instead. (This also fixes a bug in tmm where dismissing and redisplaying the *Completions* buffer would not have the special help text) * lisp/minibuffer.el (completion-eager-display--timer) (completions--eager-display, completions--start-eager-display): Add. (bug#79819) (completing-read-default): Call completions--start-eager-display, stop supporting functionp eager-display. * lisp/tmm.el (tmm-add-prompt): Delete. (tmm--completion-setup-hook): Add. (tmm-add-prompt): Add completion-setup-hook, set eager-display to t. (tmm-goto-completions): Call minibuffer-completion-help instead of tmm-add-prompt.
This commit is contained in:
parent
4e08b2d434
commit
ab8d3624c4
2 changed files with 36 additions and 21 deletions
|
|
@ -141,8 +141,7 @@ This metadata is an alist. Currently understood keys are:
|
||||||
- `cycle-sort-function': function to sort entries when cycling.
|
- `cycle-sort-function': function to sort entries when cycling.
|
||||||
Works like `display-sort-function'.
|
Works like `display-sort-function'.
|
||||||
- `eager-display': non-nil to request eager display of the
|
- `eager-display': non-nil to request eager display of the
|
||||||
completion candidates. Can also be a function which is invoked
|
completion candidates.
|
||||||
after minibuffer setup.
|
|
||||||
The metadata of a completion table should be constant between two boundaries."
|
The metadata of a completion table should be constant between two boundaries."
|
||||||
(let ((metadata (if (functionp table)
|
(let ((metadata (if (functionp table)
|
||||||
(funcall table string pred 'metadata))))
|
(funcall table string pred 'metadata))))
|
||||||
|
|
@ -1278,7 +1277,7 @@ an association list that can specify properties such as:
|
||||||
- `group-function': function for grouping the completion candidates.
|
- `group-function': function for grouping the completion candidates.
|
||||||
- `annotation-function': function to add annotations in *Completions*.
|
- `annotation-function': function to add annotations in *Completions*.
|
||||||
- `affixation-function': function to prepend/append a prefix/suffix.
|
- `affixation-function': function to prepend/append a prefix/suffix.
|
||||||
- `eager-display': function to show *Completions* eagerly.
|
- `eager-display': non-nil to show *Completions* eagerly.
|
||||||
|
|
||||||
Categories are symbols such as `buffer' and `file', used when
|
Categories are symbols such as `buffer' and `file', used when
|
||||||
completing buffer and file names, respectively.
|
completing buffer and file names, respectively.
|
||||||
|
|
@ -1300,7 +1299,7 @@ possible values are the same as in `completions-sort'.
|
||||||
- `group-function': function for grouping the completion candidates.
|
- `group-function': function for grouping the completion candidates.
|
||||||
- `annotation-function': function to add annotations in *Completions*.
|
- `annotation-function': function to add annotations in *Completions*.
|
||||||
- `affixation-function': function to prepend/append a prefix/suffix.
|
- `affixation-function': function to prepend/append a prefix/suffix.
|
||||||
- `eager-display': function to show *Completions* eagerly.
|
- `eager-display': non-nil to show *Completions* eagerly.
|
||||||
See more description of metadata in `completion-metadata'.
|
See more description of metadata in `completion-metadata'.
|
||||||
|
|
||||||
Categories are symbols such as `buffer' and `file', used when
|
Categories are symbols such as `buffer' and `file', used when
|
||||||
|
|
@ -2754,6 +2753,24 @@ so that the update is less likely to interfere with user typing."
|
||||||
((completion--eager-update-p (minibuffer-prompt-end))
|
((completion--eager-update-p (minibuffer-prompt-end))
|
||||||
(minibuffer-completion-help))))))
|
(minibuffer-completion-help))))))
|
||||||
|
|
||||||
|
(defvar completion-eager-display--timer nil)
|
||||||
|
|
||||||
|
(defun completions--eager-display ()
|
||||||
|
"Try to display *Completions* without blocking input."
|
||||||
|
;; If the user has left the minibuffer, give up on eager display of
|
||||||
|
;; *Completions*.
|
||||||
|
(when (minibufferp nil t)
|
||||||
|
(when (while-no-input
|
||||||
|
(let ((non-essential t))
|
||||||
|
(minibuffer-completion-help)))
|
||||||
|
;; If we got interrupted, try again the next time the user is idle.
|
||||||
|
(completions--start-eager-display))))
|
||||||
|
|
||||||
|
(defun completions--start-eager-display ()
|
||||||
|
"Display the *Completions* buffer when the user is next idle."
|
||||||
|
(setq completion-eager-display--timer
|
||||||
|
(run-with-idle-timer 0 nil #'completions--eager-display)))
|
||||||
|
|
||||||
(defun completions--post-command-update ()
|
(defun completions--post-command-update ()
|
||||||
"Update displayed *Completions* buffer after command, once."
|
"Update displayed *Completions* buffer after command, once."
|
||||||
(remove-hook 'post-command-hook #'completions--post-command-update)
|
(remove-hook 'post-command-hook #'completions--post-command-update)
|
||||||
|
|
@ -5143,14 +5160,14 @@ See `completing-read' for the meaning of the arguments."
|
||||||
;; `completion-eager-display' is t or if eager display
|
;; `completion-eager-display' is t or if eager display
|
||||||
;; has been requested by the completion table.
|
;; has been requested by the completion table.
|
||||||
(when completion-eager-display
|
(when completion-eager-display
|
||||||
(let* ((md (completion-metadata
|
(when (or (eq completion-eager-display t)
|
||||||
|
(completion-metadata-get
|
||||||
|
(completion-metadata
|
||||||
(buffer-substring-no-properties
|
(buffer-substring-no-properties
|
||||||
(minibuffer-prompt-end) (point))
|
(minibuffer-prompt-end) (point))
|
||||||
collection predicate))
|
collection predicate)
|
||||||
(fun (completion-metadata-get md 'eager-display)))
|
'eager-display))
|
||||||
(when (or fun (eq completion-eager-display t))
|
(completions--start-eager-display))))
|
||||||
(funcall (if (functionp fun)
|
|
||||||
fun #'minibuffer-completion-help))))))
|
|
||||||
(read-from-minibuffer prompt initial-input keymap
|
(read-from-minibuffer prompt initial-input keymap
|
||||||
nil hist def inherit-input-method))))
|
nil hist def inherit-input-method))))
|
||||||
(when (and (equal result "") def)
|
(when (and (equal result "") def)
|
||||||
|
|
|
||||||
20
lisp/tmm.el
20
lisp/tmm.el
|
|
@ -218,7 +218,9 @@ is used to go back through those sub-menus."
|
||||||
(car (nth index-of-default tmm-km-list))
|
(car (nth index-of-default tmm-km-list))
|
||||||
(minibuffer-with-setup-hook
|
(minibuffer-with-setup-hook
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(setq tmm-old-mb-map (tmm-define-keys t)))
|
(setq tmm-old-mb-map (tmm-define-keys t))
|
||||||
|
(add-hook 'completion-setup-hook
|
||||||
|
#'tmm--completion-setup-hook 'append 'local))
|
||||||
;; tmm-km-list is reversed, because history
|
;; tmm-km-list is reversed, because history
|
||||||
;; needs it in LIFO order. But default list
|
;; needs it in LIFO order. But default list
|
||||||
;; needs it in non-reverse order, so that the
|
;; needs it in non-reverse order, so that the
|
||||||
|
|
@ -231,7 +233,7 @@ is used to go back through those sub-menus."
|
||||||
" (up/down to change, PgUp to menu): ")
|
" (up/down to change, PgUp to menu): ")
|
||||||
(completion-table-with-metadata
|
(completion-table-with-metadata
|
||||||
tmm-km-list '((category . tmm)
|
tmm-km-list '((category . tmm)
|
||||||
(eager-display . tmm-add-prompt)
|
(eager-display . t)
|
||||||
(display-sort-function . identity)
|
(display-sort-function . identity)
|
||||||
(cycle-sort-function . identity)))
|
(cycle-sort-function . identity)))
|
||||||
nil t nil
|
nil t nil
|
||||||
|
|
@ -416,20 +418,16 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
|
||||||
(goto-char next)))
|
(goto-char next)))
|
||||||
(set-buffer-modified-p nil)))
|
(set-buffer-modified-p nil)))
|
||||||
|
|
||||||
(defun tmm-add-prompt ()
|
(defun tmm--completion-setup-hook ()
|
||||||
(unless tmm-c-prompt
|
(unless tmm-c-prompt
|
||||||
(error "No active menu entries"))
|
(error "No active menu entries"))
|
||||||
(or tmm-completion-prompt
|
(or tmm-completion-prompt
|
||||||
(add-hook 'completion-setup-hook
|
(tmm-completion-delete-prompt))
|
||||||
#'tmm-completion-delete-prompt 'append))
|
(with-current-buffer standard-output
|
||||||
(unwind-protect
|
|
||||||
(minibuffer-completion-help)
|
|
||||||
(remove-hook 'completion-setup-hook #'tmm-completion-delete-prompt))
|
|
||||||
(with-current-buffer "*Completions*"
|
|
||||||
(tmm-remove-inactive-mouse-face)
|
(tmm-remove-inactive-mouse-face)
|
||||||
(when tmm-completion-prompt
|
(when tmm-completion-prompt
|
||||||
(let ((inhibit-read-only t)
|
(let ((inhibit-read-only t)
|
||||||
(window (get-buffer-window "*Completions*")))
|
(window (get-buffer-window)))
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(insert
|
(insert
|
||||||
(if tmm-shortcut-inside-entry
|
(if tmm-shortcut-inside-entry
|
||||||
|
|
@ -474,7 +472,7 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
|
||||||
(defun tmm-goto-completions ()
|
(defun tmm-goto-completions ()
|
||||||
"Jump to the completions buffer."
|
"Jump to the completions buffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
(tmm-add-prompt)
|
(minibuffer-completion-help)
|
||||||
(setq tmm-c-prompt (buffer-substring (minibuffer-prompt-end) (point-max)))
|
(setq tmm-c-prompt (buffer-substring (minibuffer-prompt-end) (point-max)))
|
||||||
;; Clear minibuffer old contents before using *Completions* buffer for
|
;; Clear minibuffer old contents before using *Completions* buffer for
|
||||||
;; selection.
|
;; selection.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue