En primer lugar, un descargo de responsabilidad. He investigado esto muchas veces, y estoy bastante seguro de que ya he encontrado la respuesta de una forma u otra, pero simplemente no la entiendo.
Mi problema es el siguiente:
- Tengo un proceso que se ejecuta a través de comint
- Quiero enviar una línea de entrada, capturar salida y ver cuándo termina (cuando la última línea de la salida coincide con la expresión regular para una solicitud)
- solo cuando el proceso haya terminado de enviar la salida, quiero enviar otra línea de entrada (por ejemplo).
Para un poco de antecedentes, piense en un modo principal que implementa la interacción con un programa, que puede devolver una cantidad arbitraria de salida, en un tiempo arbitrariamente largo. Esto no debería ser una situación inusual, ¿verdad? De acuerdo, tal vez la parte donde necesito esperar entre entradas es inusual, pero tiene algunas ventajas sobre el envío de la entrada en su conjunto:
- el búfer de salida está bien formateado: entrada salida entrada salida ...
- lo que es más importante, cuando se envía mucho texto a un proceso, el texto se corta en pedazos y el proceso los vuelve a pegar; los puntos de corte son arbitrarios y esto a veces hace una entrada no válida (mi proceso no pegará correctamente un corte de entrada en el medio de un identificador, por ejemplo)
De todos modos, inusual o no, resulta que es complicado. En este momento, estoy usando algo en la línea de
(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))))
y lo llamo cada vez que envío una línea de entrada y antes de enviar la siguiente. Bueno ... funciona, eso ya es algo.
Pero también hace que emacs se cuelgue mientras espera la salida. La razón es obvia, y pensé que si incluía algún tipo de asíncrono sleep-for
(por ejemplo, 1s) en el bucle, retrasaría la salida en 1s, pero suprimiría el bloqueo. Excepto que parece que este tipo de asíncrono
sleep-for
no existe .
O lo hace? En términos más generales, ¿hay una forma idiomática de lograr esto con emacs? En otras palabras:
¿Cómo enviar entradas a un proceso, esperar la salida y luego enviar más entradas de forma asincrónica?
Al buscar alrededor (ver las preguntas relacionadas), principalmente he visto menciones de centinelas (pero no creo que se aplique en mi caso, ya que el proceso no termina) y de algunos ganchos de comint (pero ¿qué? haga que el gancho sea localmente búfer, convierta mi "evaluar las líneas restantes" en una función, agregue esta función al gancho y limpie el gancho después (eso suena muy sucio, ¿no?).
Lo siento si no me estoy aclarando, o si realmente hay una respuesta obvia disponible en alguna parte, estoy realmente confundido por todas las complejidades de la interacción del proceso.
Si es necesario, puedo hacer de todo esto un ejemplo de trabajo, pero me temo que solo haría una "pregunta de proceso específica con una respuesta de proceso específica" como todas las que encontré anteriormente y que no me ayudaron.
Algunas preguntas relacionadas sobre SO: