Zunächst ein Haftungsausschluss. Ich habe dies oft recherchiert und bin mir ziemlich sicher, dass ich die Antwort auf die eine oder andere Weise schon gefunden habe, aber ich verstehe es einfach nicht.
Mein Problem ist folgendes:
- Ich habe einen Prozess, der durch comint läuft
- Ich möchte eine Eingabezeile senden, die Ausgabe erfassen und sehen, wann sie beendet ist (wenn die letzte Zeile der Ausgabe mit dem regulären Ausdruck für eine Eingabeaufforderung übereinstimmt).
- Erst wenn der Vorgang das Senden der Ausgabe beendet hat, möchte ich eine weitere Eingabezeile senden (zum Beispiel).
Stellen Sie sich für ein wenig Hintergrund einen Hauptmodus vor, der die Interaktion mit einem Programm implementiert, das in beliebig langer Zeit eine beliebige Menge an Ausgabe zurückgeben kann. Dies sollte keine ungewöhnliche Situation sein, oder? Okay, vielleicht ist der Teil, in dem ich zwischen den Eingaben warten muss, ungewöhnlich, aber es hat ein paar Vorteile gegenüber dem Senden der Eingabe als Ganzes:
- Der Ausgabepuffer ist schön formatiert: Eingabe Ausgabe Eingabe Ausgabe ...
- Noch wichtiger ist, dass beim Senden einer großen Menge Text an einen Prozess der Text in Teile geschnitten und die Teile durch den Prozess wieder eingefügt werden. Die Schnittpunkte sind willkürlich und dies führt manchmal zu ungültigen Eingaben (mein Prozess fügt beispielsweise einen Eingabeschnitt in der Mitte eines Bezeichners nicht korrekt ein).
Wie auch immer, ungewöhnliche oder nicht, es stellt sich heraus , dass es ist kompliziert. Im Moment benutze ich etwas in der Art von
(defun mymode--wait-for-output ()
(let ((buffer (mymode-get-buffer)))
(with-current-buffer buffer
(goto-char (point-max))
(forward-line 0)
(while (not (mymode-looking-at-prompt))
(accept-process-output nil 0.001)
(redisplay)
(goto-char (point-max))
(forward-line 0))
(end-of-line))))
und ich rufe dies jedes Mal nach dem Senden einer Eingabezeile und vor dem Senden der nächsten Zeile auf. Nun ... es funktioniert, das ist schon etwas.
Aber es lässt auch Emacs hängen, während sie auf die Ausgabe warten. Der Grund liegt auf der Hand, und ich stellte mir vor, dass, wenn ich eine Art asynchroner sleep-for
Schleife (z. B. 1s) einbinde, die Ausgabe um 1s verzögert wird, das Hängen jedoch unterdrückt wird. Abgesehen davon, dass es diese Art von Asynchronität anscheinend
sleep-for
nicht gibt .
Oder doch? Gibt es einen idiomatischen Weg, dies mit Emacs zu erreichen? Mit anderen Worten:
Wie kann ich Eingaben an einen Prozess senden, auf die Ausgabe warten und dann asynchron weitere Eingaben senden?
Beim Durchsuchen (siehe die zugehörigen Fragen) habe ich hauptsächlich Erwähnungen von Sentinels (aber ich glaube nicht, dass dies in meinem Fall zutrifft, da der Prozess nicht abgeschlossen ist) und von einigen Comint-Hooks (aber was soll ich dann tun?) Gesehen mache den Hook buffer-local, verwandle meine "restlichen Zeilen auswerten" in eine Funktion, füge diese Funktion dem Hook hinzu und reinige den Hook danach - das klingt wirklich schmutzig, oder?).
Es tut mir leid, wenn ich mich nicht klar mache oder wenn irgendwo wirklich eine offensichtliche Antwort verfügbar ist, bin ich wirklich verwirrt über all die Komplikationen der Prozessinteraktion.
Bei Bedarf kann ich das alles zu einem funktionierenden Beispiel machen, aber ich befürchte, dass es nur eine weitere "spezifische Prozessfrage mit spezifischer Prozessantwort" geben wird, wie all jene, die ich zuvor gefunden habe und die mir nicht geholfen haben.
Einige verwandte Fragen zu SO: