Какие символы печатаются при нажатии клавиш Alt + Arrow?

13

Когда я нажимаю AltUp, Aвыводится на экран терминала. То же самое произошло, когда я нажал, AltDownно Bвместо этого печатается.

Другие персонажи, которые я понял;

AltLeft= Dи AltRight=C

Какова цель этих команд?

yfklon
источник

Ответы:

14

В зависимости от того, как настроен терминал, набрав Alt+Key, как набрав Escи Keyклавиши в последовательности, так что она посылает ESC символ (он же \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возможность), что это escape-последовательность, отправляемая после нажатия Up.

Теперь для Alt-Upнекоторых терминалов, таких как rxvtи его производных, таких как etermsend, \033за которыми следует escape-последовательность для Up(то есть \033\033[Aили \033\033OA), в то время как некоторые другие, какxterm или gnome-terminalимеют отдельные последовательностей для этих типов ключей при использовании комбинированных ключей , таких как 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

Они предназначены для поиска в истории вперед и назад командных строк, которые начинаются, как текущая, до текущей позиции курсора, что очень удобно для вызова предыдущих команд.

Стефан Шазелас
источник
3

Вы можете использовать Crtl+ vдля возврата кодов ввода вашей клавиатуры. Если вы сделаете это для клавиш со стрелками, вы получите [[D^, [[C^, [[A^и [[Bзначение. Для клавиш со Altстрелками + нет привязок по умолчанию , поэтому кажется, что выполненное действие - это печать только буквенного кода. Однако, если вы создаете локальную версию файла конфигурации библиотеки readline:

$ cp /etc/inputrc ~/.inputrc

И добавьте строку:

"\e[1;3C": "sometexthere"

Где [1;3Cнаходится входной код Alt+ (вы можете получить его так же, как и до использования Crtl+ vярлыка) и перезапустить свой терминал, тогда Crtl+ ярлык вернет вам текст «sometexthere», а другие Altсочетания клавиш + прекратят возвращать символы.

Вместо текста вы можете передать связываемую команду из 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

Nykakin
источник
3

AltКлюч часто используется в качестве мета - модификатора. Курсорные и функциональные клавиши называются специальными клавишами поскольку они могут отправлять несколько символов - и отправляемые символы можно изменить.

Некоторые пользователи, например, bashожидают, что нажатие Altотправит клавишу с префиксом escape-символа. Документированная мета-функция (см. terminfo(5)) Имеет дело с восьмым битом:

Если терминал имеет «мета-ключ», который действует как клавиша Shift, устанавливая 8-й бит любого передаваемого символа, этот факт можно указать с помощью km. В противном случае программное обеспечение будет предполагать, что 8-й бит равен четности, и обычно он очищается. Если существуют строки для включения и выключения этого «мета-режима» , они могут быть заданы как smmи rmm.

bashоб этом тоже знает (см. ncurses FAQ ), но мало кто из пользователей заинтересован в этой функции. Тем не менее, они привыкли называть Alt«мета», хотя мета-режим отключен. И у rxvt, и у xterm эта функция была (по крайней мере) в начале 1990-х годов.

Другие пользователи (с тех пор как xtermэта функция появилась в патче № 94, 1999 ) могут ожидать, что информация модификатора будет закодирована как параметр в последовательности символов, которую отправит специальный ключ. В документации XTerm эти модифицированные клавиши называются функциональными клавишами в стиле «ПК», чтобы отличать их от «стиля VT220» (в котором не было модификаторов). Немодифицированная клавиша курсора может отправить ESC[A, но также допустимо иметь параметр , например ESC[5A, который приложение должно понимать как повторение этого пять раз. Первая версия xterm«S PC-стиль ключей используется , что„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 поддерживает только двухсимвольные имена и 1023-байтовые описания, не было никаких причин делать эти расширенные имена доступными через интерфейс termcap . Они легко доступны для приложений, использующих интерфейс terminfo .

Теперь возникает трудность: у приложения есть несколько способов определить, что представляет собой подобная последовательность клавиш:

  1. проанализировать последовательность символов полностью
  2. частично проанализировать его и выбросить controlмодификатор, если он не нужен
  3. просто сравните последовательность символов со словарем, надеясь определить значение таким образом.

Немногие программы сделали бы первое; некоторые текстовые редакторы будут делать второй ( на самом деле, я сделал это для dedв конце 1980 - х годов ). Разработчики приложений, например, bashвыбрали третий путь, предполагая, что большая часть информации находится в termcap . В качестве альтернативы они могли бы составить таблицу с информацией termcap / terminfo и использовать интерфейс, предоставляющий наилучшую информацию. xtermделает это для функции tcap-query , предоставляя vimфактические назначения функциональных клавиш.

Поскольку ни одна из строк, bashсравниваемых со строками, не совпадает со строками, которые он получает, он может запутаться, соглашаясь на частичные совпадения (например, сам символ перехода).

Дальнейшее чтение:

Томас Дики
источник