Excluding Environment Variables from ZSH Autocomplete

Solution 1:

I didn't find such an option, but maybe you are helped, if your completion would be case sensitive. you can set this in your ~/.zshrc:

# Set to this to use case-sensitive completion
CASE_SENSITIVE="true" 

Solution 2:

TL;DR

Add this to your ~/.zshrc

function _parameters() {}

Explanation:

In the zsh completion system every completable pattern is matched to some completion function. In the case where completion is invoked in the command position (in zsh lingo), zsh invokes the function associated with the special pattern -command-.

All completion patterns and functions are stored in the _comps_ variable as an associative array. So, you can see which function is invoked for completing commands like this:

echo ${_comps[-command-]}

In my case the function is _command_names. If we take a look at the source code of this function,

whence -f _command_names

then you'll see all sources from which possible completions are gathered. It can be builtins, executables on the path, local executables if the completion prefix contains a slash, aliases, functions, jobs, reserved words and, crucially, parameters, which includes environment variables. Looking at the code of _command_names I see that whether parameters should be suggested or not was not made configurable - the _parameters function is always invoked. The _parameters function likewise doesn't seem sufficiently configurable.

At this point we know enough to look at a few solutions. One would be to modify _command_names and remove the parameters:_parameters sources. Another is to make the _parameters function a no-op. The second option looks less error-prone and is therefore my recommendation.


Note that overriding the _parameters function also disables completion environment variables in other places (e.g., typing $ and then hit Tab). To allow completing environment variables in other places, patching _parameters instead of overriding it is a possible solution. Here is an example:

autoload +X _parameters # load it for patching latter
functions[_parameters]="
[[ \$curcontext = -command- ]] && return
$functions[_parameters]"

It skips processing environment variables if $curcontext, the context for the called completion function, is in the program name. Escaping it is needed to make expanding $curcontext happens until the patched function is executed.