Daniel YC Lin
Daniel YC Lin

Reputation: 16002

auto completion in zsh on 3rd parameter

I have a shell script it's usage is:

foo.sh <name> <type> <*.tar.gz>

I want to setup a complete on 3rd parameter only. If I press on 1st parameter, just show the usage.

Could I use zsh's zshcomp to do this job?

for example:

foo.sh <tab>  # display usage
foo.sh a b <tab> # show files match with *.tar.gz

Is there similar script which I could follow?

Upvotes: 5

Views: 2158

Answers (1)

simont
simont

Reputation: 72547

Things to read.

Here is a blog post discussing the Z-Shell Completion System.

For a slightly more in-depth discussion, read this unix.stackexchange answer.

And, as always, read the man pages!.

Edit: Forgot to add: echo $fpath will show you the function path that zsh uses. On OSX, I have: /usr/local/share/zsh/4.3.17/functions, (location may vary for you), which contains all the ZSH completion functions. Have a look at _ssh, _ls, _tar etc - they're all there, and they all have lots of nifty features you can learn from.


Addressing the question: the direction you should go.

What you're asking is achievable, though. There are several steps.

  1. You need to write a z-shell completion function. It needs to be located on the fpath; the function-path that zsh uses for it's completion system functions. (If it's a small function, putting it into ~/.zshrc will also work, but isn't recommended).

  2. You want completion on the 3rd parameter. To do that, your function would look something like the following:

    _arguments "3:<MENU>:<COMPLETION>"
    

    <MENU> is the menu description, which you'll see if you've enabled the menu descriptions. (That's done using zstyle; read the man pages, or the linked pages, for more information). <COMPLETION> is the things that you can complete with. For example, if you used:

    _arguments "3::(Foo Bar)"
    

    when you ran your script and pressed <TAB>, you'd have the option of either Foo or Bar. [NOTE: There is no <MENU> in that example. If you don't want a menu descriptor, you can omit it as shown].

  3. You want completion on *.tar files. You can call _files to do that:

    _files -g \*.tar
    
  4. Show usage on first parameter: that'd be a completion with no arguments (ie, argument 1). I'm not sure why you'd want completion on only the third option but not the first two (typical usage descriptions), so I don't know how to answer this. If your script is supposed to be used like this: script foo bar FILE.tar, wouldn't you want to complete the foo and bar arguments as well?
    Perhaps a better solution would be displaying the usage when the script is run without parameters.

Full script would look something like the following:


#compdef myscript

_arguments "3:tar files:_files -g \*.tar"

Upvotes: 7

Related Questions