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 u
ESC [ 2 7 ; modifier ; codepoint ~
formatOtherKeys
modifyOtherKeys
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ę modifyOtherKeys
funkcję, 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 TERM
zmienna środowiskowa nie jest ustawiona na xterm
lub 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 term
gdzieś w twoim load-path
, i tworząc plik Lisp o nazwie term/$TERM.el
gdzie $TERM
jest 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-lossage
aby sprawdzić, czy w ogóle dociera do Emacsa.