Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make zsh complete arguments from a file

zsh is great but its completion system is very diverse. And the documentation lacks good examples. Is there a template for completing for a specific application. The completion would get its match data from a file, separated by newlines?

I tried modifying an older example of mine that takes match data "live":

~ % cat .zsh/completers/_jazzup 
#compdef jazz_up
_arguments "2: :(`mpc lsplaylists|sed -e 's# #\\\\ #g'`)"

I could supply cat my_file there instead of mpc invocation and so on but would there be a more elegant way to do this simple task? And that completion there is placement-specific: can you provide an example where zsh would attempt to complete at any point after the program name is recognized?

The match data will have whitespaces and so on, the completion should escape the WS. Example of that:

Foo bar
Barbaric
Get it (42)

Now if that completion would be configured for a command Say, we should get this kind of behaviour out of zsh:

$ Say Fo<TAB>
$ Say Foo\ bar
$ Say Ge<TAB>
$ Say Get\ it\ \(42\)
like image 454
mike3996 Avatar asked Jun 26 '13 11:06

mike3996


People also ask

How do you use zsh completion?

When you hit the tab key, the system will complete the path to the Documents folder. At this point, you can add a character or two to get to a unique completion, and hit the tab key again. In zsh you can also hit the tab key repeatedly to cycle through the suggested completions.

Where do I put zsh completion files?

Since zsh 5.0. 7, the default function load path ( $fpath ) includes /usr/local/share/zsh/site-functions . So install your completion functions there. Note that /usr/share/fish/vendor_completions.

What does Compinit do in zsh?

Autoloaded files Furthermore, if the directory in question ends in the path segment Core, or has a subdirectory named Core, compinit will add all subdirectories of the directory where Core is to the path: this allows the functions to be in the same format as in the zsh source distribution.


1 Answers

Simple completion needs are better addressed with _describe, it pairs an array holding completion options and a description for them (you can use multiple array/description pairs, check the manual).

(_arguments is great but too complex.)

[...]

First create a file

echo "foo\nbar\nbaz\nwith spac e s\noh:noes\noh\:yes" >! ~/simple-complete

Then create a file _simple somewhere in your $fpath:

#compdef simple

# you may wish to modify the expansion options here
# PS: 'f' is the flag making one entry per line
cmds=( ${(uf)"$(< ~/simple-complete)"} ) 

# main advantage here is that it is easy to understand, see alternative below
_describe 'a description of the completion options' cmds

# this is the equivalent _arguments command... too complex for what it does
## _arguments '*:foo:(${cmds})'

then

function simple() { echo $* }
autoload _simple # do not forget BEFORE the next cmd! 
compdef _simple simple # binds the completion function to a command

simple [TAB]

it works. Just make sure the completion file _simple is placed somewhere in your fpath.

Notice that : in the option list is supposed to be used for separating an option from their (individual) description (oh:noes). So that won't work with _describe unless you quote it (oh\:yes). The commented out _arguments example will not use the : as a separator.

like image 188
Francisco Avatar answered Oct 25 '22 20:10

Francisco