Probleme mit Tastenkombinationen bei Verwendung des Terminals

30

Ich habe die folgende Zeile in init.el:

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

Es funktioniert sehr gut in GUI-Fenstern, aber wenn emacses mit der -nwOption aufgerufen C-;wird, kommentiert es keinen Bereich, sondern fügt nur ;Zeichen ein. M-x comment-region RETfunktioniert jedoch gut.

Ich habe versucht, dieser Antwort auf ein ähnliches Problem zu folgen , C-q C-;kehre aber gerade zurück ;und möchte offensichtlich nicht nackt binden ;.

Wie erreicht man den gewünschten Effekt?

WeSenseASoulInSearchOfAnswers
quelle
4
Es ist möglich, dass Ihr Terminal (was verwenden Sie übrigens?) Diese Befehlssequenz nicht erkennt. Versuchen Sie es mit der C-;Combo und verwenden Sie dann, um M-x view-lossagezu sehen, ob es überhaupt zu Emacs kommt.
Dan
Ich benutze gnome-terminalund M-x view-lossagekehre zurück:ESC [ > 1 ; 2 8 0 2 ; 0 c ; ESC x v i e w - l o s s a g e RET
WeSenseASoulInSearchOfAnswers
3
Sieht nach einem Terminalproblem aus: Wenn diese Tastenkombination Emacs erreichen würde, würde sie C-;eher so aussehen als c ;(oder zumindest so C-;).
Dan
@Dan: Könntest du das als Antwort geben? Das würde die Frage als beantwortet markieren und es einfacher machen, die Lösung zu sehen, was für andere Menschen mit dem gleichen Problem gut ist. Vielen Dank!
Tikhon Jelvis
Zusammengefasst und gepostet mit einem zusätzlichen Link zum Lesen. Bearbeiten Sie auch den Fragentitel, um ihn etwas allgemeiner zu gestalten.
Dan

Antworten:

17

Erstens das allgemeinere Problem: Terminalemulatoren sind häufig in den Steuerungs- und Escape-Sequenzen beschränkt, die sie senden können. Also: Es kann vorkommen, dass das Terminal Ihre Sonderzeichen verschluckt, bevor sie Emacs erreichen. Als allgemeine Diagnose können Sie mit C-h l(oder M-x view-lossage) feststellen , ob Ihre Tastenkombinationen es in Emacs schaffen.

Weitere Informationen zu diesem Problem finden Sie in diesem Stapelüberlauf-Thread und den darin enthaltenen Links.

Um das Hin und Her in den Kommentaren zusammenzufassen, deutet Ihr spezifisches Problem darauf hin, dass das Terminal und nicht Emacs das Problem ist. Als du es versucht hast C-;und dann M-x view-lossagehast du blah blah blah c ; ESC v i e w - l o s s a g e RET. Das sieht nach einem Terminalproblem aus: Wenn die Tastenkombination Emacs erreichen würde, würde das c ;Teil so aussehen C-;.

Dan
quelle
33

In Shift + Up wird von Emacs in einem Terminal nicht erkannt. Ich erkläre, wie Terminals die meisten Funktionstasten in Escape-Sequenzen übersetzen, da die Schnittstelle zwischen Anwendungen und Terminals Zeichen (oder vielmehr Bytes) und keine Tasten überträgt. Nur wenige Kombinationen aus Modifikator und Zeichen haben einen eigenen Charakter:

  • CtrlPlus ein Buchstabe oder einer von @[\]^_verwandelt sich in Bytes 0–31 (ASCII- Steuerzeichen ).
  • Oft wird Ctrl+ ?zu Byte 127 und Ctrl+ Spaceentspricht Ctrl+ @(Byte 0).
  • Einige Funktionstasten entsprechen Steuerzeichen: Tab= Ctrl+ I, Return= Ctrl+ M, Esc= Ctrl+ [.
  • Und Backspace= Ctrl+ Hoder Ctrl+ ?je nach Konfiguration. Ctrl+ ?ist für Emacs praktischer, da Ctrl+ HHilfe ist.
  • Meta+ characterwird gesendet, Escgefolgt von einem Zeichen .

Was ist also mit anderen Kombinationen wie Ctrl+ ;oder Ctrl+ Shift+ letter? Da es kein entsprechendes Zeichen gibt, muss das Terminal entweder ein Zeichen wiederverwenden oder eine Escape-Sequenz senden. Viele Terminals ignorieren Modifikatoren, wenn kein entsprechendes Zeichen vorhanden ist. Daher erhalten Sie Ctrl+ ;Senden ;, Ctrl+ Shift+ letterEntsprechung zu Ctrl+ letterusw.

Terminalanbieter machten das lange Zeit so einfach. Es gab keinen Standard für Escape-Sequenzen, der sich selbst aufrechterhielt - Terminalanbieter implementieren ihn nicht, Anwendungen unterstützen ihn nicht, Benutzer erwarten ihn nicht. Einige Terminal-Emulatoren können so konfiguriert werden, dass sie beliebige Escape-Sequenzen senden. Wenn dies möglich ist, können Sie sie konfigurieren und die Escape-Sequenzen an Emacs deklarieren (dazu später mehr).

In letzter Zeit ändert sich die Situation, da es zwei Vorschläge zur Standardisierung von Fluchtsequenzen gab. Eines ist LeoNerds libtermkey mit der Syntax . Ein weiteres Beispiel ist Thomas Dickeys xterm mit der Syntax . Aktuelle Versionen von xterm (≥216) können für beide Syntaxarten durch Festlegen der Ressource konfiguriert werden . Die Funktion muss durch Setzen des Werts ungleich Null aktiviert werden .ESC [ codepoint ; modifier uESC [ 2 7 ; modifier ; codepoint ~formatOtherKeysmodifyOtherKeys

Wenn Ihr Terminal-Emulator diese Syntax nicht unterstützt, aber konfiguriert werden kann, wählen Sie eine der beiden Optionen aus.

Seit Emacs 24.4 schaltet Emacs die Funktion automatisch ein, modifyOtherKeyswenn festgestellt wird, dass das Terminal eine xterm-Version ≥216 hat. Die Erkennung von Escape-Sequenzen zum Codieren von Schlüsseln durch Emacs funktioniert über die Variable local-function-key-map. Ab Emacs 24.4 werden nicht alle Escape-Sequenzen unterstützt. Sie können den folgenden Code in Ihrer Init-Datei verwenden, um den Auftrag abzuschließen.

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

Wenn die TERMUmgebungsvariable nicht auf xtermoder eine Variante wie festgelegt ist xterm-256color, aktiviert Emacs diese Sequenzen nicht. Wenn Emacs bereits Unterstützung für Ihren Wert von hat TERM, können Sie Unterstützung hinzufügen, indem Sie eine Funktion ähnlich der oben genannten definieren, die nach dem Laden der Lisp-Datei ausgeführt wird, deren Name den Wert von hatTERM . Wenn Emacs keine solche Unterstützung hat, können Sie es hinzufügen, indem Sie ein Unterverzeichnis erstellen, das an einer beliebigen Stelle termin Ihrem Verzeichnis aufgerufen wird load-path, und eine Lisp-Datei mit dem Namen term/$TERM.elwhere $TERMis the value of erstellen und eine aufgerufene TERMFunktion definieren terminal-init-$TERM.

Während ich schreibe, scheinen nur wenige Terminalemulatoren außer xterm diese Escape-Sequenzen übernommen zu haben. Unter OSX können Sie iTerm2 konfigurieren, indem Sie eine Escape-Sequenz für jede Tastenkombination einzeln auswählen.

Gilles 'SO - hör auf böse zu sein'
quelle
2
Ihre Antworten zu diesem Thema sind immer hervorragend, Gilles. Sehr geschätzt.
Phils
Groß!. Obwohl es mir ziemlich schwer fällt herauszufinden, wie ich diese Sequenzen urxvt senden kann. Könnten Sie mir helfen :)
Amos
@Amos Ich benutze kein rxvt. Sie sollten unter Unix und Linux fragen, wie Sie mit modifyOtherKeys die gleichen Escape-Sequenzen wie mit xterm senden können.
Gilles 'SO - hör auf böse zu sein'
funktioniert nicht unter macOS xterm-256color. M-C-%erkannt werdenESC 5
LoranceChen
@LoranceChen Das ist das erwartete Verhalten, wenn die modifyOtherKeysFunktion nicht aktiv ist. Beachten Sie, dass es nur in ausreichend aktuellen Versionen von xterm unterstützt wird und erst seit Emacs 24.4 automatisch aktiviert wird. Ich weiß nicht, ob OSX mit den neuesten Versionen ausgeliefert wird. Wenn dies nicht der Fall ist und es bei Ihnen nicht funktioniert, empfehle ich Ihnen, eine neue Frage zu stellen. Erwähnen Sie die Versionen, die Sie verwenden.
Gilles 'SO - hör auf böse zu sein'
2

Gilles 'Antwort lautete: On OSX, you can configure iTerm2 by selecting an escape sequence for each key combination, one by one. Ich hatte ein kleines Problem, also hier eine ausführliche Erklärung, falls Sie wie ich sind, verwirrt.

Wenn Emacs in einem Terminal (z. B. Macs Standard-Terminal.app) C-x C-;nicht ausgeführt comment-linewird und Sie diese Funktionalität wünschen, müssen Sie zu iTerm2 wechseln (Terminal.app verfügt nicht über die Fähigkeit) und eine Tastenzuordnung erstellen unter Profile ... Tasten wie folgt:

^;     ^[[59;5u

Klicken Sie dazu auf die +Schaltfläche. Daraufhin wird ein kleines Fenster mit dem Namen "Tastaturkürzel" angezeigt. Dieses Fenster hat anfangs zwei Felder. Das obere Feld hat den Wert "Zum Festlegen klicken" und das untere Feld den Wert "Ignorieren". Klicken Sie auf die obere Schaltfläche und geben Sie ein C-;. Hiermit wird die Tastenkombination festgelegt, mit der die Aktion und der Code ausgeführt werden. Klicken Sie auf das untere Feld "Aktion" und suchen Sie "Escape-Sequenz senden", das sich etwas mehr als auf halber Strecke befindet. Nachdem Sie darauf geklickt haben, wird ein drittes Feld mit dem Namen "Esc +" angezeigt. Geben Sie in dieses Feld Folgendes ein:

[59;5u

Der 59dezimale ASCII-Code des Kommas und 5der Code für Ctrl. Drücken Sie dann "OK", um den Vorgang abzuschließen. Die richtige Tastenkombination für die Tastenfolge ist jetzt in den Einstellungen von iTerm2 enthalten. Wenn Sie Emacs in iTerm starten, haben Sie jetzt Zugriff auf C-x C-;Funktionen.

Tannenzapfen
quelle