Имейте zsh, возвращая не зависящие от регистра автоматические матчи, но предпочитайте точные совпадения

Я использую zsh с файлом oh-my-zsh rc, и есть некоторое поведение, которое я нахожу особенно раздражающим. По умолчанию oh-my-zsh настроен на возврат нечувствительных к регистру совпадений при автозаполнении. Такое поведение иногда бывает хорошим, но в других случаях это действительно отстой. Есть ли способ, которым я могу настроить zsh только для использования соответствия case-insenstive, если нет совпадений с учетом регистра?

Например, в этом случае будет использоваться совпадение с учетом регистра:

> ls
LICENSE.txt    lib/
> emacs l <-- should autocomplete to lib/

В этом случае произойдет автозаполнение без учета регистра:

> ls
README    lib/
> emacs r <-- should autocomplete to README

Спасибо!

Ответ 1

Просто раскомментируйте следующую строку в ~/.zshrc:

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"

Это сработало для меня

Ответ 2

Создайте файл ~/.oh-my-zsh/custom/better-completion.zsh (предположим, что вы используете пути по умолчанию для oh-my-zsh) со следующими строками

zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'

Пояснение:

Правила совпадений в завершении zsh в целом определены в стиле matcher-list. Для oh-my-zsh это определено в ~/.oh-my-zsh/lib/completion.zsh (один раз для чувствительности к регистру и один раз для нечувствительности к регистру). Вы могли бы изменить его там, но он, вероятно, исчезнет, ​​если вы обновите свой oh-my-zsh. ~/.oh-my-zsh/custom специально предназначен для настройки, а файлы с расширением .zsh загружаются оттуда на .oh-my-zsh/oh-my-zsh.sh в конце конфигурации.

Настройки по умолчанию (без учета регистра) для matcher-list в oh-my-zsh:

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'

Первый из них говорит о том, что обрабатывать сменный и нижний регистр взаимозаменяемы. Поскольку это первое правило, оно будет неизменно использоваться для каждого матча.

Единственное изменение, которое необходимо сделать, это добавить '' для простого завершения (это даже первый пример в zshcompsys(1) для matcher-list)

zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'

Это сначала пытается выполнить текущее слово точно так же, как и его написанное, перед тем, как пробовать нечувствительные к регистру или другие совпадения.

Чтобы быть полным:

  • Второе (исходное) правило допускает частичное завершение до ., _ или -, например. f.bfoo.bar.
  • Третье правило позволяет завершить работу с левой стороны написанного текста, например. barfoobar)