Ich habe eine Funktion, die automatisch ausgeführt wird, nachdem der Benutzer eine Aktion ausgeführt hat. Die Ausführung der Funktion dauert jedoch lange. Dies bedeutet, dass Emacs nach jeder Eingabe für kurze Zeit nicht mehr reagiert. Um dies zu beheben, möchte ich überprüfen, ob der Benutzer eine neue Eingabe eingegeben hat, und in diesem Fall die Ausführung dieser Funktion abbrechen und mit der Benutzereingabe fortfahren.
Gibt es eine Variable, die Tastatureingaben in der Warteschlange enthält? Wenn nicht, gibt es eine andere Möglichkeit zu überprüfen, ob der Benutzer eine Taste gedrückt hat, seit eine Funktion ausgeführt wurde?
while-no-input
Makro ansehen . Es scheint zu tun, was Sie wollen: dh es bricht die Ausführung seines Körpers ab, wenn neue Eingaben erscheinen.Antworten:
OK, ich werde eine erweiterte Antwort versuchen. Die Sache ist, Emacs Lisp ist Single-Threaded. Sie können mehr Prozesse drehen, jedoch nicht im Emacs Lisp-Interpreter. Die Tastatureingaben, die Sie vom Benutzer lesen müssen, um Ihre Funktion zu unterbrechen, müssen jedoch von demselben Emacs Lisp-Interpreter verarbeitet werden. Dies bedeutet, dass Sie möglicherweise keine Möglichkeit haben, den Lisp-Code von innen heraus zu unterbrechen, wenn Ihr Interpreter beim Interpretieren eines Lisp-Codes nicht weiterkommt. Hier ist eine Stelle im Handbuch, die diese Situation beschreibt:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html
Wie hat Emacs noch die C-gFunktion / Abbrechen? - Es gibt Timer und Funktionen, die E / A ausführen (auf Ereignisse in der Befehlsschleife warten). Timer können dafür sorgen, dass Ihre Berechnungen in Blöcken durchgeführt werden, sodass Sie Punkte in Ihren Berechnungen haben, an denen Sie sich umschauen und gegebenenfalls alle weiteren Berechnungen verhindern können. E / A-Funktionen können
quit
Signale senden . Das Makrowith-keyboard-quit
wartet auf dieses Signal und wird nach dem Empfang ordnungsgemäß beendet. Ihre Funktion muss jedoch wissen, um dieses Signal zu senden. Dies bedeutet, dass Sie nicht von Tastaturunterbrechungen profitieren können, wenn Ihre Funktion den Benutzer daran hindert, Tastatureingaben zu senden.Fazit: Versuchen Sie, den Code Ihrer Funktion in zu verpacken
while-no-input
. Wenn dies nicht funktioniert, schreiben Sie Ihre Funktion so um, dass Emacs Tastaturereignisse verarbeiten kann.quelle
C-g
kann lisp-Code immer unterbrechen,while-no-input
erweitert dies nur auf andere Tastatureingaben.(while t)
. (Aber bevor Sie dies tun, stellen Sie sicher, dass Sie alle Ihre Änderungen gespeichert haben).(while t)
in ein*scratch*
und drücken SieC-x C-e
dannC-g
; Ich habe dieQuit
Nachricht erhalten, Emacs ist nicht hängen geblieben.*scratch*
vertrauenswürdig ist, da jede Bewertung, die Sie dort vornehmen, in eine Hilfsfunktion eingebunden ist.(while t (condition-case _ (while t) (quit nil)))
, ich denke theoretisch ist das unterbrechbar, wenn man nurC-g
zum richtigen Zeitpunkt treffen könnte , aber in der Praxis kann man das nicht.Ich würde mit gehen
input-pending-t
. Aus den Dokumenten:Ein kurzes Beispiel:
quelle