Function: icomplete-completions
icomplete-completions is a byte-compiled function defined in
icomplete.el.gz.
Signature
(icomplete-completions NAME CANDIDATES PREDICATE REQUIRE-MATCH)
Documentation
Identify prospective candidates for minibuffer completion.
The display is updated with each minibuffer keystroke during minibuffer completion.
Prospective completion suffixes (if any) are displayed, bracketed by one of (), [], or {} pairs. The choice of brackets is as follows:
(...) - a single prospect is identified and matching is enforced,
[...] - a single prospect is identified but matching is optional, or
{...} - multiple prospects, separated by commas, are indicated, and
further input is required to distinguish a single one.
If there are multiple possibilities, icomplete-separator separates them.
The displays for unambiguous matches have [Matched] appended
(whether complete or not), or [No matches], if no eligible
matches exist.
Source Code
;; Defined in /usr/src/emacs/lisp/icomplete.el.gz
;;;_ > icomplete-completions (name candidates predicate require-match)
(defun icomplete-completions (name candidates predicate require-match)
"Identify prospective candidates for minibuffer completion.
The display is updated with each minibuffer keystroke during
minibuffer completion.
Prospective completion suffixes (if any) are displayed, bracketed by
one of (), [], or {} pairs. The choice of brackets is as follows:
(...) - a single prospect is identified and matching is enforced,
[...] - a single prospect is identified but matching is optional, or
{...} - multiple prospects, separated by commas, are indicated, and
further input is required to distinguish a single one.
If there are multiple possibilities, `icomplete-separator' separates them.
The displays for unambiguous matches have ` [Matched]' appended
\(whether complete or not), or ` [No matches]', if no eligible
matches exist."
(let* ((ignored-extension-re
(and minibuffer-completing-file-name
icomplete-with-completion-tables
completion-ignored-extensions
(concat "\\(?:\\`\\.\\./\\|"
(regexp-opt completion-ignored-extensions)
"\\)\\'")))
(minibuffer-completion-table candidates)
(minibuffer-completion-predicate
(if ignored-extension-re
(lambda (cand)
(and (not (string-match ignored-extension-re cand))
(or (null predicate)
(funcall predicate cand))))
predicate))
(md (completion--field-metadata (icomplete--field-beg)))
(comps (icomplete--sorted-completions))
(open-bracket (if require-match "(" "["))
(close-bracket (if require-match ")" "]")))
;; `concat'/`mapconcat' is the slow part.
(if (not (consp comps))
(progn ;;(debug (format "Candidates=%S field=%S" candidates name))
(format " %sNo matches%s" open-bracket close-bracket))
(if icomplete-vertical-mode
(icomplete--render-vertical comps md)
(let* ((last (if (consp comps) (last comps)))
;; Save the "base size" encoded in `comps' then
;; removing making `comps' a proper list.
(base-size (prog1 (cdr last)
(if last (setcdr last nil))))
(most-try
;; icomplete-hide-common-prefix logic is used
;; unconditionally when there is single match.
(when (or icomplete-hide-common-prefix (not (cdr comps)))
(if (and base-size (> base-size 0))
(completion-try-completion
name candidates predicate (length name) md)
;; If the `comps' are 0-based, the result should be
;; the same with `comps'.
(completion-try-completion
name comps nil (length name) md))))
(most (if (consp most-try) (car most-try)
(if most-try (car comps) "")))
;; Compare name and most, so we can determine if name is
;; a prefix of most, or something else.
(compare (compare-strings name nil nil
most nil nil completion-ignore-case))
(ellipsis (if (char-displayable-p ?…) "…" "..."))
(determ (unless (or (eq t compare) (eq t most-try)
(= (setq compare (1- (abs compare)))
(length most)))
(concat open-bracket
(cond
((= compare (length name))
;; Typical case: name is a prefix.
(substring most compare))
;; Don't bother truncating if it doesn't gain
;; us at least 2 columns.
((< compare (+ 2 (string-width ellipsis))) most)
(t (concat ellipsis (substring most compare))))
close-bracket)))
;;"-prospects" - more than one candidate
(prospects-len (+ (string-width
(or determ (concat open-bracket close-bracket)))
(string-width icomplete-separator)
(+ 2 (string-width ellipsis)) ;; take {…} into account
(string-width
(buffer-substring (save-excursion
(goto-char (icomplete--field-beg))
(pos-bol))
(icomplete--field-end)))))
(prospects-max
;; Max total length to use, including the minibuffer content.
(* (+ icomplete-prospects-height
;; If the minibuffer content already uses up more than
;; one line, increase the allowable space accordingly.
(/ prospects-len (window-width)))
(window-width)))
;; Find the common prefix among `comps'.
;; We can't use the optimization below because its assumptions
;; aren't always true, e.g. when completion-cycling (bug#10850):
;; (if (eq t (compare-strings (car comps) nil (length most)
;; most nil nil completion-ignore-case))
;; ;; Common case.
;; (length most)
;; Else, use try-completion.
(prefix (when icomplete-hide-common-prefix
(try-completion "" comps)))
(prefix-len
(and (stringp prefix)
;; Only hide the prefix if the corresponding info
;; is already displayed via `most'.
(string-prefix-p prefix most t)
(length prefix))) ;;)
prospects comp limit)
(prog1
(if (or (eq most-try t) (and (not icomplete-scroll)
(not (consp (cdr comps)))))
(concat determ " [Matched]")
(when (member name comps)
;; NAME is complete but not unique. This scenario poses
;; following UI issues:
;;
;; - When `icomplete-hide-common-prefix' is non-nil, NAME
;; is stripped empty. This would make the entry
;; inconspicuous.
;;
;; - Due to sorting of completions, NAME may not be the
;; first of the prospects and could be hidden deep in
;; the displayed string.
;;
;; - Because of `icomplete-prospects-height' , NAME may
;; not even be displayed to the user.
;;
;; To circumvent all the above problems, provide a visual
;; cue to the user via an "empty string" in the try
;; completion field.
(setq determ (concat open-bracket "" close-bracket)))
(while (and comps (not limit))
(setq comp
(let ((cur (completion-lazy-hilit (car comps))))
(if prefix-len (substring cur prefix-len) cur))
comps (cdr comps))
(setq prospects-len
(+ (string-width comp)
(string-width icomplete-separator)
prospects-len))
(if (< prospects-len prospects-max)
(push comp prospects)
(setq limit t)))
(setq prospects (nreverse prospects))
;; Decorate first of the prospects.
(when prospects
(let ((first (copy-sequence (pop prospects))))
(put-text-property 0 (length first)
'face 'icomplete-first-match first)
(push first prospects)))
(concat determ
"{"
(mapconcat #'identity prospects icomplete-separator)
(concat (and limit (concat icomplete-separator ellipsis))
"}")))
;; Restore the base-size info, since completion-all-sorted-completions
;; is cached.
(if last (setcdr last base-size))))))))