Shell Auto-completion Systems

One great feature of modern command shells that improves experience is the tab-completion of commands. After typing part of a command and hitting the TAB key the shell presents list of possible completions of a given command. For some commands the completions are quite sophisticated. Lets look how it works for most common shells.


Completion scripts are based on shell functions. A completion function will be called and variable COMP_WORDS will contain strings that user typed and COMP_CWORD indicates current position in input. To offer a suggestions the function will set COMPREPLY variable to possible values.

The compgen is a helper builtin that is often used to generate list of possible options given all options and prefix.

The completion functions are registered with the complete builtin. To list all registered completions one can run complete -p.



Zsh has a bit more sophisticated system. It offers more helper builtins to help with writing the completion functions. Another improvement is that completions can contain short descriptions for proposed options that are displayed to the user.

The _describe function is a simple way to specify options and arguments similar to compgen in bash. For advanced cases there is the _arguments helper that takes more formal specification of possible options and arguments and generates completions accordingly. There is also an option to generate completion from the commands help usage message that is taken from command --help.

The completion functions are registered with the #compdef directive and lazily loaded when a completion for a particular command is invoked.



Fish has a simple completion system similar to bash but it does not seem to provide additional helper functions. Completion functions are registered with a custom version of complete.



I explored completion systems in hope of leveraging existing command descriptions. It turns out completion scripts are written in quite an ad-hoc fashion, usually hand-crafted and often do not contain complete set of possible options and arguments. Therefore it will not be possible to reuse them for generating command UIs.

However, they could used initially for a context-sensitive completion. By that I mean when a command needs a file the autocompletion suggests existing files from a current directory. Or when a command requires a server we can list suggestions based on known hosts and so on.