Завершение zsh для ssh путает имена хостов с локальными файлами

Нашел. В аналогичном случае автор жаловался, что:

Мне нужно ждать около 20 секунд, пока моя сеть не подключится.

Оказалось, что :

Эта задержка вызвана протоколом Spanning Tree Protocol (STP)

. Действительно, одно из различий заключалось в том, что / etc / network / interfaces Debian хост содержал bridge_stp на , тогда как в Ubuntu не было оператора bridge_stp .

3
16.11.2016, 10:05
3 ответа

Второй ответ пытается объяснить, что вам нужно сделать две вещи:

1 _убедитесь, что ваши общие правила сопоставления не чувствительны к регистру -нечувствительны к регистру(matcher-list)-из обновленного вопроса это не так,

2 _изменить Unix/ (Тип/ )_хосты(фактическое местоположение может отличаться, но не Unix/ _ssh-этот обрабатывает ~/.ssh/configхостов, см. ниже )последние 2 строки до:

_wanted hosts expl host \
   compadd -M 'm:{a-z}={A-Z} r:|.=* r:|=*' -a "$@" - _hosts

Все это уже было изложено в моем ответе, так что просто попробуйте сделать это, не читая все обоснования перед этим. Кроме того, поскольку ваша глобальная конфигурация не чувствительна к регистру -, ответ @zeppelin также должен работать, хотя он не использует $fpath и удаляет также небольшие совпадения -> CAPS для хостов.

Я проверил это с вашими настройками из обновления, и они работают должным образом.

Обновление :помните, что zshсохраняет свои функции загруженными, поэтому после изменения _hostsвам необходимо перезагрузить его, либо войдя заново, либо:

unfunction _hosts
autoload -Uz _hosts

Также помните, что zshможет иметь скрипты, "скомпилированные" в zwcформу (zcompile [file]), и если такой файл существует и новее, чем исходный код, он будет использоваться вместо него.

Ад. обновление 2:

Обработка определенных хостов ~/.ssh/configна самом деле почти такая же, как и для _hosts-, в зависимости от вашей версии zsh в Unix/ (Command/ )_ssh ] или Unix/ (Тип/ )_ssh _hosts измените

compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" $config_hosts

строка до

compadd -M 'm:{a-z}={A-Z} r:|.=* r:|=*' "$@" $config_hosts

5
06.08.2020, 08:11

Есть два аспекта этого вопроса.

  1. глобальное завершение zsh с нечувствительностью к регистру -. Это очень популярно, но ИМХО бессмысленно делать это двумя -способами. Так как я обычно не пишу заглавными буквами (или по ошибке ), давайте рассматривать все ЗАГЛАВНЫЕ буквы как преднамеренные:

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

mkdir DOC drone
ls D[tab] => DOC
ls d[tab] => drone DOC
ls Dr[tab] => [empty]

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

А так как повторяющиеся значения списка соответствий -объединяются (цитата из документации :" Эта опция может быть указана более одного раза. В этом случае все указанные соответствия -спецификации объединяются с пробелами между ними, чтобы сформировать строку спецификации для использования " ), вы не можете переопределить это позже, например

compdef '_hosts -M m:' foo

не отменяет предыдущее определение из файла hosts _. Поэтому, если у вас есть {a-zA-Z}={A-Za-z}в вашей глобальной конфигурации, вы не сможете очистить это, даже с помощью matcher, например.:

zstyle ':completion:*:scp:*:*' matcher "m:{A-Z}={A-Z}"

не поможет. К сожалению, вам необходимо начать решение этой проблемы на глобальном уровне. Компромиссное -решение может состоять в том, чтобы иметь два -прохода по всему миру:

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' 'm:{A-Z}={a-z}'

ls d[tab] => DOC drone
ls D[tab] => DOC
ls Dr[tab] => drone
  1. Вторая часть проблемы заключается в том, что функция -определяет список соответствий -. Как указано выше, это невозможно очистить, поэтому вам нужно справиться с этим, как уже описано в ответе @zeppelin, изменив предоставленный файл zsh -:

_хосты:

[....]
_wanted hosts expl host \
    compadd -M 'm:{a-z}={A-Z} r:|.=* r:|=*' -a "$@" - _hosts

Теперь и с системным -широким сопоставлением -list 'm :{a -z}={A -Z}':

scp d[tab] => /directory/ DOC drone /remote host name/ docker /user/ daemon
scp D[tab] => DOC

Предлагаемое решение с изменением исходных файлов завершения не является правильным способом, как отметил @zeppelin... но создание собственной функции выборки хоста -также имеет недостатки. К сожалению, правильное решение остается за разработчиками zsh, которые могут добавить опцию очистки matcher -, определить какой-то новый стиль или просто исправить функцию завершения, чтобы она не игнорировала регистр сама по себе, просто следуйте глобальным настройкам.

Тем не менее, даже с этой проблемой есть красивое и чистое решение -вместо изменения (возможно, какой-то пакет дистрибутива )/usr/share/zsh/... можно поместить исправленную копию в /etc /zsh/functions и просто скажите zsh использовать это местоположение:fpath=(/etc/zsh/functions $fpath). Так вы избежите перезаписи файла после обновления системы.

Подведение итогов

  1. изменить глобальный список соответствий -:

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' 'm:{A-Z}={a-z}'

  1. поместите измененный _файл hosts в какой-нибудь каталог /etc/zsh или $HOME:

fpath=(/etc/zsh/functions $fpath)

/etc/zsh/functions/ _хосты:

[....]
_wanted hosts expl host \
    compadd -M 'm:{a-z}={A-Z} r:|.=* r:|=*' -a "$@" - _hosts
2
19.07.2020, 18:10

Вам не нужно изменять какие-либо функции завершения, чтобы получить то, что вы хотите. Просто добавьте это в свой ~/.zshrcфайл:

# $PREFIX is the part of the current word that's to the left of the cursor.
# $SUFFIX is the part of the current word that's to the right of the cursor.
# Let's ignore all host completions that don't explicitly match what we've typed, 
# but allow for additional characters at the cursor position and at the end of what 
# we've typed. This makes the matching case sensitive.
# `(b)` escapes characters that are significant to globbing.
zstyle -e ':completion:*:hosts' ignored-patterns 'reply=(
  "^(${(b)PREFIX}*${(b)SUFFIX}*)"
)'

# But if that would lead to no results, then offer the ignored completions anyway.
zstyle ':completion:*' completer _expand _complete _ignored

Я проверил это с помощью конфигурации и тестовых случаев, которые вы опубликовали, и это работает.

Документация:

2
04.08.2020, 07:54

Теги

Похожие вопросы