Skip to content
Mrigank's Blog
Go back

Writing your first ZSH autocompletion function

Edit page

In this post, I’ll guide you in writing few, very basic Zsh autocompletion functions. Everything will be used at its minimal level.

I’m assuming that you’ve a basic knowledge of bash.

You need activate completion system first if you’re not using something like oh-my-zsh. Just run(or add to .zshrc):

autoload -U compinit
compinit

Let’s say our program is called hello.

Here’s what will happen:

function _hello(){
    #You write your code here
}
compdef _hello hello

Whenever you want to throw out possible completions, you’ll use one of the following utility functions(in this post):

compadd

You want:

hello <Tab>
    cmd1    cmd2    cmd3

You’ll write:

comdadd cmd1 cmd2 cmd3

_describe

You want:

hello <Tab>
cmd1    --  description1
cmd2    --  description2

You’ll write:

_describe 'command' "('cmd1:description1' 'cmd2:description2')"

Note: In both of above commands, we didn’t consider which argument no. it is, means even hello cmd1 <Tab> will give same output. Next command will solve this problem.

_arguments

Now this is a powerful one. You can control multiple arguments.

By multiple arguments I mean hello arg1 arg2 not hello arg1|arg2

Here’s the basic syntax: _arguments <something> <something> ... where <something> can either be:

First one is self-explanatory, whenever called it’ll give

hello <Tab>
-o  --  description

For the second one:

_arguments ‘1: :(world universe)’ 2. Set variable `state` to an identifier. For example, if we want to call another function at argument no. 2, we can write: bash local state _arguments ‘2: :->identifier’ case $state in identifier) #do some special work when we want completion for 2nd argument … ```

That might be confusing, lets sum up _arguments by an example:

Lets say, our program has possible args like:

hello [cat|head] <file at /var/log> one|two

Its completion function can be:

function _hello(){
    local state 
    _arguments '1: :(cat head)' '2: :->log' '3: :->cache'

    case $state in
        log)
            _describe 'command' "($(ls $1))"    #this is for demonstration purpose only, you'll use _files utility to list a directories
            ;;
        cache)
            compadd one two #this could be done above also, in _arguments, you know how :)
            ;;
    esac
}

What Next?

I hope you were able to successfully write your first autocompletion function. I recommed to visit:


Edit page
Share this post:

Previous Post
Flutter: The master of all
Next Post
Capturing network requests on Android

Comments