Simplest way of defining autocomplete subcommands

40 views Asked by At

I have a CLI program that has a few nested subcommands, like

program task
program task start
program task stop
program config
program config set
program config unset

And I'd like to implement a very rudimentary bash autocomplete for it. I don't necessarily want to go the route of defining a shell-function for it, but was hoping to simply use wordlists, like

complete -W "task config" -- "program"

But it doesn't seem I can define nested completion wordlists that way, like

complete -W "start stop" -- "program task"
complete -W "set unset" -- "program config"

Is there a simple way of achieving autocompletion for such commands?

1

There are 1 answers

0
Tasos Papastylianou On

Here's an example of the _get_comp_words_by_ref function I mentioned in my comments.

# "program" completion

# This file should either be copied in your system-defined place where other
# such completion scripts reside, such as /usr/share/bash-completion/completions
# or /etc/bash_completion.d (check which one is called by your .bashrc file).
#
# Alternatively, simply 'source' it in your .bashrc file.


function _program () {

  _get_comp_words_by_ref -c CURRENT_WORD -p PREVIOUS_WORD -w WORDS_ARRAY -i CURRENT_WORD_INDEX


  if   test "$CURRENT_WORD_INDEX" -eq 2     &&   # dealing with a second-level subcommand
       test "${WORDS_ARRAY[0]}" = "program"
  then if   test "$PREVIOUS_WORD" = "task"
       then COMPREPLY=( $( compgen -W "start stop" -- $CURRENT_WORD ) )
       elif test "$PREVIOUS_WORD" = "config"
       then COMPREPLY=( $( compgen -W "set unset" -- $CURRENT_WORD ) )
       fi
  elif test "$CURRENT_WORD_INDEX" -eq 1 && test "$PREVIOUS_WORD" = "program"
  then COMPREPLY=( $( compgen -W "task config" -- $CURRENT_WORD ) )
  fi

}

complete -F _program program

Source this file and try typing program co[TAB], program config u[TAB], etc.