J'ai une fonction qui s'exécute automatiquement après que l'utilisateur a effectué une action. Cependant, la fonction prend beaucoup de temps. Cela signifie qu'Emacs ne répond plus pendant une courte période après chaque entrée. Pour résoudre ce problème, je voudrais vérifier si l'utilisateur a entré une nouvelle entrée et si oui, annuler l'exécution de cette fonction et poursuivre la saisie de l'utilisateur.
Y a-t-il une variable qui contient les entrées de clavier en file d'attente? Sinon, existe-t-il un autre moyen de vérifier si l'utilisateur a appuyé sur un bouton depuis le début de l'exécution d'une fonction?
while-no-input
macro. Il semble faire ce que vous voulez: c'est-à-dire qu'il annule l'exécution de son corps lorsque de nouvelles entrées apparaissent.Réponses:
OK, je vais essayer une réponse élargie. Le fait est qu'Emacs Lisp est monothread. Vous pouvez faire tourner plus de processus, mais pas à l'intérieur de l'interpréteur Emacs Lisp. Cependant, l'entrée au clavier que vous devez lire à l'utilisateur pour interrompre votre fonction doit être traitée par le même interpréteur Emacs Lisp. Cela signifie que si votre interprète est bloqué en train d'interpréter du code Lisp, vous ne pourrez peut-être pas l'interrompre de l'intérieur. Voici un endroit dans le manuel qui décrit cette situation:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html
Alors, comment Emacs a-t-il toujours la C-gfonctionnalité / annulation? - Il y a des temporisateurs et des fonctions qui font des E / S (attendre les événements dans la boucle de commande). Les temporisateurs peuvent arranger vos calculs en morceaux, afin que vous ayez des points dans vos calculs où vous pouvez regarder autour et, si nécessaire, empêcher tous les calculs ultérieurs. Les fonctions d'E / S peuvent envoyer un
quit
signal. La macrowith-keyboard-quit
attend ce signal et une fois reçue, elle se terminera normalement. Cependant, votre fonction doit savoir pour envoyer ce signal. Cela signifie que si votre fonction empêche l'utilisateur d'envoyer des entrées au clavier, vous ne pourrez pas bénéficier des interruptions du clavier.En résumé: essayez d'enrouler le code de votre fonction dans
while-no-input
. Si cela ne fonctionne pas, essayez de réécrire votre fonction de manière à permettre à Emacs de traiter les événements du clavier.la source
C-g
peut toujours interrompre le code lisp,while-no-input
l'étend simplement à d'autres entrées du clavier.(while t)
. (Mais avant de le faire, assurez-vous d'avoir enregistré toutes vos modifications).(while t)
dans*scratch*
et frappéC-x C-e
puisC-g
; J'ai compris leQuit
message, Emacs n'est pas resté coincé.*scratch*
on peut faire confiance, car chaque évaluation que vous y faites est enveloppée dans une fonction d'aide.(while t (condition-case _ (while t) (quit nil)))
, je pense qu'en théorie c'est interruptible si vous pouviez juste frapperC-g
au bon moment, mais en pratique vous ne pouvez pas.J'irais avec
input-pending-t
. De la documentation:Un exemple rapide:
la source