Übersetzen von Zeichenfolgen in Tastendrücke

8

Bei einer Zeichenfolge in elisp möchte ich Emacs simulieren, die alle Tastendrücke erhalten, die zum erneuten Erstellen dieser Zeichenfolge erforderlich sind. Angesichts der Zeichenfolge "Hallo" würden sich Emacs genauso verhalten, als hätte ich Umschalt + H, e, l, l, o gedrückt. Beachten Sie, dass dies nicht immer mit dem Einfügen von Text in den Puffer identisch ist. Einige Modi wie der Suchmodus hören Tastendruckereignisse direkt ab.

Der Grund, warum dies notwendig ist, liegt darin, dass es viele Modi und Erweiterungen gibt, die davon ausgehen, dass alle Eingaben von der Tastatur stammen, oder davon ausgehen, dass jede Änderung von Puffer / Fenster / Rahmen mit dem Tastatureingabeereignis verbunden ist, und viele die Zeit, zu der sie die mit diesem Ereignis verbundenen Daten überprüfen. Für den Spracherkennungsmodus, an dem ich arbeite, um nahtlos mit dem vorhandenen Code zu arbeiten, kann er nicht einfach direkt in elisp aufrufen, um Aktionen auszuführen, sondern muss elisp anweisen, die Tasten zu drücken, damit diese Aktionen ausgeführt werden.

Ich habe ungelesene Befehlsereignisse gefunden, kenne jedoch keinen vorhandenen Code, der Zeichenfolgen in die erforderlichen Schlüsselsequenzen übersetzt. Gibt es so etwas schon?

Joseph Garvin
quelle

Antworten:

5

Tut

(execute-kbd-macro (kbd "Hello"))

zufällig arbeiten?

PythonNut
quelle
2
In diesem Fall funktioniert es, aber nicht mit der Zeichenfolge "C-Beams". Eine Möglichkeit, dies zu vermeiden, besteht darin, zwischen den einzelnen Zeichen Leerzeichen einzufügen. (let ((string "C-Beams")) (execute-kbd-macro (kbd (mapconcat #'char-to-string string " "))))wird funktionieren. Wahrscheinlich gibt es einen besseren Weg ...
YoungFrog
Hmm, der Mapconcat-Trick funktioniert nicht, wenn die Zeichenfolge tatsächlich Leerzeichen enthält, z. B. wird aus "C-Strahlen" "C-Strahlen". (execute-kbd-macro (kbd "SPC"))funktioniert jedoch, so dass Sie etwas aufwändigeres als mapconcat schreiben könnten, um diese Ersetzung durchzuführen ... dies macht mir Sorgen, obwohl es möglicherweise andere relevante Schlüssel gibt, die diese spezielle Behandlung erfordern.
Joseph Garvin
Anscheinend haben auch Zeilenumbrüche und Registerkarten dieses Problem. Ich kann mich mit dem Ersetzen von SPC / RET / TAB befassen, obwohl ich mich frage, ob dieser gesamte Ansatz Probleme mit internationalen Tastaturen haben wird.
Joseph Garvin
(mapc (lambda (char) (execute-kbd-macro (char-to-string char))) string)scheint in Ordnung zu funktionieren. Aber (natürlich?) Wenn es ein Tabulatorzeichen gibt, wird es so tun, als würde es TAB treffen, was möglicherweise nicht an einen Befehl gebunden ist, der einen tatsächlichen Tabulator einfügt ...
YoungFrog
@ YoungFrog: das scheint immer noch gebrochen zu sein von \ n
Joseph Garvin
4

Okay, meine erste Antwort weist eine Reihe von Mängeln auf, die in den Kommentaren aufgeführt sind.

execute-kbd-macro ist eine integrierte Funktion in C source code.

(execute-kbd-macro MACRO &optional COUNT LOOPFUNC)

Führen Sie MACRO als Zeichenfolge von Editorbefehlszeichen aus. MACRO kann auch ein Vektor von Tastaturereignissen sein . Wenn MACRO ein Symbol ist, wird seine Funktionsdefinition verwendet. COUNT ist eine Wiederholungszählung oder einmal Null oder 0 für Endlosschleife.

Optionales drittes Argument LOOPFUNC kann eine Funktion sein, die vor jeder Iteration des Makros aufgerufen wird. Die Iteration stoppt, wenn LOOPFUNC null zurückgibt.

(Hervorhebung von mir)

Eine Lösung, um eine Zeichenfolge als einzelne Tastendrücke direkt an Emacs weiterzuleiten, lautet:

(defun insert-via-kbd (str)
  (execute-kbd-macro (vconcat str)))

Dies scheint ziemlich gut zu funktionieren (es handhabt sogar Japanisch!), Aber es gibt immer noch einige Kuriositäten:

  • \nauslösen C-j(nicht C-m, REToder <return>)
  • \twird auslösen TAB(nicht <tab>)
PythonNut
quelle