emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Possible minibuffer completion enhancements


From: Eshel Yaron
Subject: Possible minibuffer completion enhancements
Date: Sun, 14 Jan 2024 18:28:27 +0100
User-agent: Gnus/5.13 (Gnus v5.13)

Hello Emacs,

I have a few enhancements in my working branch that revolve around
inspecting and modifying minibuffer completion settings interactively.
These additions (described below) are backward compatible, documented,
and, at times, even useful.  So I propose adding them to upstream.

You can try out and examine these changes by cloning from
https://git.sr.ht/~eshel/emacs and building Emacs as usual.

[ git.sr.ht has been having some connectivity issues in the past few
  days, to put it mildly, so in case it doesn't work, you can also find
  the code at git://git.eshelyaron.com/emacs.git ]

If any of this looks like it might be appropriate for upstream Emacs,
I'll format and submit the relevant parts as individual patches.

There are five additions that can be considered, together or separately:

1. Interactively narrow (restrict) the list of minibuffer completions

   This lets you filter the list of possible completions.  A new Info
   node "Completions Narrowing" describes this feature in full:

     When there are many possible completion candidates, you may want to
     narrow the selection to a smaller subset by filtering out some of the
     options.  You can use the commands ‘C-x n n’ and ‘C-x n m’ in the
     minibuffer to restrict the completions list.  Narrowing the list of
     minibuffer completions is different from narrowing buffers (*note
     Narrowing::), although the two are conceptually related since both allow
     you to focus on some part of a larger whole.

     ‘C-x n n’ (‘minibuffer-narrow-completions-to-current’) restricts the
     list of possible completions to only include candidates that match the
     current minibuffer input.  This command clears the minibuffer so you can
     type another (partial) input and complete it with completion candidates
     that also match the previous input.  If you call this command with a
     negative prefix argument (‘C-- C-x n n’), it instead excludes all
     matches for the current input from subsequent completions.

     ‘C-x n m’ (‘minibuffer-narrow-completions’) is similar to ‘C-x n n’,
     but more versatile.  This command restricts the list of possible
     completions in different ways, depending on what kind of completion
     candidates you're dealing with.  For example, commands that read a
     symbol name from the minibuffer, such as ‘C-h f’ and ‘C-h o’ (*note Name
     Help::), let you restrict the completions list with ‘C-x n m’ to show
     only symbols with a given property.  *Note (elisp)Symbol Properties::.
     Similarly, commands that read a buffer name, such as ‘C-x b’ (*note
     Select Buffer::), make ‘C-x n m’ restrict the completions list by
     candidate buffer major mode.  When the command does not provide a
     specific way of restricting completion candidates, ‘C-x n m’ prompts you
     for a regular expression and narrows the completions list to only
     include candidates which match that regular expression.  *Note
     Regexps::.

     When you narrow the completions list with ‘C-x n n’ or with ‘C-x n m’,
     Emacs extends the completions heading line with a description of the
     restriction that is currently in effect (*note Completions Heading
     Line::).  The mode line of the ‘*Completions*’ buffer also indicates the
     restriction with the text ‘CompsNarrow’.  You can apply multiple
     restrictions one after the other to narrow the completions list
     incrementally.  For example, typing ‘M-x C-x n m foo <RET> C-x n m bar
     <RET>’ shows only commands that match both ‘foo’ and ‘bar’ in the
     completions list.

     Use ‘C-x n w’ (‘minibuffer-widen-completions’) in the minibuffer to
     remove the restrictions on the list of possible completions that you set
     with ‘C-x n n’ or with ‘C-x n m’.  ‘C-x n w’ prompts you for the
     description of a current completions restriction, and removes the
     corresponding restriction.  The default candidate is the most recent
     restriction, and you can use completion to select other restriction
     descriptions.  You can even specify multiple restrictions to remove at
     once, by separating their descriptions with commas in the minibuffer.
     If there is only one restriction to begin with, ‘C-x n w’ removes it
     without prompting.  If you invoke this command with a prefix argument
     (‘C-u C-x n w’), it removes all restrictions without prompting,
     regardless of how many there are.

2. Interactively sort the list of minibuffer completions

   This lets you change the order of the completions list by invoking a
   command in the minibuffer.  Here's the gist of it:

     ‘C-x C-v’ (‘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
     ‘completions-sort’ (*note Completion Options::).  This command lets you
     change the order of the current completions list interactively.  You can
     invoke it with a negative prefix argument (‘C-- C-x C-v’) to reverse the
     current order.  The user option ‘minibuffer-completions-sort-orders’
     determines which orders this command suggests for sorting the
     completions list.  By default, this includes alphabetical sorting,
     sorting by candidate position in the minibuffer history, and no sorting
     at all.  Some commands that use minibuffer completion also provide
     additional sorting options that are specifically useful with their
     completion candidates.  For example, during file name completion, as in
     ‘C-x C-f’ (*note Visiting::), you can use ‘C-x C-v’ to sort candidate
     file names chronologically by their last modified time.

   Another possibly interesting detail is that the completions heading
   line indicates a non-default sorting order; for example, it might say
   "70 possible completions, sorted alphabetically...".  This is
   customizable via the existing `completions-header-format` option,
   which is extended accordingly (in a backward compatible manner).

3. Interactively set the completion styles for the current minibuffer

   This lets you modify the completion styles that the current
   minibuffer makes use of, on the fly:

     ‘C-x /’ (minibuffer-set-completion-styles) lets you set the
     completion styles for the current minibuffer.  *Note Completion
     Styles::.  This command prompts you for a list of completion styles, and
     sets that list as the effective completion styles for following
     completion operations in the current minibuffer.  With a plain prefix
     argument (‘C-u C-x /’), it instead discards all changes that you made to
     the current completion styles.  With a zero numeric prefix argument
     (‘C-0 C-x /’), it keeps all current completion styles except the style
     that produced that current completions list.  Conversely, a numeric
     prefix argument of one (‘C-1 C-x /’) says to keep only the completion
     style that produced the current completions list, disabling other
     completion styles for the current minibuffer.

     ...

     The mode line of the ‘*Completions*’ buffer indicates which
     completion style produced the listed completion candidates, by showing
     the name of that style.  (For example, the mode line says
     ‘Completions[basic]’ when the ‘basic’ completion style is in effect.)
     You can hover over the mode line style indicator with the mouse to see
     its full description.

4. Interactively replace the separator in `completing-read-multiple`

   This lets you examine and change the regular expression that matches
   input separators in a `completing-read-multiple` minibuffer:

     When displaying the completions list for ‘completing-read-multiple’,
     the mode line of the ‘*Completions*’ buffer includes an indicator that
     says ‘Multi’.  Hovering over that indicator with the mouse shows
     help about the current input separator.

     ...

     [‘crm-change-separator’], bound to ‘C-x ,’ in the minibuffer during
     ‘completing-read-multiple’, changes the current input separator.
     It prompts for a new separator regular expression, and sets the
     local value of ‘crm-separator’ to that regular expression.  With a
     prefix argument, this command also prompts for a replacement string
     (that should match the new separator) and replaces all of the
     existing separators in the minibuffer with that replacement string.

5. Cycling completions convenience commands

   This adds a dedicated command for cycling completions so you can make
   use of both cycling and the regular completion behavior at any time.
   Another new command lets you restore the minibuffer contents to the
   partial input you had when you started cycling:

     ‘C-o’ (‘minibuffer-cycle-completion’) cycles among the list of
     possible completions.  The first time you hit ‘C-o’, it expands your
     partial input in the minibuffer to the first matching completion
     candidate.  Another ‘C-o’ replaces the minibuffer contents with the next
     completion candidate, and repeating ‘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 ‘C-o’.  You can invoke ‘C-o’ with a numeric
     prefix argument N to cycle N candidates forward at once.  A negative N
     cycles backward instead.  A prefix argument of zero (‘C-0 C-o’) switches
     the cycling direction, so the next ‘C-o’ presses cycle backward.

     ‘C-l’ (‘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 ‘<TAB>’
     and ‘C-o’, record the partial input that you provide them for you to
     later retrieve it with ‘C-l’.  For example, if you type ‘M-x bar’ and
     start cycling with ‘C-o’, only to realize that you want a candidate that
     matches ‘baz’ and not ‘bar’, then you can type ‘C-l’ to restore the
     minibuffer input to ‘bar’, change it to ‘baz’ and complete again.


The overall theme is to provide more control over minibuffer completions
while you're using them.  This is inspired by Icicles by Drew Adams,
although Icicles covers a much wider ground, and my changes aim for
compatibility and integration with "vanilla" Emacs completions first.
I've tried to pick key bindings that are convenient and don't currently
do something particularly useful in the minibuffer, but I'm open for
suggestions on this regard.  How do people feel about adding something
along these lines to Emacs?

In general, I'm happy to upstream anything that seems useful/desirable
in my working branch, even if I haven't mentioned it here specifically.


Best,

Eshel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]