Eu tenho uma função que é executada automaticamente depois que o usuário executa alguma ação. No entanto, a função leva muito tempo para ser concluída. Isso significa que o Emacs fica sem resposta por um curto período de tempo após cada entrada. Para corrigir isso, gostaria de verificar se o usuário inseriu uma nova entrada e, em caso afirmativo, cancelar a execução desta função e prosseguir com a entrada do usuário.
Existe uma variável que contém entradas de teclado na fila? Caso contrário, existe outra maneira de verificar se o usuário pressionou um botão desde que uma função começou a ser executada?
while-no-input
macro. Parece fazer o que você deseja: isto é, cancela a execução de seu corpo quando novas entradas são exibidas.Respostas:
OK, vou tentar uma resposta expandida. O problema é que o Emacs Lisp é de thread único. Você pode girar mais processos, mas não dentro do interpretador Emacs Lisp. No entanto, a entrada do teclado que você precisa ler do usuário para interromper sua função precisa ser processada pelo mesmo intérprete do Emacs Lisp. Isso significa que, se o seu intérprete estiver travado na interpretação de algum código Lisp, talvez não haja uma maneira de interrompê-lo por dentro. Aqui está um lugar no manual que descreve essa situação:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html
Então, como o Emacs ainda tem a C-gfuncionalidade / canceling? - Existem timers e funções que executam E / S (aguardam eventos no loop de comando). Os temporizadores podem organizar seus cálculos em pedaços, para que você tenha pontos em seus cálculos em que possa olhar ao redor e, se necessário, impedir todos os cálculos adicionais. As funções de E / S podem enviar
quit
sinal. A macrowith-keyboard-quit
aguarda esse sinal e, uma vez recebido, sai normalmente. No entanto, sua função precisa saber para enviar este sinal. Isso significa que, se sua função impedir que o usuário envie entrada do teclado, você não poderá se beneficiar das interrupções do teclado.Conclusão: tente agrupar o código da sua função
while-no-input
. Se isso não funcionar, tente reescrever sua função de forma que o Emacs processe os eventos do teclado.fonte
C-g
sempre pode interromper o código lisp,while-no-input
apenas o estende a outras entradas do teclado.(while t)
. (Mas antes de fazer isso, verifique se todas as alterações foram salvas).(while t)
em*scratch*
e bateuC-x C-e
entãoC-g
; Eu recebi aQuit
mensagem, o Emacs não ficou preso.*scratch*
pode ser confiável, porque cada avaliação que você faz lá é envolvida em uma função auxiliar.(while t (condition-case _ (while t) (quit nil)))
, eu acho que na teoria é interrompível se você pudesse acertarC-g
no momento certo, mas na prática você não pode.Eu iria com
input-pending-t
. Dos documentos:Um exemplo rápido:
fonte