20

In zsh, I'm trying to get an idea of which commands have an existing completion so that I can write completions for commands that don't.

Is there a way to list the commands that zsh will complete without grepping the completion files? For instance, is there a built-in command that will list them?

tegarri
  • 203
  • 2
  • 5

1 Answers1

36

The list of known completions is stored in the associative array _comps. The command names and other completion contexts are used as keys for _comps, while the corresponding completion functions are stored as values.

You can get a full list of commands with associated completions with the following command:

for command completion in ${(kv)_comps:#-*(-|-,*)}
do
    printf "%-32s %s\n" $command $completion
done | sort

Explanation:

  • for command completion in LIST; COMMAND takes iterates over LIST while taking two elements, command and completion, on every iteration and running COMMAND for them. This is also a short form of the for-loop that does not require do and done.
  • ${(kv)ASSOC_ARRAY} expands the associative array ASSOC_ARRAY to a space separated list of key-value pairs. So it is an alternating list of "key1 value1 key2 value2 key3 value3 …", which is taken up by the two arguments of the for-loop. $ASSOC_ARRAY would only expand to a list of values.
  • ${ASSOC_ARRAY:#PATTERN} filters out all elements of ASSOC_ARRAY from its expansion, where the key matches PATTERN.
  • The pattern -*(-|-,*) matches the names of all special contexts, like -math-, -parameter- or -value-,NAME,COMMAND. It would also filter any command name that either matches -*- or -*-,*, should such a command have a completion on your system. (You could just leave out the pattern filter to be sure)
  • printf "%-32s %s\n" $command $completion does a formatted output so that you get a nice table. $command is printed in place of %-32s, padded to 32 characters with left-alignment (-). $completion is printed in place of %s.
  • | sort: associative arrays are unordered, so output of the loop needs to be run through sort in order to get a ordered list.
Adaephon
  • 16,929
  • 1
  • 54
  • 71
  • What do the `key` and `value` signify here? – kapad Nov 03 '20 at 20:32
  • @Adaephon what do you call `${(kv)ASSOC_ARRAY}` this type of syntax where you have the parentheses and some letters inside it `(kv)` ? do you have a good reference for it i can read up on ? thanks – 8c6b5df0d16ade6c Aug 19 '21 at 09:31