first (@code{minibuffer-complete-and-exit}). @xref{Completion Exit}.
@item ?
Display a list of completions (@code{minibuffer-completion-help}).
+@item C-o
+Cycle minibuffer input among possible completion candidates
+(@code{minibuffer-cycle-completion}).
+@item C-l
+Restore the minibuffer input that Emacs used to compute the current
+set of completion candidates.
+(@code{minibuffer-restore-completion-input}).
@item C-x C-v
Change the order of the list of possible completions
(@code{minibuffer-sort-completions}).
the minibuffer, or completes it and then submits it, depending on the
``strictness'' of the completion. @xref{Completion Exit}.
+@cindex cycle completions
+@cindex completions cycling
+@kindex C-o @r{(completion)}
+@findex minibuffer-cycle-completion
+ @kbd{C-o} (@code{minibuffer-cycle-completion}) cycles among the list
+of possible completions. The first time you hit @kbd{C-o}, it expands
+your partial input in the minibuffer to the first matching completion
+candidate. Another @kbd{C-o} replaces the minibuffer contents with
+the next completion candidate, and repeating @kbd{C-o} lets you cycle
+among all completions for your initial input, wrapping around when you
+reach the end of the list. While you're cycling, Emacs remembers the
+initial partial input you started with, and the corresponding set of
+completion candidates. If you edit a completion candidate in the
+minibuffer after cycling to it, that tells Emacs to forget about your
+previous partial input and compute a new set of completion candidates
+based on your new input the next time you hit @kbd{C-o}. You can
+invoke @kbd{C-o} with a numeric prefix argument @var{n} to cycle
+@var{n} candidates forward at once. A negative @var{n} cycles
+backward instead. A prefix argument of zero (@kbd{C-0 C-o}) switches
+the cycling direction, so the next @kbd{C-o} presses cycle backward.
+
+@kindex C-l @r{(completion)}
+@findex minibuffer-restore-completion-input
+ @kbd{C-l} (@code{minibuffer-restore-completion-input}) restores the
+minibuffer contents to the (partial) input that you last used for
+completion in the current minibuffer. Commands that complete your
+input, such as @kbd{@key{TAB}} and @kbd{C-o}, record the partial input
+that you provide them for you to later retrieve it with @kbd{C-l}.
+For example, if you type @kbd{M-x bar} and start cycling with
+@kbd{C-o}, only to realize that you want a candidate that matches
+@samp{baz} and not @samp{bar}, then you can type @kbd{C-l} to restore
+the minibuffer input to @samp{bar}, change it to @samp{baz} and
+complete again.
+
+@anchor{Sort Completions}
+@cindex sort completions
+@cindex completions sort order
@kindex C-x C-v @r{(completion)}
@findex minibuffer-sort-completions
- @key{C-x C-v} (@code{minibuffer-sort-completions}) changes the order
+ @kbd{C-x C-v} (@code{minibuffer-sort-completions}) changes the order
of the completions list. By default, Emacs sorts the list of possible
completion candidates in the order that you specify in user option
@code{completions-sort} (@pxref{Completion Options}). This command
@vindex completion-cycle-threshold
If @code{completion-cycle-threshold} is non-@code{nil}, completion
-commands can cycle through completion alternatives. Normally, if
-there is more than one completion alternative for the text in the
-minibuffer, a completion command completes up to the longest common
-substring. If you change @code{completion-cycle-threshold} to
-@code{t}, the completion command instead completes to the first of
-those completion alternatives; each subsequent invocation of the
-completion command replaces that with the next completion alternative,
-in a cyclic manner. If you give @code{completion-cycle-threshold} a
-numeric value @var{n}, completion commands switch to this cycling
-behavior only when there are @var{n} or fewer alternatives.
+commands such as @kbd{@key{TAB}} can cycle through completion
+alternatives. Normally, if there is more than one completion
+alternative for the text in the minibuffer, a completion command
+completes up to the longest common substring. If you change
+@code{completion-cycle-threshold} to @code{t}, the completion command
+instead behaves like @kbd{C-o} (@code{minibuffer-cycle-completion}):
+it completes to the first of those completion alternatives; each
+subsequent invocation of the completion command replaces that with the
+next completion alternative, in a cyclic manner. If you give
+@code{completion-cycle-threshold} a numeric value @var{n}, completion
+commands switch to this cycling behavior only when there are @var{n}
+or fewer alternatives.
@vindex completions-format
When displaying completions, Emacs will normally pop up a new buffer
This function completes the minibuffer contents as far as possible.
@end deffn
+@deffn Command minibuffer-cycle-completion
+This function expands the current minibuffer contents to the first
+matching completion, and cycles among all matching candidates if you
+call it repeatedly.
+@end deffn
+
+@deffn Command minibuffer-restore-completion-input
+This function restores the last input that a completion command, such
+as @code{minibuffer-complete}, expanded in the current minibuffer.
+@end deffn
+
@deffn Command minibuffer-complete-and-exit
This function completes the minibuffer contents, and exits if
confirmation is not required, i.e., if
@item @key{TAB}
@code{minibuffer-complete}
+@item C-o
+@code{minibuffer-cycle-completion}
+
+@item C-l
+@code{minibuffer-restore-completion-input}
+
@item C-x C-v
@code{minibuffer-sort-completions}
list of possible completions. By default, this keymap makes the
following bindings:
-@table @asis
+@table @kbd
@item n
@code{minibuffer-narrow-completions-to-current}
minibuffer unconditionally. By default, this keymap makes the following
bindings:
-@table @asis
-@item @kbd{C-j}
+@table @kbd
+@item C-j
@code{minibuffer-complete-and-exit}
@item @key{RET}
invoke this command with a negative prefix argument ('C-- C-x C-v'),
it reverses the current order.
-*** New minor mode 'completions-auto-update-mode'.
-This global minor mode automatically updates the *Completions* buffer
-as you type in the minibuffer.
++++
+*** New command 'minibuffer-cycle-completion'.
+This command, bound to 'C-o' in the minibuffer, expands the current
+minibuffer contents to the first matching completion, and cycles among
+all matching candidates if you call it repeatedly. This is similar to
+'minibuffer-complete' ('TAB' in the minibuffer) with non-nil
+'completion-cycle-threshold', except that
+'minibuffer-cycle-completion' always cycles, regardless of the value
+of 'completion-cycle-threshold' and the number of completion
+candidates.
+
++++
+*** New command 'minibuffer-restore-completion-input.
+This command, bound to 'C-l' in the minibuffer, restores the (partial)
+input that you last used for completion in the current minibuffer.
+++
*** New command 'crm-change-separator'.
(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 completion-tab-width nil)
('always t))
(minibuffer-completion-help beg end))
(t (minibuffer-hide-completions)
+ (minibuffer--cache-completion-input
+ string (car (completion-boundaries
+ string
+ minibuffer-completion-table
+ minibuffer-completion-predicate "")))
(when exact
;; If completion did not put point at end of field,
;; it's a sign that completion is not finished.
base-size md
minibuffer-completion-table
minibuffer-completion-predicate))
- (sort-fun (completion-metadata-get all-md 'cycle-sort-function))
+ (sort-fun
+ (or minibuffer-completions-sort-function
+ (completion-metadata-get all-md 'cycle-sort-function)))
(group-fun (completion-metadata-get all-md 'group-function)))
(when last
(setcdr last nil)
(substring string 0 base-size))
all)))))
+ ;; Cache input for `minibuffer-restore-completion-input',
+ ;; unless STRING is an exact and sole completion.
+ (unless (and (not (consp (cdr all))) (equal (car all) string))
+ (minibuffer--cache-completion-input string 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.
;; If a match is not required, exit after all.
(exit-minibuffer)))))
+(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))))
+
+(defun minibuffer-cycle-completion (arg)
+ "Cycle minibuffer input to the ARGth next completion.
+
+If ARG is negative, cycle back that many completion candidates.
+If ARG is 0, change cycling direction.
+
+Interactively, ARG is the prefix argument, and it defaults to 1."
+ (interactive "p" minibuffer-mode)
+ (let* ((times (abs arg)))
+ (when (< arg 1) (completion-switch-cycling-direction))
+ (if (< 0 times)
+ (dotimes (_ times) (minibuffer-force-complete))
+ (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."
+ (interactive "" minibuffer-mode)
+ (when completion--input
+ (completion--replace (+ (minibuffer-prompt-end) (cdr completion--input))
+ (point-max)
+ (car completion--input))))
+
(defun minibuffer-force-complete (&optional start end dont-cycle)
"Complete the minibuffer to an exact match.
Repeated uses step through the possible completions.
(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*" 0))
+ (pm (with-current-buffer "*Completions*"
+ (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,
(ngettext "" "s" (length styles))
(mapconcat #'symbol-name styles "', `"))))
+(defun minibuffer--cache-completion-input (string base-size)
+ "Record STRING and BASE-SIZE for `minibuffer-restore-completion-input'."
+ (setq completion--input (cons (substring string base-size) base-size)))
+
(defun minibuffer-completion-help (&optional start end)
"Display a list of possible completions of the current minibuffer contents."
(interactive)
minibuffer-completion-table
minibuffer-completion-predicate
(- (point) start)
- md)))
+ md))
+ (last (last completions))
+ (base-size (or (cdr last) 0)))
+ (minibuffer--cache-completion-input string base-size)
(message nil)
(if (or (null completions)
(and (not (consp (cdr completions)))
(completion--message "Sole completion")
(completion--fail)))
- (let* ((last (last completions))
- (base-size (or (cdr last) 0))
- (prefix (unless (zerop base-size) (substring string 0 base-size)))
+ (let* ((prefix (unless (zerop base-size) (substring string 0 base-size)))
(minibuffer-completion-base (substring string 0 base-size))
(base-prefix (buffer-substring (minibuffer--completion-prompt-end)
(+ start base-size)))
:parent minibuffer-local-map
"TAB" #'minibuffer-complete
"<backtab>" #'minibuffer-complete
- ;; M-TAB is already abused for many other purposes, so we should find
- ;; another binding for it.
- ;; "M-TAB" #'minibuffer-force-complete
+ "C-o" #'minibuffer-cycle-completion
+ "C-l" #'minibuffer-restore-completion-input
"SPC" #'minibuffer-complete-word
"?" #'minibuffer-completion-help
"<prior>" #'switch-to-completions
(defun completions-auto-update ()
"Update the *Completions* buffer, if it is visible."
(when (get-buffer-window "*Completions*" 0)
- (if completion-in-region-mode
- (completion-help-at-point)
- (minibuffer-completion-help)))
+ ;; Preserve current `completion--input'.
+ (let ((completion--input completion--input))
+ (if completion-in-region-mode
+ (completion-help-at-point)
+ (minibuffer-completion-help))))
(setq completions-auto-update-timer nil))
(defun completions-auto-update-start-timer ()
(let ((executing-kbd-macro t)) ; Force the real minibuffer
(completing-read "Prompt: " ,collection)))))
+(ert-deftest restore-completion-input-test ()
+ (completing-read-with-minibuffer-setup
+ '("foo" "food" "bar" "baz")
+ (execute-kbd-macro (kbd "b TAB"))
+ (should (equal (minibuffer-contents) "ba"))
+ (execute-kbd-macro (kbd "C-l"))
+ (should (equal (minibuffer-contents) "b"))
+ (execute-kbd-macro (kbd "DEL f C-o C-o C-o"))
+ (should (equal (minibuffer-contents) "foo"))
+ (execute-kbd-macro (kbd "C-l"))
+ (should (equal (minibuffer-contents) "f"))
+ (execute-kbd-macro (kbd "M-<down> M-<down>"))
+ (should (equal (minibuffer-contents) "food"))
+ (execute-kbd-macro (kbd "C-l"))
+ (should (equal (minibuffer-contents) "f"))))
+
(ert-deftest completion-auto-help-test ()
(let (messages)
(cl-letf* (((symbol-function 'minibuffer-message)