W Shift + Up nie jest rozpoznawany przez Emacsa w terminalu Wyjaśniam, jak terminale tłumaczą większość klawiszy funkcyjnych na sekwencje specjalne, ponieważ interfejs między aplikacjami a terminalami przesyła znaki (a raczej bajty), a nie klucze. Tylko kilka kombinacji modyfikatora + postaci ma swój własny charakter:
- Ctrlplus litera lub jeden z
@[\]^_zamienia się w bajty 0–31 (znaki sterujące ASCII ).
- Często Ctrl+ ?zamienia się w bajt 127, a Ctrl+ Spaceodpowiada Ctrl+ @(bajt 0).
- Niektóre klawisze funkcyjne są równoważne ze znakami kontrolnymi: Tab= Ctrl+ I, Return= Ctrl+ M, Esc= Ctrl+ [.
- I Backspace= Ctrl+ Hlub Ctrl+ w ?zależności od konfiguracji. Ctrl+ ?jest wygodniejszy dla Emacsa, ponieważ Ctrl+ Hto pomoc.
- Meta+ characterjest wysyłany zgodnie z Escnastępującym po nim znakiem .
A co z innymi kombinacjami, takimi jak Ctrl+ ;lub Ctrl+ Shift+ letter? Ponieważ nie ma odpowiedniego znaku, terminal musi albo ponownie użyć znaku, albo wysłać sekwencję zmiany znaczenia. Wiele terminali ignoruje modyfikatory, gdy nie ma odpowiedniego znaku, więc kończy się na Ctrl+ ;wysyłaniu ;, Ctrl+ Shift+ letterrównoważnym Ctrl+ letteritp.
Dostawcy terminali przez długi czas robili tę prostą rzecz. Nie było standardu dla sekwencji ucieczki, który byłby samonapędzający się - dostawcy terminali go nie implementują, aplikacje nie obsługują go, użytkownicy tego nie oczekują. Niektóre emulatory terminali można skonfigurować tak, aby wysyłały dowolne sekwencje specjalne, więc jeśli możesz, możesz je skonfigurować i zadeklarować sekwencje specjalne Emacsowi (więcej na ten temat później).
Ostatnio sytuacja się zmienia, ponieważ pojawiły się dwie propozycje standaryzacji sekwencji ucieczki. Jednym z nich jest libtermkey LeoNerda ze składnią . Kolejnym jest xterm Thomasa Dickeya ze składnią . Obecne wersje xterm (≥216) można skonfigurować dla dowolnej składni przez ustawienie zasobu; funkcja musi zostać aktywowana poprzez ustawienie wartości niezerowej.ESC [ codepoint ; modifier uESC [ 2 7 ; modifier ; codepoint ~formatOtherKeysmodifyOtherKeys
Jeśli emulator terminala nie obsługuje tych składni, ale można go skonfigurować, wybierz jedno z nich.
Od Emacsa 24.4 Emacs automatycznie włącza tę modifyOtherKeysfunkcję, gdy wykryje, że terminal jest w wersji xterm ≥216. Wykrywanie przez Emacsa sekwencji ucieczki do kodowania kluczy działa poprzez zmienną local-function-key-map. Począwszy od Emacsa 24.4, nie wszystkie sekwencje specjalne są obsługiwane. Możesz użyć następującego kodu w pliku init, aby ukończyć zadanie.
;; 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))
Jeśli TERMzmienna środowiskowa nie jest ustawiona na xtermlub wariant taki jak xterm-256color, Emacs nie aktywuje tych sekwencji. Jeśli Emacs ma już wsparcie dla twojej wartości TERM, możesz dodać wsparcie definiując funkcję podobną do powyższej, która ma być wykonywana po załadowaniu pliku Lisp, którego nazwa jest wartościąTERM . Jeśli Emacs nie ma takiego wsparcia, możesz go dodać, tworząc podkatalog wywoływany termgdzieś w twoim load-path, i tworząc plik Lisp o nazwie term/$TERM.elgdzie $TERMjest wartość TERM, definiując wywoływaną funkcję terminal-init-$TERM.
Jak piszę, wydaje się, że niewiele emulatorów terminali innych niż xterm przyjęło te sekwencje specjalne. W OSX można skonfigurować iTerm2 , wybierając sekwencję zmiany znaczenia dla każdej kombinacji klawiszy, jeden po drugim.
C-;kombinacji, a następnie użyj,M-x view-lossageaby sprawdzić, czy w ogóle dociera do Emacsa.