Traduzindo seqüências de caracteres para pressionamentos de tecla

8

Dada uma string no elisp, eu gostaria de simular o emacs recebendo as teclas necessárias para recriar essa string. Portanto, considerando a string "Hello", o emacs agiria exatamente da mesma forma como se eu tivesse pressionado Shift + H, e, l, l, o. Observe que isso nem sempre é o mesmo que inserir texto no buffer - alguns modos como o modo isearch escutam diretamente os eventos de pressionamento de tecla.

O motivo disso é necessário, porque existem muitos modos e extensões que pressupõem que todas as entradas são provenientes do teclado ou que qualquer alteração no buffer / janela / quadro será associada ao evento de entrada do teclado, e muitos o horário em que eles inspecionam os dados associados a esse evento. Para o modo de reconhecimento de fala no qual trabalho para trabalhar perfeitamente com o corpo de código existente, ele não pode simplesmente chamar diretamente o elisp para executar ações; em vez disso, ele precisa dizer ao elisp para pressionar as teclas para que essas ações aconteçam.

Encontrei eventos de comando não lidos, mas não conheço nenhum código existente que traduza seqüências de caracteres para as seqüências de teclas necessárias. Algo assim já existe?

Joseph Garvin
fonte

Respostas:

5

Faz

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

trabalhar por acaso?

PythonNut
fonte
2
Funcionará neste caso, mas não com a sequência "C-Beams", por exemplo. Uma maneira de evitá-lo é adicionar espaços entre cada caractere. (let ((string "C-Beams")) (execute-kbd-macro (kbd (mapconcat #'char-to-string string " "))))vai funcionar. Provavelmente há uma maneira melhor ...
YoungFrog
Hmm, o truque mapconcat não funciona se a string realmente contém espaços, por exemplo, "C Beams" se torna "Cbeams". (execute-kbd-macro (kbd "SPC"))funciona, portanto, você pode escrever algo um pouco mais elaborado do que o mapconcat para fazer essa substituição ... isso me preocupa, embora possa haver outras chaves relevantes que precisam desse tratamento especial.
Joseph Garvin
Parece que novas linhas e guias também têm esse problema. Posso lidar com a substituição do SPC / RET / TAB, embora eu me pergunte se toda essa abordagem terá problemas com os teclados internacionais.
Joseph Garvin
(mapc (lambda (char) (execute-kbd-macro (char-to-string char))) string)parece funcionar ok. Mas (? É claro) se há um caractere de tabulação, ele vai fingir que está batendo TAB, o que não pode ser ligado a um comando inserir um separador real ...
YoungFrog
@YoungFrog: que parece ainda estar quebrado por \ n
Joseph Garvin
4

Ok, então minha primeira resposta tem várias deficiências, conforme detalhado em seus comentários.

execute-kbd-macro é uma função interna do C source code.

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

Execute o MACRO como uma sequência de caracteres de comando do editor. MACRO também pode ser um vetor de eventos do teclado . Se MACRO é um símbolo, sua definição de função é usada. COUNT é uma contagem de repetição, ou nulo por uma vez ou 0 para loop infinito.

O terceiro argumento opcional LOOPFUNC pode ser uma função chamada antes de cada iteração da macro. A iteração para se LOOPFUNC retornar nulo.

(ênfase minha)

Portanto, uma solução para passar uma string diretamente para o Emacs como pressionamentos de teclas individuais é:

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

Isso parece funcionar muito bem (ele até lida com o japonês!), Mas ainda existem algumas esquisitices:

  • \ndesencadeará C-j(não C-m, RETou <return>)
  • \tirá disparar TAB(não <tab>)
PythonNut
fonte