Tout d'abord, un avertissement. J'ai fait des recherches à ce sujet plusieurs fois, et je suis presque sûr d'avoir déjà trouvé la réponse d'une manière ou d'une autre, mais je ne la comprends tout simplement pas.
Mon problème est le suivant:
- J'ai un processus en cours d'exécution via comint
- Je veux envoyer une ligne d'entrée, capturer la sortie et voir quand elle est terminée (lorsque la dernière ligne de la sortie correspond à l'expression rationnelle pour une invite)
- seulement lorsque le processus a fini d'envoyer la sortie, je veux envoyer une autre ligne d'entrée (par exemple).
Pour un peu de contexte, pensez à un mode majeur implémentant l'interaction avec un programme, qui peut retourner une quantité arbitraire de sortie, dans un temps arbitrairement long. Cela ne devrait pas être une situation inhabituelle, non? D'accord, la partie où je dois attendre entre les entrées est peut-être inhabituelle, mais elle présente quelques avantages par rapport à l'envoi de l'entrée dans son ensemble:
- le tampon de sortie est bien formaté: entrée sortie entrée sortie ...
- plus important encore, lorsque vous envoyez beaucoup de texte à un processus, le texte est coupé en morceaux et les morceaux sont collés par le processus; les points de coupure sont arbitraires et cela rend parfois une entrée invalide (mon processus ne recollera pas correctement une entrée coupée au milieu d'un identifiant, par exemple)
Quoi qu'il en soit, inhabituelle ou non, il se trouve qu'il est compliqué. En ce moment, j'utilise quelque chose comme
(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))))
et j'appelle cela à chaque fois après avoir envoyé une ligne d'entrée, et avant d'envoyer la suivante. Eh bien ... ça marche, c'est déjà quelque chose.
Mais cela fait aussi bloquer emacs en attendant la sortie. La raison est évidente, et j'ai pensé que si j'incluais une sorte d'asynchrone sleep-for
(par exemple 1s) dans la boucle, cela retarderait la sortie de 1s, mais supprimerait le blocage. Sauf qu'il semble que ce type d'asynchrone
sleep-for
n'existe pas .
Ou alors? Plus généralement, existe-t-il un moyen idiomatique d'y parvenir avec emacs? En d'autres termes:
Comment envoyer une entrée à un processus, attendre la sortie, puis envoyer plus d'entrée, de manière asynchrone?
En cherchant autour (voir les questions connexes), j'ai principalement vu des mentions de sentinelles (mais je ne pense pas que cela s'applique dans mon cas, car le processus ne se termine pas) et de quelques crochets de comint (mais alors quoi? Devrais-je rendre le crochet tampon local, transformer mon "évaluer les lignes restantes" en une fonction, ajouter cette fonction au crochet et nettoyer le crochet par la suite? cela semble vraiment sale, n'est-ce pas?).
Je suis désolé si je ne suis pas clair, ou s'il y a vraiment une réponse évidente disponible quelque part, je suis vraiment confus par toutes les subtilités de l'interaction des processus.
Si nécessaire, je peux faire de tout cela un exemple de travail, mais je crains que cela ne fasse qu'une "question de processus spécifique avec une réponse de processus spécifique" comme toutes celles que j'ai trouvées plus tôt et ne m'a pas aidé.
Quelques questions connexes sur SO: