Function: Man-completion-table

Man-completion-table is a byte-compiled function defined in man.el.gz.

Signature

(Man-completion-table STRING PRED ACTION)

Source Code

;; Defined in /usr/src/emacs/lisp/man.el.gz
(defun Man-completion-table (string pred action)
  (cond
   ;; This ends up returning t for pretty much any string, and hence leads to
   ;; spurious "complete but not unique" messages.  And since `man' doesn't
   ;; require-match anyway, there's not point being clever.
   ;;((eq action 'lambda) (not (string-match "([^)]*\\'" string)))
   ((equal string "-k")
    ;; Let SPC (minibuffer-complete-word) insert the space.
    (complete-with-action action '("-k ") string pred))
   (t
    (let ((table (cdr Man-completion-cache))
          (section nil)
          (prefix string))
      (when (string-match "\\`\\([[:digit:]].*?\\) " string)
        (setq section (match-string 1 string))
        (setq prefix (substring string (match-end 0))))
      (unless (and Man-completion-cache
                   (string-prefix-p (car Man-completion-cache) prefix))
        (with-temp-buffer
          ;; In case inherited doesn't exist.
          (setq default-directory (Man-default-directory))
          ;; Actually for my `man' the arg is a regexp.
          ;; POSIX says it must be ERE and "man-db" seems to agree,
          ;; whereas under macOS it seems to be BRE-style and doesn't
          ;; accept backslashes at all.  Let's not bother to
          ;; quote anything.
          (let ((process-environment (copy-sequence process-environment)))
            (setenv "COLUMNS" "999") ;; don't truncate long names
            ;; manual-program might not even exist.  And since it's
            ;; run differently in Man-getpage-in-background, an error
            ;; here may not necessarily mean that we'll also get an
            ;; error later.
            (when (eq 0
                      (ignore-errors
                        (process-file
                         manual-program nil '(t nil) nil
                         "-k" (concat (when (or Man-man-k-use-anchor
                                                (string-equal prefix ""))
                                        "^")
                                      (if (string-equal prefix "")
                                          prefix
                                        ;; FIXME: shell-quote-argument
                                        ;; is not entirely
                                        ;; appropriate: we actually
                                        ;; need to quote ERE here.
                                        ;; But we don't have that, and
                                        ;; shell-quote-argument does
                                        ;; the job...
                                        (shell-quote-argument prefix))))))
              (setq table (Man-parse-man-k)))))
	;; Cache the table for later reuse.
        (when table
          (setq Man-completion-cache (cons prefix table))))
      ;; The table may contain false positives since the match is made
      ;; by "man -k" not just on the manpage's name.
      (if section
          (let ((re (concat "(" (regexp-quote section) ")\\'")))
            (dolist (comp (prog1 table (setq table nil)))
              (if (string-match re comp)
                  (push (substring comp 0 (match-beginning 0)) table)))
            (completion-table-with-context (concat section " ") table
                                           prefix pred action))
        ;; If the current text looks like a possible section name,
        ;; then add a completion entry that just adds a space so SPC
        ;; can be used to insert a space.
        (if (string-match "\\`[[:digit:]]" string)
            (push (concat string " ") table))
        (let ((res (complete-with-action action table string pred)))
          ;; In case we're completing to a single name that exists in
          ;; several sections, the longest prefix will look like "foo(".
          (if (and (stringp res)
                   (string-match "([^(]*\\'" res)
                   ;; In case the paren was already in `prefix', don't
                   ;; remove it.
                   (> (match-beginning 0) (length prefix)))
              (substring res 0 (match-beginning 0))
            res)))))))