Reputation: 15975
I am using zsh with oh-my-zsh's rc file and there is some behavior I find particularly annoying. By default, oh-my-zsh is configured to return case-insensitive matches when auto-completing. This behavior is sometimes good, but other times it really sucks. Is there a way I can configure zsh to only use case-insenstive matching when there are no case-sensitive matches?
For instance, this case would use case-sensitive matching:
> ls
LICENSE.txt lib/
> emacs l <-- should autocomplete to lib/
In this case, case-insensitive auto-completion would happen:
> ls
README lib/
> emacs r <-- should autocomplete to README
Thanks!
Upvotes: 74
Views: 48829
Reputation: 18399
Create a file ~/.oh-my-zsh/custom/better-completion.zsh
(assuming you are using default paths for oh-my-zsh) with the following line
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
Explanation:
Rules for matches in zsh completion in general are defined in the matcher-list
style. For oh-my-zsh this is defined in ~/.oh-my-zsh/lib/completion.zsh
(once for case-sensitive and once for case-insensitive). You could change it there but it would probably be gone if you updated your oh-my-zsh. ~/.oh-my-zsh/custom
is specifially intended for customization and files with extension .zsh
are loaded from there by .oh-my-zsh/oh-my-zsh.sh
at the end of the configuration.
The default (case-insensitive) settings for matcher-list
in oh-my-zsh are:
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
The first of which tells to handle upper and lower case interchangeable. As it is the first rule, it will be invariably used for every match.
The only change needed is to prepend ''
for simple completion (it is even the first example in zshcompsys(1)
for matcher-list
)
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
This tries first to complete the current word exactly as its written, before trying case-insensitive or other matches.
To be complete:
.
, _
or -
, e.g. f.b
-> foo.bar
.bar
-> foobar
)Upvotes: 65
Reputation: 13238
For those not using oh-my-zsh, you can add the following two lines to ~/.zshrc
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
autoload -Uz compinit && compinit
Upvotes: 49
Reputation: 672
Just uncomment the following line in ~/.zshrc:
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
It worked for me
Upvotes: 60