Traducción de cadenas a pulsaciones de teclas

8

Dada una cadena en elisp, me gustaría simular que emacs reciba las pulsaciones de teclas necesarias para volver a crear esa cadena. Entonces, dada la cadena "Hola", emacs actuaría exactamente igual que si hubiera presionado Shift + H, e, l, l, o. Tenga en cuenta que esto no siempre es lo mismo que insertar texto en el búfer; algunos modos, como el modo isearch, escuchan los eventos de pulsación de teclas directamente.

La razón por la que esto es necesario es porque hay muchos modos y extensiones que suponen que todas las entradas provienen del teclado o suponen que cualquier cambio de búfer / ventana / marco estará asociado con el evento de entrada del teclado, y muchos el momento en que inspeccionan los datos asociados con ese evento. Para el modo de reconocimiento de voz en el que trabajo para funcionar sin problemas con el cuerpo de código existente, no puede llamar directamente a elisp para realizar acciones, sino que debe decirle a elisp que presione las teclas para que esas acciones sucedan.

He encontrado eventos de comandos no leídos, pero no conozco ningún código existente que traduzca las cadenas a las secuencias de teclas necesarias. ¿Ya existe algo así?

Joseph Garvin
fuente

Respuestas:

5

Hace

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

trabajar por casualidad?

PythonNut
fuente
2
Funcionará en este caso, pero no con la cadena "C-Beams", por ejemplo. Una forma de evitarlo es agregar espacios entre cada personaje. (let ((string "C-Beams")) (execute-kbd-macro (kbd (mapconcat #'char-to-string string " "))))trabajará. Probablemente hay una mejor manera ...
YoungFrog
Hmm, el truco de mapconcat no funciona si la cadena realmente contiene espacios, por ejemplo, "vigas C" se convierten en "vigas C". (execute-kbd-macro (kbd "SPC"))funciona, así que podrías escribir algo un poco más elaborado que mapconcat para hacer esa sustitución ... esto me preocupa, aunque puede haber otras claves relevantes que necesitan este tratamiento especial.
Joseph Garvin
Parece que las nuevas líneas y pestañas también tienen este problema. Puedo tratar de sustituir SPC / RET / TAB, aunque me pregunto si todo este enfoque tendrá problemas con los teclados internacionales.
Joseph Garvin
(mapc (lambda (char) (execute-kbd-macro (char-to-string char))) string)Parece funcionar bien. Pero (? Por supuesto) si hay un carácter de tabulación, que va a fingir que está golpeando TAB, que puede no estar atado a un comando de inserción de una ficha real ...
YoungFrog
@YoungFrog: eso parece estar aún roto por \ n
Joseph Garvin
4

Bien, mi primera respuesta tiene una serie de deficiencias como se detalla en sus comentarios.

execute-kbd-macro es una función incorporada en C source code.

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

Ejecute MACRO como cadena de caracteres de comando del editor. MACRO también puede ser un vector de eventos de teclado . Si MACRO es un símbolo, se utiliza su definición de función. COUNT es un recuento repetido, o nulo por una vez, o 0 para bucle infinito.

El tercer argumento opcional LOOPFUNC puede ser una función que se llama antes de cada iteración de la macro. La iteración se detiene si LOOPFUNC devuelve nulo.

(énfasis mío)

Entonces, una solución para pasar una cadena directamente a Emacs como teclas individuales es:

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

Esto parece funcionar bastante bien (¡incluso maneja japonés!), Pero todavía hay algunas rarezas:

  • \nactivará C-j(no C-m, RETo <return>)
  • \tactivará TAB(no <tab>)
PythonNut
fuente