When I start typing something into an interactive login shell (zsh or bash) and click tab, the shell offers me autocomplete suggestions.
I broadly understand how completion specs are defined. For reference it's outlined here:
- Bash: https://www.gnu.org/software/bash/manual/bash.html#Programmable-Completion
- Zsh: http://zsh.sourceforge.net/Doc/Release/Completion-System.html
What I don't understand is how bash/zsh identify which command to complete on when a user presses tab i.e. if I do
ls [tab], how does bash/zsh identify
ls. Put differently, how do bash/zsh know to generate completions using the
ls completion spec.
Some more examples with more complicated parsing which Bash/Zsh still get right:
ls [tab]-> completes on
echo $( echo $(ls [tab]-> completes on
echo hi; git a[tab]-> completes on
echo 'cd [tab]-> does NOT complete on
echo "$(ls [tab]-> completes on
echo $( echo hi | ls [tab]-> completes on
lsdoesn't take stdin but this example still illustrates bash/zsh's parsing abilities)
I am presuming bash/zsh are using some sort of parser. However, it's not a normal parser. It completes without a properly structured command. It is aware that something is in quotes or a shell expansion, even if they are not closed.
What function is bash/zsh running to "identify" the relevant command or determine whether or not there is a command to complete on at all?
echo $(ls [TAB])
/usr/share/bash-completion/completionsare pretty self-explanatory. 1. You define a completion function via:
complete -F _function_name application_namei.e.
complete -F _ls ls2. Then you define function _function_name which expands values.
$PATH. This is used for completion. See the
echo $(ls ( ) )and press tab, it auto completes even when the code to the right is invalid syntax.