Есть ли терминалы Linux, которые могут обрабатывать все комбинации клавиш?


11

Мне нравится использовать emacs в режиме терминала ( -nw), но кажется, что большинство (все?) Терминалы не могут обрабатывать некоторые комбинации клавиш - например, C-<RET>или C-M-%. Я знаю, что это потому, что большинство терминалов эмулируют VT-100, у которого не было этих комбинаций. Существуют ли какие-либо терминалы Linux (предпочтительно KDE), которые могут обрабатывать эти комбинации клавиш, или это фундаментальное ограничение всех терминалов?

Ответы:


15

Когда вы нажимаете клавишу или комбинацию клавиш в терминале, она передается приложению, работающему в терминале, как последовательность из одного или нескольких символов. Например, когда вы нажимаете a, приложение получает a. При нажатии Enterприложение получает символ CR(он же ^M(произносится как «control-emm»), он же символ номер 13, он же \rили \015). Включающие комбинации клавиш Altобычно передаются в виде символа ESC( ^[aka \eили aka \033), за которым следует последовательность для клавиши или комбинации клавиш без Alt. Функциональные клавиши и другие комбинации клавиш передаются как escape-последовательности, начинающиеся с \e[или \eO.

Последовательности escape-полей не полностью стандартизированы, и терминалы обычно игнорируют определенные атрибуты для определенных ключей. Например, Ctrl+ Shift+ letterчасто передается в точности как Ctrl+ letterпо умолчанию.

Вы можете увидеть, что ваш терминал отправляет для комбинации клавиш, нажав Ctrl+, Vзатем эту комбинацию клавиш в приглашении оболочки или C-qили C-h cпосле комбинации клавиш в Emacs.

С некоторыми эмуляторами терминала вы можете настроить escape-последовательности для каждого ключа. На Xterm это делается через X ресурсы . Большинство настроек считывают ресурсы с ~/.Xresourcesмомента запуска X, и вы можете загрузить файл вручную с помощью xrdb -merge ~/.Xresources.

Term.VT100.translations:       #override \n\
    Ctrl ~Shift ~Meta <key>Return: string("\033[73;5~") \n\
    Ctrl Shift ~Meta <key>percent: string("\033[37;6~")

Общее соглашение использует escape-последовательности вида ESC [ number1 ; number2 ~для функциональных клавиш с модификаторами. number1указывает на функциональную клавишу ( 15в 24течение F5до F12- по историческим причинам, F1 через F4разные управляющие последовательности) и number2указывает модификатор ( 2для Shift, 5для Ctrl, 3для Meta, 8для Ctrl+ Metaи добавить 1 для + Shift- нет, это не очень последовательно).

Emacs переводит escape-последовательности во внутреннее представление ключа через input-decode-mapилиlocal-function-key-map (или function-key-mapдо Emacs 23).

(define-key local-function-key-map "\033[73;5~" [(control return)])
(define-key local-function-key-map "\033[37;6~" [(control ?L)])

Итак, если я правильно понимаю, мне нужно сначала определить escape-последовательность в моем терминале, которая соответствует некоторой комбинации клавиш. Затем в emacs мне нужно отобразить escape-последовательность обратно на комбинацию клавиш. Может ли escape-последовательность быть произвольной, если она не конфликтует с определенной в infocmp $TERM?
Йоссариан

2
@Yossarian Да. В дополнение к отсутствию противоречий escape-последовательности должны быть однозначными, то есть никакие escape-последовательности не должны быть префиксом другой. На практике это означает, что первый символ должен быть ESC(если вы не хотите попробовать какой-либо символ ≥128, но это ограничит возможные входные кодировки), а второй символ должен быть чем-то, для чего вы не хотите ESC fooпривязывать.
Жиль "ТАК - перестань быть злым"

Я только что попробовал то, что ты предложил. Должно local-set-keyбыть на самом деле define-key? Первый дает ошибку (неверное количество аргументов), а второй работает, по крайней мере, для <kbd> C-Enter </ kbd>. Кажется, у konsole все еще есть проблемы с отправкой <kbd> CM -% </ kbd>.
Йоссариан

@Yossarian Действительно, так и должно быть define-key. Я не знаю, можно ли настроить управляющие клавиши Konsole, возможно, xterm более настраиваемый, чем любая другая альтернатива.
Жиль "ТАК - перестать быть злым"

1
Обратите внимание, что xterm Томаса Дики находится в стадии активной разработки. С XTerm*modifyOtherKeys: 2ресурсом он будет генерировать уникальные последовательности даже для C-M-комбинаций, но с этим параметром вам нужно будет предоставить множество пользовательских отображений ( XTerm*modifyOtherKeys: 1менее функционально, но гораздо более функционально из коробки). Для примера (хотя тот, который не работал для меня) см. xterm-extras.elБиблиотеку и связанные с ней .Xresourcesи .inputrcфайлы в загрузке easymacs .
Фил

1

Для ограниченного, но значительного набора ключей, при условии, что KDE поддерживает KDE, можно выполнить следующие сложные рабочие сочетания клавиш в emacs -nw:

Я буду использовать мою реализацию получения S-<RET>работы в качестве примера:

  1. Откройте новую консоль, зайдите в настройки -> текущий профиль -> клавиатура -> изменить
  2. Нажмите Add и создайте новую запись для Return+Shiftи дайте ей полезную последовательность клавиш (я выбрал \E[27;3ту, которая, я думаю, является последовательностью клавиш, отправленной X, когда я копался в xev, но это может быть неправильно - важно сделать уверен, что он имеет правильный выход и не конфликтует ни с чем другим).
  3. Поиграйте с ним в маленькой тестовой зоне внизу, чтобы убедиться, что она работает.
  4. Перезапустите консоль.
  5. Запустите emacs -nwи в чистом буфере оцените:

    (read-key-sequence-vector "Type your new key:")

    затем введите новую комбинацию клавиш.

    • Если вы не знакомы с этим, напишите строку, оставьте курсор в конце строки и нажмите Cx Ce, чтобы заставить emacs запустить эту строку, он должен сказать вам все, что вы поместили в кавычки, и ждать, пока вы введите что-либо.
  6. Он должен выплевывать последовательность клавиш, которую вы можете связать.
    (Он вернулся [27 91 50 55 59 51]ко мне в отличие от скучного старого, [13]прежде чем я перепутал связывание ключей konsole.)

  7. Добавьте к вашей конфигурации emacs:

    (define-key function-key-map [27 91 50 55 59 51] [(shift return)])
    
  8. Я проверил это с emacs -nwпомощью сеанса экрана, используя:

    (define-key ess-mode-map [(shift return)] #'ess-eval-line-and-step)
    (define-key sh-mode-map [(shift return)]  #'send-line-to-shell)
    

0

Короткий ответ - это фундаментальное ограничение всех терминалов.

Немного более длинный ответ таков: даже если кто-то создал терминал, который делает то, что вы хотите, сам Emacs потребует серьезных изменений для работы с этим гипотетическим терминалом.


Это хороший момент в Emacs, который даже не приходил мне в голову. Я думаю, что я начну использовать графический интерфейс вместо этого.
Йоссариан

Это то, чем я занимаюсь.
Хрувулум

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.