Custom environment variable name completion in zsh

74 views Asked by At

I am trying to customize how zsh completes environment variable names for my custom command ee. Here is the problem: I've defined a custom completion function using compdef, and it works perfectly if I type ee and hit tab:

ee <Tab>

Here is the output of ^Xh, which is clear:

tags in context :completion::complete:ee::
    values  (_spec _echo)
tags in context :completion::complete-fuzzy:ee::
    values  (_spec _echo)

The same output ^Xh produces when I type any text which doesn't contain the dollar sign.

However, if I type the dollar sign, and then press Tab, then the list of completers change radically:

ee $<Tab>

Here what ^Xh outputs in this case:

tags in context :completion::complete-fuzzy:-parameter-::
    parameters  (_parameters _parameter autocomplete:_complete:old)
tags in context :completion::complete:-parameter-::
    parameters  (_parameters _parameter autocomplete:_complete:old)

Sometimes there are even more elements:

tags in context :completion::approximate:::
    corrections original  (autocomplete:_approximate:old)
tags in context :completion::approximate-1:-parameter-::
    parameters  (_parameters _parameter autocomplete:_complete:old)
tags in context :completion::complete-fuzzy:-parameter-::
    parameters  (_parameters _parameter autocomplete:_complete:old)
tags in context :completion::complete:-parameter-::
    parameters  (_parameters _parameter autocomplete:_complete:old)
tags in context :completion::correct:::
    corrections original  (autocomplete:_approximate:old)
tags in context :completion::correct-1:-parameter-::
    parameters  (_parameters _parameter autocomplete:_complete:old)

As you can see, the list doesn't contain my custom completion function anymore.

The question is: why $ has such impact on the completion behaviour and how to enable my custom completion even after I type $? Didn't find anything about it in the documentation.

1

There are 1 answers

0
zeionara On

The answer I came up with after browsing the zsh documentation. There is indeed a section dedicated to the question I am interested in (section 20.2.2). I've created separate handlers for usual completion and parameter completion like this:

_spec () {
  local description="$1"
  shift  # Remove the first argument (description)

  bindkey -M menuselect '^M' .accept-line

  _wanted -V values expl "$description" compadd -P '$' "$@"
}

_spec_no_prefix () {
  local description="$1"
  shift  # Remove the first argument (description)

  bindkey -M menuselect '^M' .accept-line

  _wanted -V values expl "$description" compadd "$@"
}

_echo () {
  eval "$_setup_ee_completions"
}

_echo_no_prefix () {
  eval "$_setup_ee_completions_no_prefix"
}

compdef _echo_no_prefix ee '-parameter-'
compdef _echo ee

Where _setup_ee_completions and _setup_ee_completions_no_prefix contain the following values respectively:

_spec history 'XDG_SESSION_TYPE' 'LD_LIBRARY_PATH' 'CHROME_API_VERSION' 'ENV' 'OPENAI_API_KEY' 'PYTHONPATH'
_spec_no_prefix history 'XDG_SESSION_TYPE' 'LD_LIBRARY_PATH' 'CHROME_API_VERSION' 'ENV' 'OPENAI_API_KEY' 'PYTHONPATH'