Tengo una función que se ejecuta automáticamente después de que el usuario realiza alguna acción. Sin embargo, la función tarda mucho en completarse. Esto significa que Emacs deja de responder por un corto tiempo después de cada entrada. Para solucionar esto, me gustaría verificar si el usuario ha ingresado una nueva entrada y, de ser así, cancelar la ejecución de esta función y proceder con la entrada del usuario.
¿Hay alguna variable que contenga entradas de teclado en cola? Si no, ¿hay otra forma de verificar si el usuario ha presionado un botón desde que una función comenzó a ejecutarse?
while-no-input
macro. Parece hacer lo que quiere: es decir, cancela la ejecución de su cuerpo cuando aparece una nueva entrada.Respuestas:
OK, intentaré una respuesta ampliada. La cuestión es que Emacs Lisp es de un solo subproceso. Puede girar más procesos, pero no dentro del intérprete de Emacs Lisp. Sin embargo, la entrada de teclado que necesita leer del usuario para interrumpir su función debe ser procesada por el mismo intérprete de Emacs Lisp. Esto significa que si su intérprete está atascado interpretando algún código Lisp, puede que no haya una forma de interrumpirlo desde dentro. Aquí hay un lugar en el manual que describe esta situación:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html
Entonces, ¿cómo Emacs todavía tiene la C-gfuncionalidad / cancelación? - Hay temporizadores y funciones que hacen E / S (esperar eventos en el bucle de comandos). Los temporizadores pueden organizar que sus cálculos se realicen en fragmentos, de modo que tenga puntos en sus cálculos donde pueda mirar a su alrededor y, si es necesario, evitar todos los cálculos adicionales. Las funciones de E / S pueden enviar
quit
señal. La macrowith-keyboard-quit
espera esta señal y una vez recibida saldrá con gracia. Sin embargo, su función necesita saber para enviar esta señal. Esto significa que si su función impide que el usuario envíe la entrada del teclado, no podrá beneficiarse de las interrupciones del teclado.En pocas palabras: intente envolver el código de su función
while-no-input
. Si esto no funciona, intente reescribir su función de manera que permita que Emacs procese los eventos del teclado.fuente
C-g
siempre puede interrumpir el código lisp,while-no-input
solo lo extiende a otra entrada de teclado.(while t)
. (Pero antes de hacerlo, asegúrese de haber guardado todos los cambios).(while t)
en*scratch*
y golpearC-x C-e
a continuaciónC-g
; Recibí elQuit
mensaje, Emacs no se atascó.*scratch*
embargo, no estoy seguro de cuánto se puede confiar porque cada evaluación que realice allí está envuelta en una función auxiliar.(while t (condition-case _ (while t) (quit nil)))
, creo que en teoría eso es interrumpible si pudieras golpearC-g
en el momento adecuado, pero en la práctica no puedes.Me gustaría ir con
input-pending-t
. De los documentos:Un ejemplo rápido:
fuente