Function: completion--do-completion

completion--do-completion is a byte-compiled function defined in minibuffer.el.gz.

Signature

(completion--do-completion BEG END &optional TRY-COMPLETION-FUNCTION EXPECT-EXACT)

Documentation

Do the completion and return a summary of what happened.

M = completion was performed, the text was Modified. C = there were available Completions. E = after completion we now have an Exact match.

 MCE
 000 0 no possible completion
 001 1 was already an exact and unique completion
 010 2 no completion happened
 011 3 was already an exact completion
 100 4 ??? impossible
 101 5 ??? impossible
 110 6 some completion happened
 111 7 completed to an exact completion

TRY-COMPLETION-FUNCTION is a function to use in place of try-completion. EXPECT-EXACT, if non-nil, means that there is no need to tell the user when the buffer's text is already an exact match.

Source Code

;; Defined in /usr/src/emacs/lisp/minibuffer.el.gz
(defun completion--do-completion (beg end &optional
                                      try-completion-function expect-exact)
  "Do the completion and return a summary of what happened.
M = completion was performed, the text was Modified.
C = there were available Completions.
E = after completion we now have an Exact match.

 MCE
 000  0 no possible completion
 001  1 was already an exact and unique completion
 010  2 no completion happened
 011  3 was already an exact completion
 100  4 ??? impossible
 101  5 ??? impossible
 110  6 some completion happened
 111  7 completed to an exact completion

TRY-COMPLETION-FUNCTION is a function to use in place of `try-completion'.
EXPECT-EXACT, if non-nil, means that there is no need to tell the user
when the buffer's text is already an exact match."
  (let* ((string (buffer-substring beg end))
         (md (completion--field-metadata beg))
         (comp (funcall (or try-completion-function
                            #'completion-try-completion)
                        string
                        minibuffer-completion-table
                        minibuffer-completion-predicate
                        (- (point) beg)
                        md)))
    (cond
     ((null comp)
      (minibuffer-hide-completions)
      (unless completion-fail-discreetly
	(ding)
	(completion--message "No match"))
      (minibuffer--bitset nil nil nil))
     ((eq t comp)
      (minibuffer-hide-completions)
      (goto-char end)
      (completion--done string 'finished
                        (unless expect-exact "Sole completion"))
      (minibuffer--bitset nil nil t))   ;Exact and unique match.
     (t
      ;; `completed' should be t if some completion was done, which doesn't
      ;; include simply changing the case of the entered string.  However,
      ;; for appearance, the string is rewritten if the case changes.
      (let* ((comp-pos (cdr comp))
             (completion (car comp))
             (completed (not (string-equal-ignore-case completion string)))
             (unchanged (string-equal completion string)))
        (if unchanged
	    (goto-char end)
          ;; Insert in minibuffer the chars we got.
          (completion--replace beg end completion)
          (setq end (+ beg (length completion))))
	;; Move point to its completion-mandated destination.
	(forward-char (- comp-pos (length completion)))

        (if (not (or unchanged completed))
            ;; The case of the string changed, but that's all.  We're not sure
            ;; whether this is a unique completion or not, so try again using
            ;; the real case (this shouldn't recurse again, because the next
            ;; time try-completion will return either t or the exact string).
            (completion--do-completion beg end
                                       try-completion-function expect-exact)

          ;; 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)
            (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*" 0))
                  ('always t))
                (minibuffer-completion-help beg end))
               (t (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
                    ('lazy (eq this-command last-command))
                    (_ completion-auto-help))
                  (minibuffer-completion-help beg end)
                (completion--message "Next char not unique")))
             ;; If the last exact completion and this one were the same, it
             ;; means we've already given a "Complete, but not unique" message
             ;; and the user's hit TAB again, so now we give him help.
             (t
              (if (and (eq this-command last-command) completion-auto-help)
                  (minibuffer-completion-help beg end))
              (completion--done completion 'exact
                                (unless (or expect-exact
                                            (and completion-auto-select
                                                 (eq this-command last-command)
                                                 completion-auto-help))
                                  "Complete, but not unique"))))

            (minibuffer--bitset completed t exact))))))))