2

Continued from this post:

(setq completions '("~/org/test-file-1.org" "~/org/test-file-2.org")) ; C-x C-e
(defun mybar()
(newline-and-indent)
(insert-file-contents (completing-read "Type something, use TAB for completion: " completions nil t))) ; C-x C-e
(mybar) ; C-x C-e

enter image description here

Following these evaluations, in the minibuffer: (1) The first TAB gets the longest common prefix (2) a second TAB is needed to pop up a *Completions* buffer with the complete list of candidates.

Assuming the candidate files share a non empty common prefix, how would one modify the code above to automate step (1), and to jump to (2) for the stated pattern (test-file-[digit].org)?

PS: and also, once the candidate files are displayed, one has to (3) activate the completions buffer and (4) select a file from there. I wished (3) could be automated too.

C-h o completing-read

completing-read is a built-in function in ‘C source code’.

(completing-read PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)

Read a string in the minibuffer, with completion. PROMPT is a string to prompt with; normally it ends in a colon and a space. COLLECTION can be a list of strings, an alist, an obarray or a hash table. COLLECTION can also be a function to do the completion itself. PREDICATE limits completion to a subset of COLLECTION. See ‘try-completion’, ‘all-completions’, ‘test-completion’, and ‘completion-boundaries’, for more details on completion, COLLECTION, and PREDICATE. See also Info node ‘(elisp)Basic Completion’ for the details about completion, and Info node ‘(elisp)Programmed Completion’ for expectations from COLLECTION when it’s a function.

REQUIRE-MATCH can take the following values:

  • t means that the user is not allowed to exit unless the input is (or completes to) an element of COLLECTION or is null.
  • nil means that the user can exit with any input.
  • ‘confirm’ means that the user can exit with any input, but she needs to confirm her choice if the input is not an element of COLLECTION.
  • ‘confirm-after-completion’ means that the user can exit with any input, but she needs to confirm her choice if she called
    ‘minibuffer-complete’ right before ‘minibuffer-complete-and-exit’
    and the input is not an element of COLLECTION.
  • anything else behaves like t except that typing RET does not exit if it does non-null completion.

If the input is null, ‘completing-read’ returns DEF, or the first element of the list of default values, or an empty string if DEF is nil, regardless of the value of REQUIRE-MATCH.

If INITIAL-INPUT is non-nil, insert it in the minibuffer initially,
with point positioned at the end. If it is (STRING . POSITION), the
initial input is STRING, but point is placed at zero-indexed
position POSITION in STRING. (Note that this is different from
‘read-from-minibuffer’ and related functions, which use one-indexing
for POSITION.) This feature is deprecated--it is best to pass nil
for INITIAL-INPUT and supply the default value DEF instead. The
user can yank the default value into the minibuffer easily using
M-n.

HIST, if non-nil, specifies a history list and optionally the initial position in the list. It can be a symbol, which is the history list
variable to use, or it can be a cons cell (HISTVAR . HISTPOS). In
that case, HISTVAR is the history list variable to use, and HISTPOS
is the initial position (the position in the list used by the
minibuffer history commands). For consistency, you should also
specify that element of the history as the value of INITIAL-INPUT.
(This is the only case in which you should use INITIAL-INPUT instead
of DEF.) Positions are counted starting from 1 at the beginning of
the list. The variable ‘history-length’ controls the maximum length
of a history list. If HIST is t, history is not recorded.

DEF, if non-nil, is the default value or the list of default values.

If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits the
current input method and the setting of ‘enable-multibyte-characters’.

Completion ignores case if the ambient value of
‘completion-ignore-case’ is non-nil.

See also ‘completing-read-function’.

Probably introduced at or before Emacs version 1.6.

2
  • 1
    One way to do it is to calculate the common prefix yourself and provide it to completing-read as the INITIAL-INPUT argument (see the doc string C-h v completing-read for usage).
    – NickD
    Commented Mar 30, 2023 at 16:41
  • "... one has to (3) activate the completions buffer and (4) select a file from there." Are you using a GUI Emacs? If so, all you have to do is click on it.
    – NickD
    Commented Mar 30, 2023 at 20:25

2 Answers 2

1

Apart from @NickD's helpful comment that you can calculate the common prefix yourself (maybe it should be an answer instead of just a comment):


No, as far as I know, vanilla Emacs doesn't show matches without user input (TAB).

(Various 3rd-party completion frameworks can do this. Icicles has offered this incremental completion since 2005, for instance.)

M-x report-emacs-bug for enhancement requests. See option completion-auto-help, for example -- you might want to request another value for this option that does what you want (show completions without having to hit TAB).

1
  • Given my noted propensity to not get things, I think it would be better for someone who does to do an enhancement request.
    – user19777
    Commented Mar 30, 2023 at 18:09
1

[I made my comment into an answer and supplied an implementation of longest common prefix as well].

The first TAB typed in completing-read's prompt fills in the longest common prefix of the completions. The second TAB then shows you the list of completiong for you to choose. If instead you type something else and then press TAB again, completion will limit the available choices further. You can continue like this until there is only one choice left and the final TAB completes the input to match that choice.

If you want the first TAB to just list all your choices, one way to do it is to calculate the common prefix yourself and provide it to completing-read as the INITIAL-INPUT argument. As the doc string of completing-read says:

If INITIAL-INPUT is non-nil, insert it in the minibuffer initially, with point positioned at the end.

It's as if you typed it in up to that point, so pressing TAB pops up a *Completions* buffer with all the choices.

Let's assume that there is a function lcp that takes a list of strings and returns the longest common prefix of all the string in the list. For convenience, we'll assume that the list is already sorted (which is no burden, since you will probably get it by calling directory-files which sorts the list by default).

So if completions is the list of all completions, then (lcp completions) will be the longest common prefix of all the completions. In your example, it will return "~/org/test-file-". Then you can use that as the INITIAL-INPUT argument of completing-read:

   ...
   (completing-read "PROMPT: " completions nil t (lcp completions))
   ...

Here's an implementation of lcp:

  (defun my/longest-common-prefix (list-of-strings)
    "Longest common prefix of strings in a list.
  The list is assumed to be sorted (but we really only need
  the (lexicographically) smallest and largest strings:
  the first and last elements of the list if the list is sorted)."
    (let ((s1 (first sl))
          (s2 (car (last sl)))
          (i 0))
      (while (eq (aref s1 i) (aref s2 i))
        (setq i (1+ i)))
      (substring s1 0 i)))

It assumes that the list of strings handed to it is sorted, so that the "smallest" element (lexicographically speaking) is the first element and the "largest" element is the last element of the list. If we find the longest common prefix of these two, we have found the longest common prefix of the whole list.

The rest of the calculation steps through the two strings one position at a time and compares the characters at that position. If they are the same, it increments the position and goes around the loop again. If they are different, the loop exits and at that point we know that the two strings have the same characters at each position from 0 to one before the last position checked. So we return the substring of the first string (or the second or any other string in the list) starting at position 0 and ending at one less than the last position checked (Lisp strings, like Python strings and C strings start at position 0): (substring s1 0 i)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.