Implementing the Tab Completion Feature

Implementing the Tab Completion Feature


2 min read

If you are building a command line application and it has many options, then you will most likely want the feature of tab completion. This is actually the feature I wanted. Then I found this article and I followed the steps and it work perfectly. In this article, let me talk about what I thought and what I have done.

Tab completion is a feature of shell. So we can't implement this feature in our own application. What we need to do is find the interface the shell provides and integrate our own application with the interface.

There are a lot of shells and each may have different interfaces. I use a mac and it uses the zsh shell by default. So let me use the zsh shell as an example.

So let's say the command of our application is called yaox023 and we can pass in a lot of different options including yaox023 option-1, yaox023 option-2 and yaox023 option-3.

The flow of the tab completion feature is as follows:

  1. User have typed yaox023 option-

  2. User hit tab key

  3. Shell call the api our application provides

  4. The api returns a list of options

  5. Shell gets the options and displays them to the user

What we need to do first is to provide an api. This is simple, we can just provide another command line options, which may works like below.

$ yaox023 --complete option-

Note that the result should be a string of options separated by \n.

Next, we need to let the shell call this api. A shell script can be prepared as below completion.zsh.

yaox023_complete() {
  local word completions
  completions="$(yaox023 --complete "${word}")"
  reply=( "${(ps:\n:)completions}" )

compctl -f -K yaox023_complete yaox023

As you can see, we first write a function in which the api is called to get all options. At the last line of the function, the string return by the api will be splitted by \n and give back to shell. Secondly the compctl command is used to hook the function so when the tab key is hit this function should be called.

The final thing should be simple, we can just run this script.

$ chmod +x ./completion.zsh
$ source ./completion.zsh

Lastly, sure we can return the filtered related options in our application, but we can also return all options regradless of the current word passed in. The shell will also do the filtering and only display possible options. The choice is in our hands.