`(repeat :tag "insert a new menu to add more styles"
(choice :convert-widget completion--update-styles-options)))
-(defconst completion--cycling-threshold-type
- '(choice (const :tag "No cycling" nil)
- (const :tag "Always cycle" t)
- (integer :tag "Threshold")))
-
(defcustom completion-styles
;; First, use `basic' because prefix completion has been the standard
;; for "ever" and works well in most cases, so using it first
Each entry has the shape (CATEGORY . ALIST) where ALIST is
an association list that can specify properties such as:
- `styles': the list of `completion-styles' to use for that category.
-- `cycle': the `completion-cycle-threshold' to use for that category.
- `sort-function': function to sort entries when cycling.
- `group-function': function for grouping the completion candidates.
- `annotation-function': function to add annotations in *Completions*.
Each override has the shape (CATEGORY . ALIST) where ALIST is
an association list that can specify properties such as:
- `styles': the list of `completion-styles' to use for that category.
-- `cycle': the `completion-cycle-threshold' to use for that category.
- `sort-function': function to sort entries when cycling.
function from metadata, or if that is nil, fall back to `completions-sort';
`identity' disables sorting and keeps the original order; and other
:value-type (set :tag "Properties to override"
(cons :tag "Completion Styles"
(const styles) ,completion--styles-type)
- (cons :tag "Cycling threshold"
- (const cycle)
- ,completion--cycling-threshold-type)
(cons :tag "Sort order"
(const sort-function)
(choice
(delete-region (point) (+ (point) length)))
(forward-char suffix-len)))
-(defcustom completion-cycle-threshold nil
- "Number of completion candidates below which cycling is used.
-Depending on this setting `completion-in-region' may use cycling,
-whereby invoking a completion command several times in a row
-completes to each of the candidates in turn, in a cyclic manner.
-If nil, cycling is never used.
-If t, cycling is always used.
-If an integer, cycling is used so long as there are not more
-completion candidates than this number."
- :version "24.1"
- :type completion--cycling-threshold-type)
+(defvar completion-cycle-threshold nil
+ "This variable is obsolete and no longer used.")
+
+(make-obsolete-variable 'completion-cycle-threshold nil "30.1")
(defcustom completions-sort 'alphabetical
"Sort candidates in the *Completions* buffer.
"Face used for the separator lines between the candidate groups."
:version "28.1")
-(defun completion--cycle-threshold (metadata)
- (let* ((cat (completion-metadata-get metadata 'category))
- (over (completion--category-override cat 'cycle)))
- (if over (cdr over) completion-cycle-threshold)))
-
(defvar-local completion-all-sorted-completions nil)
-(defvar-local completion--all-sorted-completions-location nil)
-(defvar-local completion--input nil)
-(defvar completion-cycling nil) ;Function that takes down the cycling map.
+(defvar-local completion-history nil)
(defvar completion-tab-width nil)
(defvar completion-fail-discreetly nil
;; It did find a match. Do we match some possibility exactly now?
(let* ((exact (test-completion completion
minibuffer-completion-table
- minibuffer-completion-predicate))
- (threshold (completion--cycle-threshold md))
- (comps
- ;; Check to see if we want to do cycling. We do it
- ;; here, after having performed the normal completion,
- ;; so as to take advantage of the difference between
- ;; try-completion and all-completions, for things
- ;; like completion-ignored-extensions.
- (when (and threshold
- ;; Check that the completion didn't make
- ;; us jump to a different boundary.
- (or (not completed)
- (< (car (completion-boundaries
- (substring completion 0 comp-pos)
- minibuffer-completion-table
- minibuffer-completion-predicate
- ""))
- comp-pos)))
- (completion-all-sorted-completions beg end))))
- (completion--flush-all-sorted-completions)
+ minibuffer-completion-predicate)))
(cond
- ((and (consp (cdr comps)) ;; There's something to cycle.
- (not (ignore-errors
- ;; This signal an (intended) error if comps is too
- ;; short or if completion-cycle-threshold is t.
- (consp (nthcdr threshold comps)))))
- ;; Not more than completion-cycle-threshold remaining
- ;; completions: let's cycle.
- (setq completed t exact t)
- (completion--cache-all-sorted-completions beg end comps)
- (minibuffer-force-complete beg end))
(completed
- (cond
- ((pcase completion-auto-help
- ('visible (get-buffer-window completions-buffer-name 0))
- ('always t))
- (minibuffer-completion-help beg end))
- (t (minibuffer-hide-completions)
- (when (minibufferp)
- (let ((base-size
- (car (completion-boundaries
- string
- minibuffer-completion-table
- minibuffer-completion-predicate ""))))
- (minibuffer--cache-completion-input
- (substring string base-size)
- (buffer-substring-no-properties
- (minibuffer-prompt-end)
- (+ (minibuffer-prompt-end) base-size)))))
- (when exact
- ;; If completion did not put point at end of field,
- ;; it's a sign that completion is not finished.
- (completion--done completion
- (if (< comp-pos (length completion))
- 'exact 'unknown))))))
+ (if (pcase completion-auto-help
+ ('visible (get-buffer-window completions-buffer-name 0))
+ ('always t))
+ (minibuffer-completion-help beg end)
+ (minibuffer-hide-completions)
+ (when exact
+ ;; If completion did not put point at end of field,
+ ;; it's a sign that completion is not finished.
+ (completion--done completion
+ (if (< comp-pos (length completion))
+ 'exact 'unknown)))))
;; Show the completion table, if requested.
((not exact)
(if (pcase completion-auto-help
(minibuffer--bitset completed t exact))))))))
+(defun minibuffer-restore-completion-input ()
+ "Restore the state of the minibuffer prior to last completion command."
+ (interactive "" minibuffer-mode)
+ (if-let ((record (pop completion-history))
+ (contents (car record))
+ (point (cdr record)))
+ (if (and (equal contents (minibuffer-contents))
+ (equal point (point)))
+ (minibuffer-message "Popped completion history")
+ (completion--replace (minibuffer-prompt-end)
+ (point-max)
+ contents)
+ (goto-char point)
+ (when (get-buffer-window completions-buffer-name 0)
+ ;; Refresh *Completions* buffer, if already visible.
+ (minibuffer-completion-help)))
+ (user-error "Empty completion history")))
+
+(defmacro minibuffer-record-completion-input (&rest body)
+ "Execute BODY and record the prior minibuffer state if BODY changed it."
+ (declare (indent 0) (debug t))
+ (let ((cnt (make-symbol "contents"))
+ (pos (make-symbol "position"))
+ (res (make-symbol "result")))
+ `(let ((,cnt (minibuffer-contents))
+ (,pos (point))
+ (,res (progn ,@body)))
+ (unless (and (equal ,cnt (minibuffer-contents))
+ (equal ,pos (point)))
+ (push (cons ,cnt ,pos) completion-history))
+ ,res)))
+
(defun minibuffer-complete ()
"Complete the minibuffer contents as far as possible.
Return nil if there is no valid completion, else t.
If no characters can be completed, display a list of possible completions.
If you repeat this command after it displayed such a list,
scroll the window of possible completions."
- (interactive)
- (completion-in-region (minibuffer--completion-prompt-end) (point-max)
- minibuffer-completion-table
- minibuffer-completion-predicate))
+ (interactive "" minibuffer-mode)
+ (minibuffer-record-completion-input
+ (completion-in-region (minibuffer--completion-prompt-end) (point-max)
+ minibuffer-completion-table
+ minibuffer-completion-predicate)))
(define-obsolete-function-alias 'minibuffer-complete-word
'minibuffer-complete "30.1")
(defun completion--in-region-1 (beg end)
- ;; If the previous command was not this,
- ;; mark the completion buffer obsolete.
- (setq this-command 'completion-at-point)
- (unless (eq 'completion-at-point last-command)
- (completion--flush-all-sorted-completions)
- (setq minibuffer-scroll-window nil))
-
- (cond
- ;; If there's a fresh completion window with a live buffer,
- ;; and this command is repeated, scroll that window.
- ((and (window-live-p minibuffer-scroll-window)
- (eq t (frame-visible-p (window-frame minibuffer-scroll-window))))
- (let ((window minibuffer-scroll-window))
- (with-current-buffer (window-buffer window)
- (cond
- ;; Here this is possible only when second-tab, but instead of
- ;; scrolling the completion list window, switch to it below,
- ;; outside of `with-current-buffer'.
- ((eq completion-auto-select 'second-tab))
- ;; Reverse tab
- ((equal (this-command-keys) [backtab])
- (if (pos-visible-in-window-p (point-min) window)
- ;; If beginning is in view, scroll up to the end.
- (set-window-point window (point-max))
- ;; Else scroll down one screen.
- (with-selected-window window (scroll-down))))
- ;; Normal tab
- (t
- (if (pos-visible-in-window-p (point-max) window)
- ;; If end is in view, scroll up to the end.
- (set-window-start window (point-min) nil)
- ;; Else scroll down one screen.
- (with-selected-window window (scroll-up))))))
- (when (eq completion-auto-select 'second-tab)
- (switch-to-completions))
- nil))
- ;; If we're cycling, keep on cycling.
- ((and completion-cycling completion-all-sorted-completions)
- (minibuffer-force-complete beg end)
- t)
- (t (prog1 (pcase (completion--do-completion beg end)
- (#b000 nil)
- (_ t))
- (if (window-live-p minibuffer-scroll-window)
- (and (eq completion-auto-select t)
- (eq t (frame-visible-p (window-frame minibuffer-scroll-window)))
- ;; When the completion list window was displayed, select it.
- (switch-to-completions))
- (completion-in-region-mode -1))))))
-
-(defun completion--cache-all-sorted-completions (beg end comps)
- (add-hook 'after-change-functions
- #'completion--flush-all-sorted-completions nil t)
- (setq completion--all-sorted-completions-location
- (cons (copy-marker beg) (copy-marker end)))
- (setq completion-all-sorted-completions comps))
-
-(defun completion--flush-all-sorted-completions (&optional start end _len)
- (unless (and start end
- (or (> start (cdr completion--all-sorted-completions-location))
- (< end (car completion--all-sorted-completions-location))))
- (remove-hook 'after-change-functions
- #'completion--flush-all-sorted-completions t)
- ;; Remove the transient map if applicable.
- (when completion-cycling
- (funcall (prog1 completion-cycling (setq completion-cycling nil))))
- (setq completion-all-sorted-completions nil)))
+ (prog1 (pcase (completion--do-completion beg end)
+ (#b000 nil)
+ (_ t))
+ (if (window-live-p minibuffer-scroll-window)
+ (and (eq completion-auto-select t)
+ (eq t (frame-visible-p (window-frame minibuffer-scroll-window)))
+ ;; When the completion list window was displayed, select it.
+ (switch-to-completions))
+ (completion-in-region-mode -1))))
(defun completion--metadata (string base md-at-point table pred)
;; Like completion-metadata, but for the specific case of getting the
(mapcan #'cdr groups)))
(defun completion-all-sorted-completions (&optional start end)
- (or completion-all-sorted-completions
- (let* ((start (or start (minibuffer-prompt-end)))
- (end (or end (point-max)))
- (string (buffer-substring start end))
- (md (completion--field-metadata start))
- (all (completion-all-completions
- string
- minibuffer-completion-table
- minibuffer-completion-predicate
- (- (point) start)
- md))
- (last (last all))
- (base-size (or (cdr last) 0))
- (all-md (completion--metadata (buffer-substring-no-properties
- start (point))
- base-size md
- minibuffer-completion-table
- minibuffer-completion-predicate))
- (sort-fun
- (or minibuffer-completions-sort-function
- (completion-metadata-get all-md 'sort-function)
- (pcase completions-sort
- ('nil #'identity)
- ('alphabetical #'minibuffer-sort-alphabetically)
- ('historical #'minibuffer-sort-by-history)
- (_ completions-sort))))
- (full-base (substring string 0 base-size))
- (minibuffer-completion-base
- (funcall (or (alist-get 'adjust-base-function all-md) #'identity)
- full-base)))
- (when last
- (setcdr last nil)
-
- ;; Delete duplicates: do it after setting last's cdr to nil (so
- ;; it's a proper list), and be careful to reset `last' since it
- ;; may be a different cons-cell.
- (setq all (delete-dups all))
- (setq last (last all))
-
- (when sort-fun (setq all (funcall sort-fun all)))
-
- ;; Cache input for `minibuffer-restore-completion-input',
- ;; unless STRING is an exact and sole completion.
- (let ((input (substring string base-size)))
- (and (minibufferp)
- (or (consp (cdr all)) ; not sole
- (not (equal input (car all)))) ; not exact
- (minibuffer--cache-completion-input
- input (buffer-substring (minibuffer-prompt-end)
- (+ (minibuffer-prompt-end)
- base-size)))))
-
- ;; Cache the result. This is not just for speed, but also so that
- ;; repeated calls to minibuffer-force-complete can cycle through
- ;; all possibilities.
- (completion--cache-all-sorted-completions
- start end (nconc all base-size))))))
+ (let* ((start (or start (minibuffer-prompt-end)))
+ (end (or end (point-max)))
+ (string (buffer-substring start end))
+ (md (completion--field-metadata start))
+ (all (completion-all-completions
+ string
+ minibuffer-completion-table
+ minibuffer-completion-predicate
+ (- (point) start)
+ md))
+ (last (last all))
+ (base-size (or (cdr last) 0))
+ (all-md (completion--metadata (buffer-substring-no-properties
+ start (point))
+ base-size md
+ minibuffer-completion-table
+ minibuffer-completion-predicate))
+ (sort-fun
+ (or minibuffer-completions-sort-function
+ (completion-metadata-get all-md 'sort-function)
+ (pcase completions-sort
+ ('nil #'identity)
+ ('alphabetical #'minibuffer-sort-alphabetically)
+ ('historical #'minibuffer-sort-by-history)
+ (_ completions-sort))))
+ (full-base (substring string 0 base-size))
+ (minibuffer-completion-base
+ (funcall (or (alist-get 'adjust-base-function all-md) #'identity)
+ full-base)))
+ (when last
+ (setcdr last nil)
+
+ ;; Delete duplicates: do it after setting last's cdr to nil (so
+ ;; it's a proper list), and be careful to reset `last' since it
+ ;; may be a different cons-cell.
+ (setq all (delete-dups all))
+ (setq last (last all))
+
+ (when sort-fun (setq all (funcall sort-fun all)))
+
+ (let ((result (nconc all base-size)))
+ ;; Cache the result. This is not just for speed, but also so that
+ ;; repeated calls to minibuffer-force-complete can cycle through
+ ;; all possibilities.
+ (setq completion-all-sorted-completions result)))))
(defun minibuffer-toggle-completion-ignore-case ()
"Toggle completion case-sensitively for the current minibuffer."
\\[exit-minibuffer] when you know you want the first
completion even before cycling to it."
(interactive "" minibuffer-mode)
- (completion--flush-all-sorted-completions)
(if-let ((beg (minibuffer-prompt-end))
(end (cdr (minibuffer--completion-boundaries)))
(all (completion-all-sorted-completions beg end)))
(defun completion-switch-cycling-direction ()
"Switch completion cycling from forward to backward and vice versa."
- (setq completion-all-sorted-completions
- (let* ((all completion-all-sorted-completions)
- (last (last all))
- (base (cdr last)))
- (when last (setcdr last nil))
- (setq all (nreverse all))
- (setq last (last all))
- (when last (setcdr last (cons (car all) base)))
- (cdr all))))
+ (let* ((all completion-all-sorted-completions)
+ (last (last all))
+ (base (cdr last)))
+ (when last (setcdr last nil))
+ (setq all (nreverse all))
+ (setq last (last all))
+ (when last (setcdr last (cons (car all) base)))
+ (setq completion-all-sorted-completions (cdr all))))
(defun minibuffer-cycle-completion (arg)
"Cycle minibuffer input to the ARGth next completion.
Interactively, ARG is the prefix argument, and it defaults to 1."
(interactive "p" minibuffer-mode)
- (let* ((times (abs arg)))
+ (let ((times (abs arg)))
(when (< arg 1) (completion-switch-cycling-direction))
(if (< 0 times)
- (dotimes (_ times) (minibuffer-force-complete))
+ (dotimes (_ times) (minibuffer-cycle-completion-further))
(completion--message "Switched cycling direction"))
(when (< arg 0) (completion-switch-cycling-direction))))
-(defun minibuffer-restore-completion-input ()
- "Restore minibuffer contents to last input used for completion."
+(defun minibuffer--highlight-in-completions (cand)
+ (when-let ((win (get-buffer-window completions-buffer-name 0))
+ (pm (with-current-buffer completions-buffer-name
+ (save-excursion
+ (goto-char (point-min))
+ (when-let ((pm (text-property-search-forward
+ 'completion--string cand t)))
+ (setq-local
+ cursor-face-highlight-nonselected-window t)
+ (goto-char (prop-match-beginning pm))
+ (text-property-search-forward 'cursor-face))))))
+ (set-window-point win (prop-match-beginning pm))))
+
+(defun minibuffer-cycle-completion-further ()
+ "Cycle to next completion candidate."
+ (if-let* ((all completion-all-sorted-completions)
+ (cur (car all))
+ (beg (minibuffer-prompt-end)))
+ (progn
+ (completion--replace (+ beg (or (cdr (last all)) 0))
+ (point-max) cur)
+ (completion--done (buffer-substring-no-properties beg (point-max)) 'sole)
+ (minibuffer--highlight-in-completions cur)
+ ;; Rotate cached `completion-all-sorted-completions'.
+ (let ((last (last all)))
+ (setcdr last (cons (car all) (cdr last)))
+ (setq completion-all-sorted-completions (cdr all))))
+ (minibuffer-force-complete)))
+
+(defun minibuffer-force-complete (&optional start end _)
+ "Complete text between START and END to an exact match."
+ (declare (advertised-calling-convention (&optional start end) "30.1"))
(interactive "" minibuffer-mode)
- (let* ((string (car completion--input))
- (base (cdr completion--input))
- (base-size (length base))
- (prompt-end (minibuffer-prompt-end)))
- (setq completion--input nil)
- (unless (and string (< (+ prompt-end base-size) (point-max))
- ;; Don't restore if the base part has changed.
- (equal base (buffer-substring-no-properties
- prompt-end (+ prompt-end base-size))))
- (user-error "No partial completion input to restore"))
- (completion--replace (+ prompt-end base-size) (point-max) string)
- (when (get-buffer-window completions-buffer-name 0)
- ;; Refresh *Completions* buffer, if already visible.
- (minibuffer-completion-help))))
-
-(defun minibuffer-force-complete (&optional start end dont-cycle)
- "Complete the minibuffer to an exact match.
-Repeated uses step through the possible completions.
-DONT-CYCLE tells the function not to setup cycling."
- (interactive)
- (setq minibuffer-scroll-window nil)
;; FIXME: Need to deal with the extra-size issue here as well.
;; FIXME: ~/src/emacs/t<M-TAB>/lisp/minibuffer.el completes to
;; ~/src/emacs/trunk/ and throws away lisp/minibuffer.el.
- (let* ((start (copy-marker (or start (minibuffer--completion-prompt-end))))
+ (let* ((start (or start (minibuffer-prompt-end)))
(end (or end (point-max)))
- ;; (md (completion--field-metadata start))
(all (completion-all-sorted-completions start end))
+ (cur (car all))
(base (+ start (or (cdr (last all)) 0))))
- (cond
- ((not (consp all))
- (completion--message
- (if all "No more completions" "No completions")))
- ((not (consp (cdr all)))
- (let ((done (equal (car all) (buffer-substring-no-properties base end))))
- (unless done (completion--replace base end (car all)))
- (completion--done (buffer-substring-no-properties start (point))
- 'finished (when done "Sole completion"))))
- (t
- (completion--replace base end (car all))
- (setq end (+ base (length (car all))))
- (completion--done (buffer-substring-no-properties start (point)) 'sole)
- (setq this-command 'completion-at-point) ;For completion-in-region.
- ;; Set cycling after modifying the buffer since the flush hook resets it.
- (unless dont-cycle
- ;; If *Completions* is visible, highlight the current candidate.
- (when-let ((win (get-buffer-window completions-buffer-name 0))
- (pm (with-current-buffer completions-buffer-name
- (save-excursion
- (goto-char (point-min))
- (when-let ((pm (text-property-search-forward
- 'completion--string (car all) t)))
- (setq-local
- cursor-face-highlight-nonselected-window t)
- (goto-char (prop-match-beginning pm))
- (text-property-search-forward 'cursor-face))))))
- (set-window-point win (prop-match-beginning pm)))
- ;; If completing file names, (car all) may be a directory, so we'd now
- ;; have a new set of possible completions and might want to reset
- ;; completion-all-sorted-completions to nil, but we prefer not to,
- ;; so that repeated calls minibuffer-force-complete still cycle
- ;; through the previous possible completions.
+ (minibuffer-record-completion-input
+ (cond
+ ((atom all) (completion--message "No completions"))
+ ((atom (cdr all))
+ (let ((done (equal (car all) (buffer-substring-no-properties base end))))
+ (unless done (completion--replace base end cur))
+ (completion--done (buffer-substring-no-properties start (point))
+ 'finished (when done "Sole completion"))
+ (setq completion-all-sorted-completions nil)))
+ (t
+ (completion--replace base end cur)
+ (setq end (+ base (length cur)))
+ (completion--done (buffer-substring-no-properties start (point)) 'sole)
+ (minibuffer--highlight-in-completions cur)
(let ((last (last all)))
- (setcdr last (cons (car all) (cdr last)))
- (completion--cache-all-sorted-completions start end (cdr all)))
- ;; Make sure repeated uses cycle, even though completion--done might
- ;; have added a space or something that moved us outside of the field.
- ;; (bug#12221).
- (let* ((table minibuffer-completion-table)
- (pred minibuffer-completion-predicate)
- (extra-prop completion-extra-properties)
- (cmd
- (lambda () "Cycle through the possible completions."
- (interactive)
- (let ((completion-extra-properties extra-prop))
- (completion-in-region start (point) table pred)))))
- (setq completion-cycling
- (set-transient-map
- (let ((map (make-sparse-keymap)))
- (define-key map [remap completion-at-point] cmd)
- (define-key map (vector last-command-event) cmd)
- map)))))))))
+ (setcdr last (cons cur (cdr last)))
+ (setq completion-all-sorted-completions (cdr all)))
+ (set-transient-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (vector last-command-event)
+ #'minibuffer-cycle-completion)
+ map)
+ (lambda ()
+ (member this-command
+ '(universal-argument
+ negative-argument
+ digit-argument
+ minibuffer-cycle-completion)))
+ (lambda ()
+ (setq completion-all-sorted-completions nil))))))))
(defvar minibuffer-confirm-exit-commands
'(completion-at-point minibuffer-complete)
#'exit-minibuffer))
(defun completion-complete-and-exit (beg end exit-function)
- (completion--complete-and-exit
- beg end exit-function
- (lambda ()
- (pcase (condition-case nil
- (completion--do-completion beg end
- nil 'expect-exact)
- (error 1))
- ((or #b001 #b011) (funcall exit-function))
- (#b111 (if (not minibuffer-completion-confirm)
- (funcall exit-function)
- (minibuffer-message "Confirm")
- nil))
- (_ nil)))))
+ (minibuffer-record-completion-input
+ (completion--complete-and-exit
+ beg end exit-function
+ (lambda ()
+ (pcase (condition-case nil
+ (completion--do-completion beg end
+ nil 'expect-exact)
+ (error 1))
+ ((or #b001 #b011) (funcall exit-function))
+ (#b111 (if (not minibuffer-completion-confirm)
+ (funcall exit-function)
+ (minibuffer-message "Confirm")
+ nil))
+ (_ nil))))))
(defun completion--complete-and-exit (beg end
exit-function completion-function)
(defvar-local completions-ignore-case nil)
(defvar-local completions-action nil)
(defvar-local completions-style nil)
+(defvar-local completions-minibuffer-state nil)
(defvar completions-header-count
'(completions-candidates
(ngettext "" "s" (length styles))
(mapconcat #'symbol-name styles "', `"))))
-(defun minibuffer--cache-completion-input (string base)
- "Record STRING and BASE for `minibuffer-restore-completion-input'."
- (setq completion--input (cons string base)))
-
(defcustom minibuffer-completion-annotations t
"Whether to display annotations for completion candidates."
:type 'boolean
(cpred minibuffer-completion-predicate)
(ctable minibuffer-completion-table)
(action (minibuffer-completion-action)))
- (minibuffer--cache-completion-input (substring string base-size)
- full-base)
+
(when last (setcdr last nil))
;; Maybe highilight previously used completions.
:base-prefix base-prefix
:ignore-case completion-ignore-case
:annotations minibuffer-completion-annotations
+ :minibuffer-state (when (minibufferp)
+ (cons (minibuffer-contents) (point)))
:insert-choice-function
(let ((cprops completion-extra-properties))
(lambda (start end choice)
completions-predicate (plist-get plist :predicate)
completions-exceptional-candidates (plist-get plist :exceptional-candidates)
completions-ignore-case (plist-get plist :ignore-case)
- completions-action (plist-get plist :action)))
+ completions-action (plist-get plist :action)
+ completions-minibuffer-state (plist-get plist :minibuffer-state)))
(run-hooks 'completion-setup-hook)
(display-buffer buf
`((display-buffer-reuse-window display-buffer-at-bottom)
(defvar-keymap completion-in-region-mode-map
:doc "Keymap activated during `completion-in-region'."
- ;; FIXME: Only works if completion-in-region-mode was activated via
- ;; completion-at-point called directly.
- "M-?" #'completion-help-at-point
- "TAB" #'completion-at-point
- "M-<up>" #'minibuffer-previous-completion
- "M-<down>" #'minibuffer-next-completion
- "M-RET" #'minibuffer-choose-completion)
+ "M-?" #'completion-help-at-point
+ "M-<up>" #'minibuffer-previous-line-completion
+ "M-<down>" #'minibuffer-next-line-completion
+ "M-<left>" #'minibuffer-previous-completion
+ "M-<right>" #'minibuffer-next-completion
+ "M-RET" #'minibuffer-choose-completion)
;; It is difficult to know when to exit completion-in-region-mode (i.e. hide
;; the *Completions*). Here's how previous packages did it:
:doc "Local keymap for minibuffer input with completion."
:parent minibuffer-local-map
"TAB" #'minibuffer-complete
- "<backtab>" #'minibuffer-complete
"C-o" #'minibuffer-cycle-completion
"C-l" #'minibuffer-restore-completion-input
"C-S-a" #'minibuffer-toggle-completion-ignore-case
(defun completions-auto-update ()
"Update the *Completions* buffer, if it is visible."
(when (get-buffer-window completions-buffer-name 0)
- ;; Preserve current `completion--input'.
- (let ((completion--input completion--input))
- (if completion-in-region-mode
- (completion-help-at-point)
- (minibuffer-completion-help))))
+ (if completion-in-region-mode
+ (completion-help-at-point)
+ (minibuffer-completion-help)))
(setq completions-auto-update-timer nil))
(defun completions-auto-update-start-timer ()
:type 'float)
(defun minibuffer-hint ()
- (if-let ((all (let ((completion--input completion--input)
- (completion-lazy-hilit t)
+ (if-let ((all (let ((completion-lazy-hilit t)
completion-all-sorted-completions)
(completion-all-sorted-completions))))
(let ((minibuffer-message-timeout))