Ярлык .zshrc работает на Arch, но не на Ubuntu

Я использую оболочку zsh в качестве оболочки по умолчанию как в Ubuntu, так и в Arch.

Я настроил ярлык (стрелка вверх) для автозаполнения из истории в моей оболочке zsh, используя следующую строку в моем .zshrc :

 bindkey "^[[A" history-beginning-search-backward 

Тем не менее, когда я получаю исходный код .zshrc и / или перезагружаюсь в Ubuntu, ярлык не работает (я получаю только предыдущую команду, независимо от того, что я начал печатать), тогда как в Arch он работает нормально (у меня запускается только последняя команда с того, что я напечатал).

Кто-нибудь знает как это решить?

2 Solutions collect form web for “Ярлык .zshrc работает на Arch, но не на Ubuntu”

На большинстве xterm-подобных терминалов ␛[A Up (и она аналогична для большинства навигационных клавиш) отправляет либо ␛[A либо ␛OA зависимости от того, был ли терминал переведен в режим передачи с клавиатуры или нет. smkx и rmkx terminfo могут использоваться для smkx или rmkx терминала в этом режиме.

Запись kcuu1 (курсор вверх на 1) описывает последовательность, отправляемую Up в режиме передачи с клавиатуры , то есть ␛OA .

Debian и его производные имеют файл /etc/zsh/zshrc который выполняет

  function zle-line-init () { emulate -L zsh printf > /dev/tty '%s' ${terminfo[smkx]} } 

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

Файл также определяет ассоциативный массив $key на основе записей terminfo, чтобы помочь вам сопоставить их с виджетами. Итак, на этих системах вы можете сделать:

 (($+key[Up])) && bindkey $key[Up] history-beginning-search-backward 

Что-то, что работает в системах, где терминал находится в режиме передачи с клавиатуры, и тех, которые не имеют или не имеют хеш- $key , вы можете сделать:

 bindkey $terminfo[kcuu1] history-beginning-search-backward bindkey ${terminfo[kcuu1]/O/[} history-beginning-search-backward 

Смотрите также:

  • Мои клавиши курсора не работают (ncurses FAQ)
  • Почему я не могу использовать клавиши курсора в (любой) оболочке? (xterm FAQ)

Курсорные клавиши – это весело.

Хотя они не так забавны, как редактирование клавиш, что действительно весело.

У вас есть два набора клавиш курсора на клавиатуре, одна на клавиатуре курсора и одна на клавиатуре калькулятора .

Большинство эмуляторов терминала пытаются (иногда довольно неудачно) использовать модель DEC VT, где каждый набор клавиш переключается индивидуально между режимом приложения и обычным режимом с использованием настроек частного режима DECCKM (режим DECCKM клавиатуры) и DECNKM (режим цифровой клавиатуры), соответственно. Идея режима приложения заключается в том, что клавиши на соответствующей клавиатуре превращаются в дополнительные функциональные клавиши приложения.

⇐ Это клавиатура курсора.
  • В обычном режиме клавиши со стрелками отправляют управляющие последовательности ECMA-48 CUB , CUF , CUU и CUD , если только не применяется модификатор t Alt ; в этом случае они отправляют управляющие последовательности DECFNK .
  • В режиме приложения клавиши со стрелками отправляют SS3 одну смену 3 последовательности.
Key Это клавиатура калькулятора.
  • В обычном режиме клавиши со стрелками отправляют управляющие последовательности ECMA-48 CUB , CUF , CUU и CUD , если только не применяется модификатор t Alt ; в этом случае они отправляют управляющие последовательности DECFNK или если комбинация числовой блокировки и сдвига не вызывает их отправлять цифры.
  • В режиме приложения клавиши со стрелками отправляют другой набор последовательностей SS3 одной сменой 3 (если, опять же, комбинация числовой блокировки и сдвига не заставляет их отправлять цифры).

[ Последовательность, которую вы указали ZLE связать с виджетом, представляет собой 7-битный псевдоним ECMA-48 для управляющей последовательности CSI A , которая является управляющей последовательностью CUP («Курсор ВВЕРХ»). Эта последовательность управления генерируется только DEC VT и их эмуляторами терминала-имитатора, когда клавиатура находится в нормальном режиме и модификатор ⎇ Alt не действует. Он не будет соответствовать последовательностям смены, отправленным, когда соответствующие клавиатуры находятся в режиме приложения.

База данных terminfo мутит воду и вызывает здесь дополнительное удовольствие, поскольку она не использует эту модель для терминального ввода-вывода. Скорее, он использует свою собственную другую модель, которая воплощает понятия «локальный» и «удаленный» ключи, а это совсем не то, что приложение DEC VT / переключение нормального режима фактически вообще подразумевает; и он имеет единый механизм локального / удаленного переключения, который в итоге раздельно переключает обе клавиатуры между режимами приложения / нормального режима.

terminfo – это способ не привязывать один конкретный тип терминала к настройке ZLE на тот случай, если вы обнаружите, что у вас есть терминал или эмулятор терминала, который не имитирует DEC VT. А shell Z предоставляет вам способы доступа к необходимым записям возможностей из записи базы данных. Таким образом, вы могли прочитать из terminfo, какие последовательности управления terminfo ожидает от клавиш курсора вверх / вниз / влево / вправо, и выполнить соответствующие команды bindkey которые отображают эти последовательности управления в виджеты.

Проблема в том, что terminfo не подходит для этой работы. У него есть только способ записать одну управляющую последовательность для каждой клавиши, тогда как, как вы можете видеть, клавиши могут отправлять как минимум три разные последовательности, в зависимости от режима и нажатых модификаторов. (Модификаторы могут значительно влиять на отправленные последовательности управления в модели DEC VT.) Поэтому вам нужно переключить терминал в режим, который генерирует то, что ожидает от terminfo.

Но это становится хуже: terminfo не соответствует. Одной управляющей последовательностью иногда является последовательность режима приложения DEC VT, как записи terminfo для типа терминала putty , иногда последовательность нормального режима DEC VT, как записи terminfo для типа терминала rxvt , но никогда не последовательность DECFNK . Таким образом, у вас нет возможности узнать, следует ли вам переключаться в приложение или в обычный режим с любым конкретным терминалом или эмулятором терминала. То, что будет работать правильно для одного, пойдет не так для другого.

Поэтому другой подход заключается в том, чтобы игнорировать terminfo и понимать, что вы уже и весьма счастливо предполагаете, что ваш терминал всегда будет похож на DEC VT с вашей исходной командой bindkey . Вам просто нужно два из них, чтобы убедиться, что, если ваш терминал находится в приложении или в нормальном режиме, последовательность управления, которую он отправляет, будет соответствовать:

  bindkey "^ [OA" история-начало-поиск-назад 

Однако это не справится с нажатием клавиш-модификаторов, что добавляет дополнительные параметры в последовательность управления CUP , что приводит к сбою упрощенного соответствия строк, которое ZLE использует, когда все, что он ищет, – это просто старая CUP параметров. Вы должны вручную bindkey дополнительную команду bindkey для каждой возможной последовательности управления CUP , возникающей из каждой возможной комбинации модификаторов.

  сек 1 8 |
 пока читаешь -ри
 делать
     bindkey "^ [[1; $ {i} A" история-начало-поиск-назад
 сделанный 

ZLE здесь не один. Другие программы, основанные на terminfo, такие как fish shell, тоже страдают. (Люди из shell shell также выяснили, что выбор режима приложения / нормального режима, который подходит для одного эмулятора терминала, пойдет не так для другого.) Повторная архитектура этого (сравните libtermkey которого есть фактический анализатор управляющей последовательности ECMA-48 для ввода) в эти программы давно назрели. Но никто еще не справился с этим.

дальнейшее чтение

Linux и Unix - лучшая ОС в мире.