Почему ключ END не имеет записи terminfo?

8

В системе 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,
Игорь Лайфренко
источник
1
Разница между homeи khomeзаключается в том, что khomeстрока - это последовательность, которую производит нажатие клавиши Home, тогда как homeстрока - это последовательность, которую следует отправить в терминал для перемещения курсора в исходное положение. Насколько мне известно, terminfo не определяет endвозможности, просто kend.
Йохан Мирен
@ JohanMyréen Не могли бы вы объяснить пример «исходного положения» курсора на примере? И почему kendопределяется как \EOFв terminfo , а терминал генерирует \E[F? Это ошибка в terminfo Debian ? И как все же ncurses обнаруживает это KEY_END?
Игорь Лайфренко
Исходная позиция - верхний левый угол экрана.
Йохан Мирен

Ответы:

10

Ответ Йохана Мирена был близок, но не совсем проблема: большинство эмуляторов терминала, которые вы будете использовать, имеют нормальный режим и режим приложений для специальных клавиш. Описания терминала написаны для одного режима, который соответствует тому, что использует полноэкранное приложение. Другие приложения (такие как интерактивная оболочка ) обычно не инициализируют экран для использования режима приложения . Bash является примером этого.

В обычном режиме xterm и аналогичные терминалы отправляют escape[(CSI), а в режиме приложения отправляют их клавиатуры escapeO(SS3). В Terminfo синтаксисе, что побег является \E. Так infocmpпоказывает вам, что описание использует режим приложения. homeСпособность передается в терминал, говоря ему , как переместить курсор на главную позицию (слева вверху), и не то же самое , как khome(пересылаются от терминала с помощью клавиатуры).

Полноэкранные приложения (например, использующие ncurses) могут отправлять строки возможностей терминала для инициализации клавиатуры. Некоторые описания терминалов переводят терминал в режим приложения, некоторые - нет.

Использование kendversus endявляется соглашением об именах: в terminfo по соглашению любое имя, начинающееся с k, ссылается на специальную клавишу (функциональную клавишу, клавишу курсора, клавиатуру), чтобы прояснить, что это строки, которые должны быть прочитаны приложением. Например, kcub1( кнопка курсора назад ) отличается от cub1(переместить курсор назад на один столбец).

ncurses распознает ключ, KEY_ENDпотому что приложение, которое вы используете, будет вызывать keypadфункцию для инициализации терминала, используя smkx(мнемоника означает «запуск режима передачи с клавиатуры»). Это может / не может фактически включить режим приложения. Описание терминала консоли Linux не соответствует описанию xterm.

В принципе, вы можете использовать tputдля переключения режима (и получить разные результаты showkey):

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
^C        3 0003 0x03
^D        4 0004 0x04
$ tput smkx
$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[OH     27 0033 0x1b
         79 0117 0x4f
         72 0110 0x48

В качестве осложнения curses распознает только одно имя строки. Некоторые терминалы (например, xterm) эмулируют старые аппаратные терминалы, используя разные названия клавиш на клавиатуре редактирования. В приведенном ниже списке часто задаваемых вопросов по xterm есть возможность присвоить этой клавише «Главная» команду «Вставить» ...

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

Томас Дики
источник
Да, я использую 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вместо того, чтобы делать то, что должна делать клавиша ввода.)
Игорь Лайфренко
5

Проблема с ключом Home состоит в том, что физические терминалы, а затем эмуляторы терминалов, которые имитируют их, имеют два режима: нормальный и прикладной режим, и escape-последовательности различаются в зависимости от режима, в котором находится терминал. Terminfo не справляется с этим. В обычном режиме (он же «Режим курсора») escape-последовательность клавиши End находится ESC [ Fв режиме приложения ESC O F. Погуглив эту проблему, ты обнаружишь весь беспорядок.

Редактировать Из источника terminfo:

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

Йохан Мирен
источник
Какова процедура перехода в «режим приложения»? Это сделано ncurses ?
Игорь Лайфренко