Как утилиты Linux избегают случайного разделения последовательностей ключей ANSI в потоке stdin? - PullRequest
0 голосов
/ 30 августа 2018

Эмуляторы терминала кодируют ввод с клавиатуры как escape-последовательности ANSI.

Клавиша Escape - это один байт: \ x1b
Ключ удаления составляет 4 байта: \ x1b '[' '3' '~'

Что отличает пользователя, нажимающего клавишу Delete, от последовательности клавиш «Escape», «[», «3», «~»?

Как интерактивные программы, такие как vim, показывают разницу?

Как эмуляторы терминала и утилиты, такие как SSH, отправляют последовательности ключей таким образом, чтобы принимающая программа правильно интерпретировала?

1 Ответ

0 голосов
/ 30 августа 2018

Timing.

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

В vim опции esckeys, ttimeout и ttimeoutlen определяют, нужно ли и как долго ждать завершения escape-последовательности. Это не традиционные варианты vi; в традиционном vi побег - это просто побег, а клавиши со стрелками бесполезны.

Вы можете проверить это, набрав Esc O A или Esc [ A очень быстро в VIM. Если вы достаточно быстры, и настройки вашего терминала не слишком экзотичны, один из них будет действовать как клавиша со стрелкой вверх. Медленно набирайте одно и то же, и оно сделает что-то другое Выполните команду :set noesckeys, и она никогда не будет действовать как клавиша со стрелкой (даже если вы действительно нажимаете клавишу со стрелкой) - это цена, которую вы должны заплатить, если хотите, чтобы ответ на клавишу выхода был мгновенным.

Эксперимент можно провести с другими последовательностями, такими как ^[[3~, но 3-символьную легче набрать.

Библиотека curses также использует тайм-ауты при интерпретации ввода с терминала. Вот связанный вопрос об этом: Как я могу узнать, что пользователь нажал клавишу ESC в консоли с помощью ncurses (Linux)?

...