It kinda does, but I've added a few bells and whistles to it. Mind you, this is zsh code I haven't really cleaned up, so it's kinda messy and most likely buggy in edge cases.
This needs to be in a directory in your FPATH.
At the core, it uses _arguments to dissect the command line. This both suggests that "-t" exists, is called "tags" and later on sets a state variable to "tags" or "limits" if we're completing these arguments.
#compdef corp-ansible-wrapper
_arguments '-t[tags]:tags:->tags' '-l[limit]:limit:->limits' '-D[diffmode]' '-C[checkmode]' '::optional arg:_files'
detect_playbook
case "$state" in
tags)
...
;;
limits)
...
;;
Given this, the limits autocompletion goes one step further. `detect_playbook` mainly goes through $words and looks for a singular argument looking like "*.yml" and sets that as $PLAYBOOK. Then, based on "$PLAYBOOK", it selects a filter-expression for the groups. This ensures that a `./wrapper mariadb.yml -l<TAB>` only sees mariadb-groups, and not postgres-groups.All of that is shoved into `_values`, and then the usual zsh completion works, so with something like `./wrapper mariadb.yml -l prj4<TAB>`, zsh tries to filter the values based on the word, so this finds stuff like `prj4`, `prj49`, `dc2_prj45`, and so on, but not `prj5`.
detect_playbook
# should be an array.
case $PLAYBOOK in
postgres.yml)
FILTER="pg_\|postgres_\|pgbackrest_"
;;
mariadb.yml)
FILTER="db_\|mariadb_"
;;
# quite a few more
*)
FILTER=""
;;
esac
# probably overly complex
ANSIBLE_GROUPS_RAW=$( cat $ANSIBLE_INVENTORY/groups | grep -E "$FILTER" | sort | uniq | tr '\n' ',')
IFS=',' read -r -A ANSIBLE_GROUPS <<< "$ANSIBLE_GROUPS_RAW"
_values -s: 'groups' "${ANSIBLE_GROUPS[@]}"
For the tags I'm working on a similar thing, but this contains enough ugly shell-script already. However, the key parts there are:- You can run `ansible-playbook "$WORD" --list-tags` to get all tags a playbook references in the current inventory.
- One can give `_values` descriptions. If `_values` sees 'foo[bar]' as an option, it will show the user something like: "foo: bar" and only auto-completes to foo.
- This means, we can give standard or well-established tags short descriptions in a directory or an array or whatever, and instead of offering just "postgres_client_tls_certs" as possible auto-completions for `-t`, we can give the user a prompt like "postgres_client_tls_certs: Ensures the postgres cluster has valid and up-to-date TLS certificates for mutual TLS with applications".
It took a bit of time to understand all of this. But now documenting a tag in a place that people actually look at is very easy and straightforward.