Traduction de chaînes en touches


8

Étant donné une chaîne dans elisp, je voudrais simuler emacs recevant toutes les touches nécessaires pour recréer cette chaîne. Donc, étant donné la chaîne "Hello", emacs agirait exactement de la même manière que si j'avais appuyé sur Maj + H, e, l, l, o. Notez que ce n'est pas toujours la même chose que d'insérer du texte dans le tampon - certains modes comme le mode isearch écoutent directement les événements de pression de touche.

La raison pour laquelle cela est nécessaire est qu'il existe de nombreux modes et extensions qui supposent que toutes les entrées proviennent du clavier ou supposent que tout changement de tampon / fenêtre / cadre sera associé à l'événement d'entrée de clavier, et beaucoup de le moment où ils inspectent les données associées à cet événement. Pour que le mode de reconnaissance vocale sur lequel je travaille fonctionne de manière transparente avec le corps de code existant, il ne peut pas simplement appeler directement elisp pour effectuer des actions, il doit plutôt dire à elisp d'appuyer sur les touches pour que ces actions se produisent.

J'ai trouvé des événements de commande non lus, mais je ne connais aucun code existant qui traduira les chaînes en séquences de touches nécessaires. Est-ce que quelque chose comme ça existe déjà?

Réponses:


5

Est-ce que

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

travailler par hasard?


2
Cela fonctionnera dans ce cas, mais pas avec la chaîne "C-Beams" par exemple. Une façon de l'éviter est d'ajouter des espaces entre chaque personnage. (let ((string "C-Beams")) (execute-kbd-macro (kbd (mapconcat #'char-to-string string " "))))marchera. Il y a probablement une meilleure façon ...
YoungFrog

Hmm, l'astuce mapconcat ne fonctionne pas si la chaîne contient réellement des espaces, par exemple "C beams" devient "Cbeams". (execute-kbd-macro (kbd "SPC"))fonctionne cependant, vous pouvez donc écrire quelque chose d'un peu plus élaboré que mapconcat pour effectuer cette substitution ... cela me fait peur, bien qu'il puisse y avoir d'autres clés pertinentes qui nécessitent ce traitement spécial.
Joseph Garvin

Il semble que les sauts de ligne et les onglets aient également ce problème. Je peux gérer le remplacement de SPC / RET / TAB, bien que je me demande si toute cette approche va avoir des problèmes avec les claviers internationaux.
Joseph Garvin

(mapc (lambda (char) (execute-kbd-macro (char-to-string char))) string)semble fonctionner correctement. Mais (bien sûr?) S'il y a un caractère de tabulation, il fera semblant qu'il frappe TAB, qui pourrait ne pas être lié à une commande insérant une tabulation réelle ...
YoungFrog

@YoungFrog: qui semble encore être cassé par \ n
Joseph Garvin

4

D'accord, donc ma première réponse comporte un certain nombre de lacunes, comme détaillé dans ses commentaires.

execute-kbd-macro est une fonction intégrée à C source code.

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

Exécutez MACRO en tant que chaîne de caractères de commande d'éditeur. MACRO peut également être un vecteur d'événements clavier . Si MACRO est un symbole, sa définition de fonction est utilisée. COUNT est un nombre de répétitions, ou nul pour une fois, ou 0 pour une boucle infinie.

Le troisième argument optionnel LOOPFUNC peut être une fonction qui est appelée avant chaque itération de la macro. L'itération s'arrête si LOOPFUNC renvoie zéro.

(c'est moi qui souligne)

Ainsi, une solution pour passer une chaîne directement à Emacs en tant que touches individuelles est:

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

Cela semble fonctionner assez bien (il gère même le japonais!), Mais il y a encore des bizarreries:

  • \ndéclenchera C-j(non C-m, RETou <return>)
  • \tdéclenchera TAB(pas <tab>)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.