Когда я нажимаю AltUp, A
печатается на экране терминала. То же самое произошло, когда я нажал, AltDownно B
печатается вместо этого.
Другие персонажи, которых я осознал;
AltLeft= D
и AltRight=C
Какова цель этих команд?
решение1
В зависимости от того, как настроен терминал, ввод текста Alt+Keyподобен последовательному вводу клавиш Escи , поэтому он отправляет символ ESC (он же или ) , за которым следует символ или последовательность символов, отправленных при нажатии этого символа .Key\e
^[
\033
Key
При нажатии Upбольшинство эмуляторов терминала отправляют либо три символа \033[A
, либо \033OA
в зависимости от того, находятся ли они в режиме клавиатуры приложения или нет.
Первый соответствует escape-последовательности, которая при выводе на терминал перемещает курсор вверх. Если вы это сделаете:
printf '\nfoo\033[Abar\n\n'
Вы увидите bar
написанное после foo
одной строки вверх. Если вы это сделаете:
stty -echoctl; tput rmkx; read foo
Вы увидите, что клавиши со стрелками перемещают курсор.
Когда приложение zsh
считывает vi
эту последовательность символов с терминала, оно интерпретирует ее как действие «Вверх», поскольку из базы данных terminfo ( kcuu1
capability) ему известно, что это управляющая последовательность, отправляемая при нажатии Up.
Теперь, для Alt-Up, некоторые терминалы, такие как rxvt
и его производные, такие как eterm
send \033
с последующей escape-последовательностью для Up(то есть \033\033[A
или \033\033OA
), в то время как некоторые другие, такие как xterm
или , gnome-terminal
имеют отдельные escape-последовательности для этих типов клавиш при использовании с комбинацией клавиш, такой как Alt, Shift, Ctrl.
Обычно они отправляются \033[1;3A
по адресу Alt-Up.
При отправке на терминал эта последовательность также переместит курсор вверх (второй параметр (3) игнорируется). Соответствующего нетклавиатураключ, так что это та же самая последовательность, которая отправляется Alt-Upв или изрежим клавиатуры приложения.
Теперь, будь то \033\033[A
или \033[1;3A
, многие приложения не знают, для чего нужны эти последовательности. База данных terminfo им не поможет, потому что нет такой возможности, которая определяет, какие символы отправляют эти комбинации клавиш.
Они постараются изо всех сил интерпретировать эту последовательность. bash
например, интерпретируют \033[1;3
как escape-последовательность, ничего о ней не знают, поэтому ничего не делают, за которыми следует A
. zsh
, прекратят чтение, как только обнаружат, что нет известной совпадающей последовательности символов. Нет никакой escape-последовательности, которая бы с нее начиналась, \033[1
поэтому они пропустят ее и прочитают остальное: ;3A
и вставят это в редактор строк.
Многие приложения, такие как vi
, zsh
или readline
основанные на них приложения, такие как gdb
или bash
(хотя будьте осторожны, поскольку bash
они используют модифицированную версию readline
), позволяют добавлять привязки для любой последовательности символов.
Например, в zsh
, вы можете захотеть связать Alt-Up, Alt-Downнапример:
bindkey '\e[1;3A' history-beginning-search-backward
bindkey '\e[1;3B' history-beginning-search-forward
Они предназначены для поиска в истории командных строк, начинающихся так же, как текущая, и до текущей позиции курсора, что весьма удобно для вызова предыдущих команд.
решение2
Вы можете использовать Crtl+ vдля возврата входных кодов вашей клавиатуры. Если вы сделаете это для клавиш со стрелками, вы получите значения [[D^
, [[C^
, [[A^
, и [[B
. Для клавиш со стрелками + нет никаких привязок по умолчанию Alt, поэтому кажется, что выполняемое действие — это печать только кода буквы. Однако, если вы создадите свою локальную версию файла конфигурации библиотеки readline:
$ cp /etc/inputrc ~/.inputrc
И добавьте строку:
"\e[1;3C": "sometexthere"
Где [1;3C
находится входной код Alt+ →(его можно получить тем же способом, что и раньше, с помощью сочетания клавиш Crtl+ v) и перезапустите терминал, после чего сочетание клавиш Crtl+ →вернет вам текст «sometexthere», а другие Altсочетания клавиш +arrow перестанут возвращать символы.
Вместо текста вы можете передать связываемую команду изhttp://www.gnu.org/software/bash/manual/html_node/Bindable-Readline-Commands.html#Bindable-Readline-Commandsнравиться
"\e[1;3C": unix-line-discard
чтобы получить тот же эффект, что и Crtl+ u(удалить строку).
Более подробная информация здесь:http://cnswww.cns.cwru.edu/php/chet/readline/readline.html
решение3
Ключ Altчасто используется какметамодификатор. Курсорные и функциональные клавиши называютсяспециальные клавишипоскольку они могут отправлять несколько символов — и отправляемые символы могут быть изменены.
Некоторые пользователи, например, bash
ожидают, что нажатие Altотправит клавишу с префиксом escape-символа. Задокументированная функция "мета" (см.terminfo(5)
) имеет дело с восьмым битом:
Если на терминале есть «мета-клавиша», которая действует как клавиша Shift, устанавливая 8-й бит любого передаваемого символа, этот факт можно обозначить с помощью
km
. В противном случае программное обеспечение будет считать, что 8-й бит — это четность, и он обычно будет очищен. Если существуют строки, чтобы превратить это"мета-режим" Включено и выключено, их можно задать какsmm
иrmm
.
bash
знает об этом тоже (см.Часто задаваемые вопросы по ncurses), но мало кто из пользователей интересуется этой функцией. Тем не менее, они привыкли называть его Alt«мета», даже если режим мета отключен. И rxvt, и xterm имеют эту функцию с (как минимум) начала 1990-х годов.
Другие пользователи (после xterm
введения этой функции впатч №94, 1999) может ожидать, что информация о модификаторе будет закодирована как параметр в последовательности символов, которую будет отправлять специальная клавиша. В документации XTerm эти измененные клавиши называются"ПК-стиль"функциональные клавиши, чтобы отличить их от"VT220-стиль"(у которого не было модификаторов). Немодифицированная клавиша курсора может отправить ESC[A, но также допустимо иметьпараметр, например, ESC[5A, которое приложениедолженпонимать как повторение этого пять раз. Первая версия xterm
'sПК-стильКлючи использовали эту "5" для обозначения control, а в более поздней версии это было изменено, чтобы избежать путаницы с количеством повторений. Итак...
ESC[5A
предлагает приложению переместить курсор на 5 строк вверх, пока
ESC[1;5A
предполагает, что он переместится на одну строку вверх, сообщая приложению о controlнажатии клавиши.
Полезные комбинации находятся в базе данных ncurses terminfo с тех пор, как2004:
# 2004-07-17
# * add xterm-pc-fkeys -TD
База данных terminfo показывает текущую версиюxterm+pcfkeysс комментарием, показывающим, как кодируются модификаторы:
# This fragment describes as much of XFree86 xterm's "pc-style" function
# keys as will fit into terminfo's 60 function keys.
# From ctlseqs.ms:
# Code Modifiers
# ---------------------------------
# 2 Shift
# 3 Alt
# 4 Shift + Alt
# 5 Control
# 6 Shift + Control
# 7 Alt + Control
# 8 Shift + Alt + Control
# ---------------------------------
# The meta key may also be used as a modifier in this scheme, adding another
# bit to the parameter.
(Alt и meta не обязательно являются одной и той же клавишей). Этоструктурный элемент(в свою очередь, состоящий из других строительных блоков), из которыхxterm
Описание терминала сформировано. Он использует расширение, предоставленное в ncursesс 1999 годакоторый позволяет имена, определяемые пользователем. Поскольку termcap поддерживает только 2-символьные имена и 1023-байтовые описания, не было причин делать эти расширенные имена доступными черезtermcapИнтерфейс. Они легко доступны для приложений, использующихтерминфоинтерфейс.
А вот теперь возникает трудность: есть несколько способов, с помощью которых приложение может определить, что представляет собой подобная последовательность клавиш:
- полностью проанализировать последовательность символов
- частично проанализируйте его и отбросьте модификатор, controlесли он не нужен
- просто сравните последовательность символов со словарем, надеясь таким образом определить значение.
Немногие программы могли бы сделать первое; некоторые текстовые редакторы могли бы сделать второе (на самом деле, я так и сделал)этотдляded
вконец 1980-х). Разработчики таких приложений, как , bash
выбрали третий путь, предположив, что большая часть информации находится вtermcap. В качестве альтернативы они могли бы создать таблицу с информацией termcap/terminfo и использовать интерфейс, который предоставил лучшую информацию. xterm
делает это дляtcap-запросфункция, обеспечивающая vim
фактическое назначение функциональных клавиш.
Поскольку ни одна из строк, bash
с которыми выполняется сравнение, не совпадает с полученными строками, он может запутаться, довольствуясь частичным совпадением (например, сам по себе экранирующий символ).
Дальнейшее чтение: