Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: external completion command



On Mon, Feb 19, 2024 at 4:30 AM Felix von Leitner <felix-zsh@xxxxxxx> wrote:
>
> Hello zsh-users,

Hi, Felix.  I'm sure we've chatted before but I can't find anything
from you in the list archives going back 25 years.  Still maintaining
zsh.vim ?

>   % s memc[TAB]
>   memccpy
>   memchr
>   memcpy
>   memcmp
>
> However, since the database covers potentially gigabytes of source code,
> I have written an optimized tool to list all the words that start with a
> certain prefix. I want zsh to run that tool with the prefix I already
> typed.

There's a lot of scaffolding in the "new" completion system (which has
now been around for about 85% of the life of the "old" one), but it's
all pretty much in support of two commands:
 - compdef how what
   Tells completion "how" (e.g., what command to run) to complete for
"what" (command line context).
 - compadd details -- words...
   Tells completion to consider the listed words when invoked, with
various details like whether the words are file names and what
explanatory text to show.

The rest is all just to assist with breaking the command line and the
word adjacent to the cursor down into "what" context so that different
"how" can be selected.  The whole scaffold is loaded by running
  autoload -Uz compinit
  compinit
which also scans the directories in $fpath for files with "#compdef"
in the first line and automatically enables those.

The other minimum thing you need to know is that the $words array
contains the command and arguments for which completions are being
generated, and that the integer $CURRENT specifies the position in
$words that is adjacent to the cursor, so $words[CURRENT] is your
already typed prefix.

> I don't want to give zsh a list of all the words, because that
> would be very inefficient. I would also like to tell zsh to abort after
> reading 100 completions.

The simplest formulation of this, then, using here "taglist" as the
name of your custom tool and "s" from your example as the command name
for which completions are being offered, would be something like (in
.zshrc)

  compinit
  compdef 'compadd -- $(taglist $words[CURRENT] | head -n 100)' s

Or you could create a file named "_taglist" in a directory in your
$fpath and in that file have

#compdef s
compadd -- $(taglist $words[CURRENT] | head -n 100)

I'm glossing over the possible need to do other quoting on the $(...)
if taglist could produce results with embedded spaces, or what you
want to do if $words[CURRENT] is the empty string.

Everything beyond this is just frosting.  For example there's a
variable $curcontext that tells you what context the completion system
has figured out from the contents of the command line, and the
"zstyle" command to define and look up values based on that context,
so in the above _taglist you could change the limit of 100 to
different numbers based how many words are to the left of $CURRENT,
etc.

Hope this helps.




Messages sorted by: Reverse Date, Date, Thread, Author