Bash – How to provide Bash completion for a directory-local executable

autocompletebash

I wrote a Bash script to help me manage some symlinks. It's a wrapper around some Stow commands.

When I invoke it, I pass it two command-line arguments: a command (plug/unplug/replug) and a directory name (just its basename, not a path).

The script is called vlink, so an invocation would be, for example:

vlink plug foo

The directory name (foo in the above example) needs to be one of the subdirectories of a specific directory elsewhere on my system.

Since there are only three possible commands (plug/unplug/replug) and a specific set of possible directory names for the third argument, I'd like to provide some tab-completion for it.

I'm somewhat familiar with writing Bash completion scripts, but is there a way to provide completion commands for an executable that's not in my $PATH and is only intended to be run from its parent directory?

Best Answer

This might work:

_vlink () {
    case $COMP_CWORD in
        1) COMPREPLY=( $(compgen -W "plug unplug replug" "$2") ) ;;
        2) local IFS=$'\n'
            COMPREPLY=( $(cd /some/dir && compgen -d "$2") ) ;;
    esac
}

complete -F _vlink vlink

Replace /some/dir with the directory containing the subdirectories of interest. (I'm assuming your directory names don't have newlines in them.)

  • COMP_CWORD is the index of the word being completed (0 being the command name)
  • the second argument to the completion funciton is the word being completed (the first being the command name and the third being the previous word)

So, we use compgen:

  • for the first argument, to generate matching words from the list of words given with -W, and
  • for the second argument, to generate matching directory names from the relevant directory.
Related Question