Вы не можете изменить C-[привязку на картах уровня пользователя, как вы это сделали бы global-set-key
. Однако вы можете изменить его как событие клавиатуры, прежде чем оно достигнет этих раскладок. Вы можете сказать, например:
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
а затем использовать [control-bracketleft]
в ваших клавишных картах. Довольно просто, не правда ли?
Режиссерский крой
К сожалению, это не так просто, и это решение требует некоторых корректировок, которые окажутся очень болезненными. Вы были предупреждены. Но давайте сначала посмотрим, почему карты уровня пользователя не могут ответить на этот вопрос. Далее я обращаюсь к руководству по Emacs Lisp для emacs 26.1, когда я говорю «вижу что-то» без большей точности.
C-[на очень ранней стадии интерпретируется как управляющий символ ASCII ESC
(см. 21.7.1 - События клавиатуры ). Этот код распространяется на все остальные места в качестве префикса для более длинных последовательностей. Для этого есть причина: ESC
на самом деле это мета-префикс (см. meta-prefix-char
), И все привязки, которые читают
M-что-либо , преобразуются в последовательность, которая начинается с ESC
. Таким образом, изменения глобальной карты будет недостаточно: вам нужно сначала изменить meta-prefix-char
, а затем переназначить ESC
новую meta-prefix-char
в каждой и каждой карте, которая используется, M-прежде чем вы сможете безопасно отобразить карту C-[.
Хорошо, тогда, конечно: давайте использовать input-decode-map
. Есть пара похожих карт, которые мы можем использовать (см. Разделы 21.8.3 и 22.14), но давайте придерживаться этого. И хорошо ... это работает! Вы сделали, не так ли?
На самом деле, нет, история не заканчивается здесь. Это работает ... пока вы используете оконную систему. Если из-за неудачи вы оказались в тюрьме в консоли linux в аварийном состоянии, вы понимаете, насколько драматичной стала ситуация: клавиши со стрелками Homeи, конечно же, M-привязки - все это мусор. Почему? Потому что, когда терминал говорит ESC
(что он делает, когда вы печатаете C-[), это действительно означает ESC
и запускает последовательность того же вида, которую он использует для передачи не-ASCII символов.
Наблюдая за катастрофой, вы можете посчитать целесообразным защитить вышеуказанную input-decode-map
модификацию таким образом, чтобы она активировалась только в том случае, если оконная система управляет клавиатурой:
(let ((frame (framep (selected-frame))))
(or (eq t frame)
(eq 'pc frame)
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
)))
Затем терминалы работают так, как раньше.
Теперь мы можем иметь дело с C-[терминалами? На самом деле, да, мы можем, как на консоли Linux, так и на других эмуляторах терминала, с которыми я могу играть. Но это делает историю довольно длинной, поскольку новые персонажи выходят на сцену. Ведь это уже не один emacs: терминал теперь играет центральную роль.
Давайте послушаем, что говорит консоль Linux. Введите C-vперед каким-нибудь ключом, чтобы услышать это ясно. C-[есть ESC
; так и есть Esc. Стрелка вверх звучит как ESC [ A
, пока M-aесть
ESC A
. Хмм ... Похоже, это мета-ключевые извилины в Emacs, не так ли? Тем не мение.
Если мы не готовы сыграть некоторые трюки, основанные на времени, прошедшем между событиями персонажа (которые, кстати, не будут отличаться
Escот других C-[), похоже, у нас нет другого выбора, кроме как сказать консоли, что мы на самом деле не имеем в виду ESC
когда мы наберем C-[. Более того, довольно скоро выясняется, что C-[это не единственная проблема со стандартными кодами терминала: модификаторы в большинстве случаев стирают передаваемую информацию. Нам нужно настроить терминал по той же причине, по которой мы настраиваем emacs: было бы намного практичнее, если бы мы это сделали.
На этом этапе вы должны осмотреть глаза документации вашего терминала: справочные страницы loadkeys(1)
для консоли linux, xterm
xterm(1)
в разделе « Привязки пользовательских клавиш» и все , что я знаю для других терминалов. В KDE konsole
, вы можете определить собственные переводы в Настройки / Редактировать текущий профиль ...
затем Клавиатура . Вот выдержка из ~/.local/share/konsole/Test.keytab
игры с этим последним диалогом:
key [+Ctrl+AnyModifier : "\EO*["
После того, как терминал отправит ESC O 5 [
запрос
C-[(как в приведенной выше конфигурации), вы можете вернуться к emacs. Конечно, вы еще не закончили.
Чтобы указать emacs, какой диалект использует данный терминал, вы можете настроить его input-decode-map
. Да, к счастью, это тот самый, который мы изменили в начале этой истории, и это тот самый момент,
term/xterm.el
к которому относится xterm. Хорошее место для настройки tty-setup-hook
(см. Раздел 40.1.3):
(add-hook 'tty-setup-hook
(lambda ()
(let ((term (getenv "TERM")))
(cond
(;; xterm-function-map not in doc, but in term/xterm.el
(boundp 'xterm-function-map)
(map-my-term-codes xterm-function-map))
((equal term "linux")
(map-my-term-codes input-decode-map))
)
)))
Имейте в виду, что этот хук работает, только если вы находитесь в терминале. Таким образом, вы не можете вставить сюда код для инициализации оконной системы. Вот функция перевода сама по себе:
(defun map-my-term-codes (map)
(define-key map (kbd "M-O 5 [")
[control-bracketleft])
)
И тогда вы можете немного отдохнуть: это конец пути. Конечно, если вам не нужны терминалы, это быстро, так как вы пропустите всю болезненную часть. Но вы признаете, что это также довольно неполно.
Две последние заметки:
Я выбираю ESC O 5 [
для кода C-[. Это всего лишь пример: я не буду притворяться, что это хороший выбор. Только та 5
часть, которая означает C-, кажется, подчиняется какой-то установленной конвенции
настройка консоли linux оставляет плохой вкус: кажется, что связывание невозможно без использования промежуточного существующего символа, а те, которые мне нужны
, не существуют . Я использую символы в диапазоне F21- F246как в большинстве интернет-примеров, но это не очень хорошо. Это нормально для нескольких несвязанных привязок, но это не будет служить систематической схеме.
редактировать
- Я закончил это с Escделом - которое имеет свою индивидуальность - в другом посте: Как удалить привязки к префиксному ключу ESC
Вот фрагмент конфигурации для кормления loadkeys
. Я помещаю это в /root/custom.kmap и загружаю, когда мне нужно (что редко). Моя фактическая конфигурация также отображает стрелки и различные комбинации модификаторов, но она довольно длинная, выбор символов и последовательностей сомнителен, и я не уверен, что коды клавиш для моей клавиатуры будут совпадать с вашими. Так что давайте держать его на должном уровне: это не что иное, как иллюстрация.
keymaps 0-127
# http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html
# web+man:keymaps
# web+man:loadkeys
# escape
keycode 1 = F100
alt keycode 1 = Escape # keep the Escape behavior somewhere
# keycode 26 = bracketleft
control keycode 26 = F115 # Control_bracketleft does not exist
string F100 = "\033OO" # map this to [escape] in map-my-term-codes
string F115 = "\033O5["