Проблема Tmux Terminfo с привязкой клавиш Zsh

Zsh в режиме редактирования Emacs поставляется с привязкой по ключу по умолчанию ALT + Backspace, чтобы удалить слово с правой стороны курсора и ALT + D, чтобы удалить слово с левой стороны. Я хотел бы добавить последнюю функцию к ALT + DEL дополнительно.

Я попытался использовать базу данных terminfo чтобы правильно установить escape-последовательность для комбинации клавиш для каждого $TERM . В man terminfo я читал о kDC3 что kDC3 является Capname, которое, вероятно, мне нужно использовать для ALT + DEL .

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

 bindkey -e `tput kDC3` kill-word 

Это хорошо работает, когда я подключаюсь к своей машине напрямую через SSH ( $TERMxterm ). Но когда я запускаю Zsh внутри Tmux-сессии ( $TERMscreen ), я получаю следующее сообщение об ошибке:

 tput: unknown terminfo capability 'kDC3' 

Может ли это означать, что невозможно связать что-либо с ALT + DEL в Tmux? Или я просто делаю что-то неправильно? Может быть, kDC3 не является правильной последовательностью?

Я запускаю Debian Wheezy Beta 4 x86_64.

3 Solutions collect form web for “Проблема Tmux Terminfo с привязкой клавиш Zsh”

Первая проблема заключается в том, что ваша запись terminfo для screen не определяет возможности kDC3 ; это, вероятно, типично. Вы можете либо добавить эту возможность к своей собственной пользовательской записи screen , либо вы можете «жестко закодировать» последовательности в ваших командах bindkey .


Добавление возможностей может помочь другим программам узнать о ключах, но оно децентрализует вашу конфигурацию (было бы легко забыть об этой настройке, когда вы вручную реплицируете свою конфигурацию на новую машину или учетную запись пользователя). Вы можете извлечь соответствующие записи с помощью infocmp и создать новую запись с tic :

 { infocmp -xT screen ; infocmp -x1T xterm | grep -E '^\tkDC[3-8]?=' ; } >/tmp/s tic -x /tmp/s 

Если вы запустите tic как пользователь, который имеет право на запись в ваш каталог terminfo (например, /usr/share/terminfo ), тогда будет помещена новая запись (возможно, переписывая исходную запись); в противном случае он будет помещен под ~/.terminfo (или TERMINFO, если у вас установлена ​​эта переменная среды).

Для полноты вы можете использовать (UP|DN|RIT|LFT|PRV|NXT|HOM|END|IC|DC) вместо DC в шаблоне grep для захвата модифицированных версий Up, Down, Right, Left, PageUp, PageDown, Home, End, Insert и Delete.


Если вам не нравится децентрализация конфигурации, вызванная настройкой вашей записи terminfo, тогда вы можете «жестко закодировать» значение. Чтобы сделать его немного лучше, вы можете сначала проверить для kDC3 :

 bindkey -e ${$(tput kDC3 2>/dev/null):-'\e[3;3~'} kill-word 

Чтобы ограничить это «жесткое кодирование» только значениями TERM на основе screen :

 altdel=$(tput kDC3 2>/dev/null) [[ -z $altdel && $TERM == screen(|-*) ]] && altdel='\e[3;3~' [[ -n $altdel ]] && bindkey -e $altdel kill-word unset altdel 

Это будет работать до тех пор, пока ваш эмулятор терминала (стек) завершит создание последовательности xterm- стиля для модифицированного ключа.


Если у вас есть привязка, вам все равно нужно включить параметр xterm-keys в tmux, чтобы он генерировал последовательности xterm- стиля для ключей, переданных в его панели. Например, в ~/.tmux.conf :

 set-option -wg xterm-keys on 

Это зависит:

  • ncurses поддерживает расширенные ( определяемые пользователем ) возможности терминала.
  • kDC3 является расширенной возможностью терминала.
  • Ни один из tmux , zsh или emacs ничего не знает о kDC3 .
  • хотя tmux имеет kDC3 в таблице , он не вызывает use_extended_names чтобы включить эту функцию.
  • ncurses tput будет знать о kDC3 , если он определен в описании текущего терминала.

screen программа (которая имитирует tmux ) также ничего не знает о kDC3 . Это приложение termcap , и (для себя) обращает внимание только на 2-символьные имена. Однако на screen есть функция, которая напрямую решает вопрос: в руководстве ( 16.1 Выбор записи termcap для окна ) он сообщает, как он выбирает параметр для TERM в сеансе экрана:

Когда screen пытается определить имя терминала для себя, он сначала ищет запись с именем screen. term , где термин – это содержимое переменной $TERM . Если такой записи нет, экран запускает screen (или screen-w , если терминал широк (132 столбца или более)). Если даже эта запись не найдена, vt100 используется в качестве замены.

Идея состоит в том, что если у вас есть терминал, который не поддерживает важную функцию (например, удалить символ или очистить до EOS), вы можете создать новую запись termcap / terminfo для экрана (named screen.dumbterm ), в которой эта возможность отключена , Если эта запись установлена ​​на ваших машинах, вы можете выполнить rlogin и сохранить правильную запись termcap / terminfo. Имя терминала помещается в переменную $TERM всех новых окон. screen также устанавливает переменную $TERMCAP отражающую возможности эмуляции виртуального терминала. Кроме того, переменная $WINDOW устанавливается на номер окна каждого окна.

Терминальная база данных ncurses использует эту функцию для предоставления наиболее распространенных вариантов screen с xterm и другими терминалами, которые похожи, но имеют разные функциональные клавиши, такие как konsole , vte (например, gnome-terminal), rxvt . За исключением rxvt , остальные все еще устанавливают TERM на xterm .

В конфигурации по умолчанию вы можете не иметь этих описаний терминалов (и screen будет по-прежнему продолжать устанавливать TERM=screen и провоцировать пользователей в отчеты об ошибках, как этот вопрос). Debian, например, в своем пакете terminfo ncurses-base предоставляет только минимальный набор описаний терминалов. Вам нужно будет установить ncurses-term чтобы получить полную базу данных терминала.

Описание терминала для screen , конечно, не описывает никаких расширенных функциональных клавиш. Он включает в себя эти расширенные возможности, кстати:

 AX, G0, E0=\E(B, S0=\E(%p1%c, 

но ни одно из этих приложений (кроме tput ) ничего не делает с ними.

tmux усложняет это, не полностью сопоставляя поведение screen : он не проверяет альтернативные имена, которые предоставляет ncurses. Не объясняя, почему, на странице руководства

Переменная среды TERM должна быть установлена ​​на “screen” для всех программ, запущенных внутри tmux . В новых окнах автоматически добавится “TERM=screen” в их среду, но следует соблюдать осторожность, чтобы не перезапускать это в файлах запуска оболочки.

Вероятная причина заключается в том, что разработчик не хотел гарантировать поведение (для обновления экрана) возможностей терминала, не найденных на screen . Функциональные клавиши – это другое дело. Вы можете изменить описание терминала, как было предложено, хотя это оказалось проблемой проблемы, чем решение:

  • Мой терминал не распознается
  • Как настроить частную базу данных terminfo?

Предлагаемый сценарий , кстати, не работает. Отображение исправленного сценария было бы бессмысленным, учитывая весь фон для этой проблемы. Вместо поэтапных настроек в базе данных терминалов я был бы склонен иметь оператор case в инициализации оболочки, который проверял установку TERM на screen , и проверить, есть ли лучшая альтернатива уже в базе данных терминала. Выполнение этого правильно усложняется отказом разработчиков устанавливать TERM соответствии с возможностями своего терминала, но вы можете получить большую часть этого пути, посмотрев на переменную окружения COLORTERM .

Для вашего развлечения:

  • Где установлен COLORTERM?
  • Поддержка пользовательских TERM и COLORTERM env vars
  • Изменить переменную среды (TERM)
  • Экспортировать окружающую переменную, которая указывает, что мы находимся в KMSCON # 60
  • Как я могу обнаружить терминал Gnome?
  • RoxTerm # 38 [PATCH] Сделать переопределяющую переменную среды TERM возможной
  • Fedora: Особенности / 256 цветных терминалов

Из того, что видно из внутренних элементов tmux, похоже, не уделяет много внимания параметрам terminfo и тому подобное. Например, если вы включите режим xterm:

 set-window-option -g xterm-keys on 

фактические escape-последовательности, соответствующие различным клавишам, жестко закодированы в программу и, вероятно, отличаются от того, что скажет вам infocmp xterm .

В дополнение к этому tmux игнорирует все, что находится выше F20 потому что у него есть только определенный набор ключей, которые он распознает жестко. Так что-то вроде этого

 set-option -g terminal-overrides "screen:kf34=\033[21;5~" 

или

 tmux bind-key -t emacs-copy F34 page-up 

не собирается ничего делать, независимо от того, что xterm или tput выплевывает. По крайней мере, так оно и есть в настоящее время.

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

  • Как работать с именами файлов, содержащими одну цитату внутри функции завершения zsh?
  • Как заставить мои функции оболочки использовать существующую автозаполнение в zsh?
  • Автозаполнение оболочки очень медленное после форматирования частичного диска
  • Как проверить, запрашивалась ли предыдущая команда для ввода?
  • Почему rm исключает использование! не работает в zsh?
  • Как включить вкладку zsh / prezto?
  • Поиск не работает
  • Как увеличить историю в oh-my-zsh?
  • Как заставить команды выделяться жирным шрифтом в zsh?
  • zsh автозавершение некоторых частей каталога
  • Bindkey для выполнения команды (Zsh)
  • Linux и Unix - лучшая ОС в мире.