Проблеми з вкладками клавіш при використанні терміналу


30

У мене є такий рядок init.el:

(global-set-key [(control \;)] 'comment-region)

Він дуже добре працює у вікні графічного інтерфейсу, але якщо emacsцей -nwпараметр викликається, C-;він не коментує область, а лише вставляє ;символ. M-x comment-region RETпрацює добре, проте.

Я спробував дотримуватися цієї відповіді на подібну проблему, але C-q C-;повертається просто, ;і я, очевидно, не хочу пов'язувати голою ;.

Як досягти бажаного ефекту?


4
Можливо, що ваш термінал (для чого ви використовуєте, до речі?) Не розпізнає цю послідовність команд. Спробуйте скористатися C-;комбінацією, а потім скористайтеся, M-x view-lossageщоб побачити, чи не потрапляє він до Emacs.
Дан

Я використовую gnome-terminalі M-x view-lossageповертає:ESC [ > 1 ; 2 8 0 2 ; 0 c ; ESC x v i e w - l o s s a g e RET
WeSenseASoulInSearchOfAnswers

3
Схоже, проблема з терміналом: якби ця комбінація клавіш мала досягти Emacs, вона виглядала б C-;швидше, ніж c ;(або, принаймні, я розумію C-;).
Дан

@Dan: Чи можете ви поставити це як відповідь? Це позначило б питання як відповідь і полегшило б бачити рішення, що добре для інших людей, які мають таку ж проблему. Спасибі!
Тихон Єлвіс

Узагальнено та розміщено з додатковим посиланням для більшого читання. Також редагуйте заголовок питання, щоб зробити його трохи більш загальним.
Дан

Відповіді:


17

По-перше, більш загальна проблема: емулятори терміналів часто обмежені в послідовностях керування та виходу, які вони можуть надсилати. Отже: можливо так, що термінал проковтує ваші спеціальні символи, перш ніж вони дістануться Emacs. Як загальну діагностику, ви можете натиснути C-h l(або M-x view-lossage), щоб побачити, чи ваші комбінації клавіш перетворюються на Emacs.

Для більш детального обговорення цього питання ознайомтеся з цією ниткою переповнення стека та посиланнями на неї.

Підсумовуючи зворотні результати в коментарях, ваша конкретна проблема передбачає, що проблема не терміналу, а не Emacs. Коли ви спробували, C-;а потім M-x view-lossage, ви отримали blah blah blah c ; ESC v i e w - l o s s a g e RET. Це виглядає як термінальна проблема: якби комбінація клавіш досягала Emacs, c ;деталь виглядала б так C-;.


33

У програмі Shift + Up не розпізнається Emacs в терміналі, я пояснюю, як термінали переводять більшість функціональних клавіш у послідовності евакуації, оскільки інтерфейс між додатками та терміналами передає символи (а точніше байти), а не ключі. Лише кілька комбінацій модифікаторів + символів мають власний характер:

  • Ctrlплюс літера або один із @[\]^_перетворень на байти 0–31 ( контрольні символи ASCII ).
  • Часто Ctrl+ ?перетворюється на байт 127, а Ctrl+ Spaceеквівалентно Ctrl+ @(байт 0).
  • Деякі функціональні клавіші еквівалентні символам управління: Tab= Ctrl+ I, Return= Ctrl+ M, Esc= Ctrl+ [.
  • І Backspace= Ctrl+ Hабо Ctrl+ ?залежно від конфігурації. Ctrl+ ?зручніше для Emacs, оскільки Ctrl+ H- це допомога.
  • Meta+ characterнадсилається відповідно Escдо символу .

Що ж робити з іншими комбінаціями, такими як Ctrl+ ;або Ctrl+ Shift+ letter? Оскільки відповідного символу немає, термінал повинен або повторно використовувати символ, або надіслати послідовність відходу. Багато терміналів ігнорують модифікатори, коли немає відповідного символу, тому в кінцевому підсумку ви отримуєте Ctrl+ ;відправлення ;, Ctrl+ Shift+ letterеквівалент Ctrl+ letterта ін.

Постачальники терміналів тривалий час займалися простою справою. Не було стандартів для послідовностей евакуації, який самовдовжувався - постачальники терміналів не реалізують його, програми не підтримують його, користувачі цього не очікують. Деякі емулятори терміналів можуть бути налаштовані для надсилання довільних послідовностей евакуації, тому, якщо ваш, ви можете налаштувати його та оголосити послідовності виходу в Emacs (докладніше про це пізніше).

Останнім часом ситуація змінюється, оскільки було дві пропозиції щодо стандартизації послідовностей втечі. Один - лінійна клавіша LeoNerd із синтаксисом . Інша - xterm Томаса Дікі з синтаксисом . Поточні версії xterm (≥216) можна налаштувати для будь-якого синтаксису, встановивши ресурс; функцію потрібно активувати, встановивши ненульове значення.ESC [ codepoint ; modifier uESC [ 2 7 ; modifier ; codepoint ~formatOtherKeysmodifyOtherKeys

Якщо ваш термінальний емулятор не підтримує ці синтаксиси, але їх можна налаштувати, виберіть будь-який.

Оскільки Emacs 24.4, Emacs автоматично включає modifyOtherKeysфункцію, коли виявляє, що термінал має xterm версії ≥216. Виявлення Emacs послідовностей виходу для кодування ключів працює через змінну local-function-key-map. Станом на Emacs 24.4 підтримуються не всі послідовності втечі. Ви можете використовувати наступний код у своєму файлі init, щоб виконати завдання.

;; xterm with the resource ?.VT100.modifyOtherKeys: 1
;; GNU Emacs >=24.4 sets xterm in this mode and define
;; some of the escape sequences but not all of them.
(defun character-apply-modifiers (c &rest modifiers)
  "Apply modifiers to the character C.
MODIFIERS must be a list of symbols amongst (meta control shift).
Return an event vector."
  (if (memq 'control modifiers) (setq c (if (or (and (<= ?@ c) (<= c ?_))
                                                (and (<= ?a c) (<= c ?z)))
                                            (logand c ?\x1f)
                                          (logior (lsh 1 26) c))))
  (if (memq 'meta modifiers) (setq c (logior (lsh 1 27) c)))
  (if (memq 'shift modifiers) (setq c (logior (lsh 1 25) c)))
  (vector c))
(defun my-eval-after-load-xterm ()
  (when (and (boundp 'xterm-extra-capabilities) (boundp 'xterm-function-map))
    (let ((c 32))
      (while (<= c 126)
        (mapc (lambda (x)
                (define-key xterm-function-map (format (car x) c)
                  (apply 'character-apply-modifiers c (cdr x))))
              '(;; with ?.VT100.formatOtherKeys: 0
                ("\e\[27;3;%d~" meta)
                ("\e\[27;5;%d~" control)
                ("\e\[27;6;%d~" control shift)
                ("\e\[27;7;%d~" control meta)
                ("\e\[27;8;%d~" control meta shift)
                ;; with ?.VT100.formatOtherKeys: 1
                ("\e\[%d;3u" meta)
                ("\e\[%d;5u" control)
                ("\e\[%d;6u" control shift)
                ("\e\[%d;7u" control meta)
                ("\e\[%d;8u" control meta shift)))
        (setq c (1+ c))))))
(eval-after-load "xterm" '(my-eval-after-load-xterm))

Якщо TERMзмінна середовища не встановлена xtermабо такий варіант, як xterm-256color, наприклад , Emacs не активує ці послідовності. Якщо Emacs вже підтримує ваше значення TERM, ви можете додати підтримку, визначивши функцію, аналогічну вищевказаній, яка буде виконуватися після завантаження файлу Lisp, ім'я якого значенняTERM . Якщо Emacs не має такої підтримки, ви можете додати її, створивши підкаталог, який називається termдесь у вашому load-path, та створивши файл Lisp, який називається, term/$TERM.elде $TERMє значенням TERM, визначивши функцію, що називається terminal-init-$TERM.

Як я пишу, схоже, що мало емуляторів терміналів, окрім xterm, прийняли ці послідовності виходу. На OSX ви можете налаштувати iTerm2 , вибравши послідовність виходу для кожної комбінації клавіш по черзі.


2
Ваші відповіді на цю тему завжди чудові, Жиле. Цінується.
філс

Чудово !. Хоча мені досить важко знайти, як зробити urxvt надсилаючи ці послідовності. Не могли б ви мені подати руку :)
Амос

@Amos Я не використовую rxvt. Ви повинні запитати в Unix та Linux, як змусити urxvt надсилати ті самі послідовності евакуації, що й xterm, з modifyOtherKeys.
Жил "ТАК - перестань бути злим"

не працює на macOS xterm-256color. M-C-%бути визнанимESC 5
LoranceChen

@LoranceChen Це очікувана поведінка, якщо modifyOtherKeysфункція неактивна. Зауважте, що він підтримується лише в останніх останніх версіях xterm, і він активується автоматично автоматично з Emacs 24.4. Я не знаю, чи постачається OSX з останніми версіями. Якщо цього немає, і він не працює для вас, пропоную вам задати нове запитання. Згадайте версії, які ви використовуєте.
Жиль "ТАК - перестань бути злим"

2

У відповіді Жиля було зазначено: у On OSX, you can configure iTerm2 by selecting an escape sequence for each key combination, one by one. мене виникли невеликі труднощі з тим, щоб потрапити туди, тому ось детальне пояснення на випадок, якщо ви схожі на мене, розгублені.

Якщо під час запуску Emacs у терміналі (наприклад, за замовчуванням для Mac Terminal.app) C-x C-;не запускається comment-line, і вам потрібна ця функціональність, тоді ви повинні переключитися на iTerm2 (у Terminal.app немає можливості) та створити картографічне відображення у розділі Профілі ... Клавіші наступним чином:

^;     ^[[59;5u

Це досягається натисканням на +кнопку, яка відкриває невелике вікно під назвою "Комбінація клавіш"; це вікно має спочатку два поля; верхній має значення "Клацніть для встановлення", а внизу значення "Ігнорувати". Клацніть верхню кнопку та введіть C-;. Тут встановлюється комбінація клавіш, яка виконує дію та код. Клацніть нижнє поле "Дія" і знайдіть і натисніть "Надіслати послідовність втечі", яке знаходиться внизу трохи більше, ніж на половині шляху. Після натискання на нього з'явиться третє поле під назвою "Esc +". Всередині цього поля введіть:

[59;5u

59Десятковий ASCII - код коми, в і 5є кодом Ctrl. Потім натисніть "ОК", щоб закінчити. Правильна комбінація клавіш із послідовністю клавіш тепер буде включена у налаштування iTerm2. Коли ви запускаєте Emacs в iTerm, тепер у вас буде доступ до C-x C-;функціональності.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.