Problemi con le combinazioni di tasti quando si utilizza il terminale


30

Ho la seguente riga in init.el:

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

Funziona molto bene nella finestra della GUI, ma se emacsviene invocato con l' -nwopzione C-;non commenta la regione, inserisce solo il ;carattere. M-x comment-region RETfunziona bene comunque.

Ho provato a seguire questa risposta su un problema simile, ma C-q C-;ritorna giusto ;e ovviamente non voglio legare nuda ;.

Come ottenere l'effetto desiderato?


4
È possibile che il tuo terminale (che cosa stai usando, a proposito?) Non riconosce quella sequenza di comandi. Prova a usare la C-;combo e poi usa M-x view-lossageper vedere se arriva anche a Emacs.
Dan

Sto usando gnome-terminale M-x view-lossagerestituisce:ESC [ > 1 ; 2 8 0 2 ; 0 c ; ESC x v i e w - l o s s a g e RET
WeSenseASoulInSearchOfAnswers

3
Sembra un problema terminale: se quella combinazione di tasti dovesse raggiungere Emacs, sembrerebbe C-;piuttosto che c ;(o, almeno, capisco C-;).
Dan

@Dan: Potresti metterlo come risposta? Ciò contrassegnerebbe la domanda come risposta e renderebbe più facile vedere la soluzione, il che è positivo per le altre persone che hanno lo stesso problema. Grazie!
Tikhon Jelvis,

Riassunto e pubblicato con un link aggiuntivo per ulteriori letture. Modifica anche il titolo della domanda per renderlo un po 'più generale.
Dan

Risposte:


17

In primo luogo, il problema più generale: gli emulatori di terminali sono spesso limitati nelle sequenze di controllo e di escape che possono inviare. Quindi: può succedere che il terminale ingoia i tuoi personaggi speciali prima che raggiungano Emacs. Come diagnostica generale, puoi premere C-h l(o M-x view-lossage) per vedere se le tue combinazioni di tasti diventano Emacs.

Per ulteriori discussioni su questo problema, dai un'occhiata a questo thread Stack Overflow e ai relativi collegamenti.

Per riassumere il avanti e indietro nei commenti, il tuo problema specifico suggerisce che è il terminale piuttosto che Emacs il problema. Quando hai provato C-;e poi M-x view-lossage, hai ottenuto blah blah blah c ; ESC v i e w - l o s s a g e RET. Sembra un problema terminale: se la combinazione di tasti raggiungesse Emacs, la c ;parte sembrerebbe C-;.


33

In Shift + Up non è riconosciuto da Emacs in un terminale spiego come i terminali traducono la maggior parte dei tasti funzione in sequenze di escape, perché l'interfaccia tra applicazioni e terminali trasmette caratteri (o piuttosto byte), non chiavi. Solo alcune combinazioni di modificatori + caratteri hanno il loro carattere:

  • Ctrlpiù una lettera o una delle @[\]^_trasformazioni in byte 0–31 (caratteri di controllo ASCII ).
  • Spesso Ctrl+ ?si trasforma in byte 127 e Ctrl+ Spaceequivale a Ctrl+ @(byte 0).
  • Alcuni tasti funzione equivalgono ai caratteri di controllo: Tab= Ctrl+ I, Return= Ctrl+ M, Esc= Ctrl+ [.
  • E Backspace= Ctrl+ Ho Ctrl+ a ?seconda della configurazione. Ctrl+ ?è più conveniente per Emacs, poiché Ctrl+ Hè di aiuto.
  • Meta+ characterviene inviato come Escseguito dal carattere .

E che dire di altre combinazioni come Ctrl+ ;o Ctrl+ Shift+ letter? Poiché non esiste un carattere corrispondente, il terminale deve riutilizzare un personaggio o inviare una sequenza di escape. Molti terminali ignorano i modificatori quando non c'è un carattere corrispondente, quindi finisci con Ctrl+ ;invio ;, Ctrl+ Shift+ letterequivalente a Ctrl+ letter, ecc.

I venditori di terminali hanno continuato a fare la cosa semplice per molto tempo. Non esistevano standard per le sequenze di escape, che si autoalimentavano: i fornitori di terminali non lo implementano, le applicazioni non lo supportano, gli utenti non se lo aspettano. Alcuni emulatori di terminale possono essere configurati per inviare sequenze di escape arbitrarie, quindi se è possibile, è possibile configurarlo e dichiarare le sequenze di escape su Emacs (ne parleremo più avanti).

Ultimamente, la situazione sta cambiando, perché ci sono state due proposte per standardizzare le sequenze di escape. Uno è il libtermkey di LeoNerd con la sintassi . Un altro è il xterm di Thomas Dickey con la sintassi . Le versioni correnti di xterm (≥216) possono essere configurate per entrambe le sintassi impostando la risorsa; la funzione deve essere attivata impostando un valore diverso da zero.ESC [ codepoint ; modifier uESC [ 2 7 ; modifier ; codepoint ~formatOtherKeysmodifyOtherKeys

Se il tuo emulatore di terminale non supporta queste sintassi ma può essere configurato, scegli uno dei due.

Da Emacs 24.4, Emacs attiva automaticamente la modifyOtherKeysfunzione quando rileva che il terminale è versione xterm ≥216. Il rilevamento da parte di Emacs delle sequenze di escape per codificare le chiavi funziona attraverso la variabile local-function-key-map. A partire da Emacs 24.4, non tutte le sequenze di escape sono supportate. È possibile utilizzare il seguente codice nel file init per completare il lavoro.

;; 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))

Se la TERMvariabile di ambiente non è impostata su xtermo una variante come xterm-256color, Emacs non attiverà tali sequenze. Se Emacs ha già il supporto per il tuo valore di TERM, puoi aggiungere supporto definendo una funzione simile a quella sopra, da eseguire dopo aver caricato il file Lisp il cui nome è il valore diTERM . Se Emacs non ha tale supporto, puoi aggiungerlo creando una sottodirectory chiamata termda qualche parte nel tuo load-path, e creando un file Lisp chiamato term/$TERM.eldove $TERMè il valore di TERM, definendo una funzione chiamata terminal-init-$TERM.

Mentre scrivo, sembra che pochi emulatori terminali diversi da xterm abbiano adottato queste sequenze di escape. Su OSX, puoi configurare iTerm2 selezionando una sequenza di escape per ogni combinazione di tasti, uno per uno.


2
Le tue risposte su questo argomento sono sempre eccezionali, Gilles. Molto apprezzato.
phils,

Grande!. Anche se faccio fatica a trovare come inviare urxvt inviando quelle sequenze. Potresti darmi una mano :)
Amos,

@Amos Non uso rxvt. Su Unix e Linux dovresti chiedere a urxvt come inviare le stesse sequenze di escape di xterm con editOtherKeys.
Gilles 'SO- smetti di essere malvagio' il

non funziona su macOS xterm-256color. M-C-%essere riconosciuto aESC 5
LoranceChen il

@LoranceChen Questo è il comportamento previsto se la modifyOtherKeysfunzione non è attiva. Si noti che è supportato solo nelle versioni abbastanza recenti di xterm e viene attivato automaticamente solo da Emacs 24.4. Non so se OSX viene fornito con versioni recenti. In caso contrario, e non funziona per te, ti suggerisco di porre una nuova domanda. Menziona le versioni che stai utilizzando.
Gilles 'SO- smetti di essere malvagio' il

2

La risposta di Gilles affermava: On OSX, you can configure iTerm2 by selecting an escape sequence for each key combination, one by one. ho avuto qualche problema ad arrivarci, quindi ecco una spiegazione dettagliata nel caso in cui tu sia come me, confuso.

Se, quando si esegue Emacs in un terminale (ad es. Terminal.app predefinito di Mac), C-x C-;non viene eseguito comment-linee si desidera tale funzionalità, è necessario passare a iTerm2 (Terminal.app non ha la capacità) e creare un Key Mapping in Profili ... Tasti come segue:

^;     ^[[59;5u

Questo si ottiene facendo clic sul +pulsante, che fa apparire una piccola finestra chiamata "Scorciatoia da tastiera"; questa finestra ha inizialmente due campi; la parte superiore ha un valore di "Fai clic per impostare" e la parte inferiore ha un valore di "Ignora". Fai clic sul pulsante in alto e digita C-;. Questo imposta la combinazione di tasti che eseguirà l'azione e il codice. Fai clic sul campo inferiore, "Azione", e trova e fai clic su "Invia sequenza di escape", che è leggermente più in basso di metà. Dopo aver fatto clic su quello, apparirà un terzo campo, chiamato "Esc +". All'interno di questo campo, digitare:

[59;5u

È 59il codice ASCII decimale della virgola e 5è il codice per Ctrl. Quindi premere "OK" per terminare. La combinazione di tasti corretta per sequenza di tasti verrà ora inclusa nelle preferenze di iTerm2. Quando avvii Emacs in iTerm, ora avrai accesso alla C-x C-;funzionalità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.