В системе Debian нажатие END
клавиши генерирует ^[[F
:
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[F 27 0033 0x1b
91 0133 0x5b
70 0106 0x46
Но почему этот keychord не находится в terminfo ?
$ infocmp -1 | grep end
kend=\EOF,
Тем не менее, ncurses удается правильно распознать его как KEY_END
. Как?
TERM
является xterm-256color
Кстати, какова мотивация иметь, kend
а end
не просто end
? (то же самое для khome
и home
)
РЕДАКТИРОВАТЬ
Как сказано в комментарии Йохана Мирина, khome
строка - это последовательность, вызываемая клавишей Home. Но на Debian нажатие клавиши Home выдает home
. Почему?
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[H 27 0033 0x1b
91 0133 0x5b
72 0110 0x48
$ infocmp -1 | grep home
home=\E[H,
khome=\EOH,
home
иkhome
заключается в том, чтоkhome
строка - это последовательность, которую производит нажатие клавиши Home, тогда какhome
строка - это последовательность, которую следует отправить в терминал для перемещения курсора в исходное положение. Насколько мне известно, terminfo не определяетend
возможности, простоkend
.kend
определяется как\EOF
в terminfo , а терминал генерирует\E[F
? Это ошибка в terminfo Debian ? И как все же ncurses обнаруживает этоKEY_END
?Ответы:
Ответ Йохана Мирена был близок, но не совсем проблема: большинство эмуляторов терминала, которые вы будете использовать, имеют нормальный режим и режим приложений для специальных клавиш. Описания терминала написаны для одного режима, который соответствует тому, что использует полноэкранное приложение. Другие приложения (такие как интерактивная оболочка ) обычно не инициализируют экран для использования режима приложения . Bash является примером этого.
В обычном режиме xterm и аналогичные терминалы отправляют escape
[
(CSI), а в режиме приложения отправляют их клавиатуры escapeO
(SS3). В Terminfo синтаксисе, что побег является\E
. Такinfocmp
показывает вам, что описание использует режим приложения.home
Способность передается в терминал, говоря ему , как переместить курсор на главную позицию (слева вверху), и не то же самое , какkhome
(пересылаются от терминала с помощью клавиатуры).Полноэкранные приложения (например, использующие ncurses) могут отправлять строки возможностей терминала для инициализации клавиатуры. Некоторые описания терминалов переводят терминал в режим приложения, некоторые - нет.
Использование
kend
versusend
является соглашением об именах: в terminfo по соглашению любое имя, начинающееся с k, ссылается на специальную клавишу (функциональную клавишу, клавишу курсора, клавиатуру), чтобы прояснить, что это строки, которые должны быть прочитаны приложением. Например,kcub1
( кнопка курсора назад ) отличается отcub1
(переместить курсор назад на один столбец).ncurses распознает ключ,
KEY_END
потому что приложение, которое вы используете, будет вызыватьkeypad
функцию для инициализации терминала, используяsmkx
(мнемоника означает «запуск режима передачи с клавиатуры»). Это может / не может фактически включить режим приложения. Описание терминала консоли Linux не соответствует описанию xterm.В принципе, вы можете использовать
tput
для переключения режима (и получить разные результатыshowkey
):В качестве осложнения curses распознает только одно имя строки. Некоторые терминалы (например, xterm) эмулируют старые аппаратные терминалы, используя разные названия клавиш на клавиатуре редактирования. В приведенном ниже списке часто задаваемых вопросов по xterm есть возможность присвоить этой клавише «Главная» команду «Вставить» ...
Дальнейшее чтение:
getch
страница руководства)источник
keypad
функцию. Но с вопросом "как ncurses удается обнаружить его какKEY_END
" я имел в виду "какkeypad
декодировать^[[F
вkend
" (учитывая, что для интерпретации цепочек ключейkeypad
используется база данных terminfo ). Если я правильно понял, это происходит потому, чтоshowkey -a
находится в режиме курсора, тогда как приложение ncurses находится в режиме приложения.showkey
не переключается между обычным / прикладным режимами. Это специфичная для Linux программа, делающая предположения о консоли Linux, а не использующая базу данных терминалаshowkey
не переключается между режимами, то он использует состояние по умолчанию, как бы оно ни называлось. Дело в том , чтоshowkey
отпечатки^[[F
, а не^[OF
, которые приводят к моей растерянности. (Я просто использовалshowkey
для визуального представления фактическую клавиатуру, которую посылает терминал, нажимая на кнопку клавиатуры, не подозревая, что в этом могут быть какие-то тонкости.)tput smkx
и получить другие результаты.less
утилите: она переводит себя в режим приложения, но затем не может интерпретировать клавишу ввода клавиатуры. Должен ли я отправить отчет об ошибке? (Вы можете проверить это, запустивless
и нажав клавишу ввода на клавиатуре после ввода/
- она выведетESCOM
вместо того, чтобы делать то, что должна делать клавиша ввода.)Проблема с ключом Home состоит в том, что физические терминалы, а затем эмуляторы терминалов, которые имитируют их, имеют два режима: нормальный и прикладной режим, и escape-последовательности различаются в зависимости от режима, в котором находится терминал. Terminfo не справляется с этим. В обычном режиме (он же «Режим курсора») escape-последовательность клавиши End находится
ESC [ F
в режиме приложенияESC O F
. Погуглив эту проблему, ты обнаружишь весь беспорядок.Редактировать Из источника terminfo:
тогда предполагается, что клавиши курсора находятся в «режиме курсора», и определения клавиш курсора должны соответствовать этому предположению, в противном случае приложение может завершиться ошибкой. Также ожидается, что приложения всегда будут передавать строку в терминал, прежде чем они выйдут ».
источник