Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to list all zsh autocompletions?

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?

like image 584
tegarri Avatar asked Oct 13 '16 01:10

tegarri


People also ask

How do I get zsh autocomplete?

zsh-autocomplete adds real-time type-ahead autocompletion to Zsh. Find as you type, then press Tab to insert the top completion, Shift Tab to insert the bottom one, or ↓ / PgDn to select another completion.

Where are zsh completions stored?

On macOS completions are stored in /usr/share/zsh/5.3/functions (replace the 5.3 with 5.7. 1 in Catalina). This directory stores many functions used with zsh and is in the default fpath . All the files in that directory that start with an underscore _ contain the completion definitions command.

What is Compinit zsh?

Use of compinit When run, it will define a few utility functions, arrange for all the necessary shell functions to be autoloaded, and will then re-bind all keys that do completion to use the new system.

What is Zstyle?

The Zsh module “zstyle” allows you to configure settings for a specific Zsh module or widget.


1 Answers

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.
like image 63
Adaephon Avatar answered Sep 30 '22 14:09

Adaephon