Wesley Schwengle IncludeIf: A digital space written in pencil Articles Series Answerrit /dev/null About IncludeIf: A digital space written in pencil Devs /dev/null zsh: Dynamically ignore files for autocomplete

You might also like

In the zshell you can use CORRECT_IGNORE_FILE to ignore files for spelling corrections (or autocorrect for commands). While handy, it is somewhat limited as it is global. Now, I wanted to ignore it only for git and not other commands. But I haven’t found a way to only target git without having to make a wrapper around git (which I don’t want to do).

So I wrote an autoloaded function that does this for me. The idea is rather simple. In your .zshrc you set a zstyle that tells which file should be ignored based on files (or directories) that exist in the current directory. Based on this you build the CORRECT_IGNORE_FILE environment variable or you just unset it. This function is then hooked into the chpwd action. I went with three default options, check dir, file, or just exist: d, f, or e. File wins, then directory, then exists.

In addition, there is also support for whole-sale directories. If you have a directory where you know things are gonna be conflicting, for example in my git repo of git itself, my git poh conflicts with the po (i18n) directory and the ci directory with my co alias. The beauty is, nameddir support comes out of the box, so you don’t need to spell it out, you just jot down ~git for where-ever your git source directory is.

The API is a little inconsistent between the two. But one is more, if this combination exist, just ignore this path, eg, for .git and app just ignore app. I actually want to ignore things only for certain commands.
Whereas the directory option allows in this dir just ignore these two units, like ci and po.

# in your .zshrc add-zsh-hook chpwd set-correct-ignore # zstyle ':local:correct-ignore:d' $ignore $conditions zstyle ':local:correct-ignore:d' app .git app # zstyle ':local:correct-ignore:directory' $dir $ignore $ignore zstyle ':local:correct-ignore:directory' ~git ci po

The actual autoloaded function can seen here:

# set-correct-ignore local word dirs check_type all_exist local ignore_words=() for check_type in f d e; do local -A rules zstyle -g patterns ':local:correct-ignore:'$check_type for word in $patterns do zstyle -a ':local:correct-ignore:'$check_type $word dirs all_exist=1 for dir in ${=dirs}; do case $check_type in e) [[ -e $dir ]] || { all_exist=0; break };; d) [[ -d $dir ]] || { all_exist=0; break };; f) [[ -f $dir ]] || { all_exist=0; break };; esac done (( all_exist )) && ignore_words+=($word) done done zstyle -g patterns ':local:correct-ignore:directory' for dirs in $patterns do zstyle -a ':local:correct-ignore:directory' $dirs words [ $PWD != $dirs ] && continue ignore_words+=($words) done if (( ${#ignore_words} )); then export CORRECT_IGNORE_FILE="${(j:|:)ignore_words}" else unset CORRECT_IGNORE_FILE fi

Now you can enter, in this case a Laravel project and git ap won’t trigger a correction from zsh: zsh: correct 'ap' to 'app' [nyae]?. Sweet! Totally :)