que utilizan GNU Readline a la moda "seleccionar", mediante el registro de una llamada de retorno de este modo:GNU Readline: cómo borrar la línea de entrada?
rl_callback_handler_install("", on_readline_input);
Y luego conectar rl_callback_read_char
como la devolución de llamada para mi lazo para select()
STDIN_FILENO
. Eso es todo bastante estándar, y funciona bien.
Ahora, mi programa imprime de forma asincrónica mensajes en la pantalla, a veces intercalados con las entradas del usuario. Una sesión de "limpia" se vería así:
user input
SERVER OUTPUT
SERVER OUTPUT
user input
SERVER OUTPUT
Pero lo que si el usuario está a medio camino a través de una línea cuando llega la respuesta del servidor? A continuación, se pone feo:
user input
SERVER OUTPUT
user inSERVER OUTPUT
put
SERVER OUTPUT
i fijo esto simplemente mediante la impresión de un salto de línea antes de la salida del servidor si el usuario hubiera tecleado nada (esto es fácil de decir comprobando rl_line_buffer
), y luego hacer rl_forced_update_display()
después de imprimir la salida del servidor . Ahora se ve así:
user input
SERVER OUTPUT
user in
SERVER OUTPUT
user input
SERVER OUTPUT
Esto es mejor, pero aún así no es perfecto. El problema viene cuando el usuario ha introducido toda una línea, pero aún no se presione Enter - a continuación, se ve así:
user input
SERVER OUTPUT
user input
SERVER OUTPUT
user input
SERVER OUTPUT
Esto es malo, ya que se muestra al usuario que escriben tres comandos (tres respuestas para tres entradas son tan posibles como tres respuestas para dos entradas, que es lo que realmente sucedió).
un corte desagradable (que funciona) es hacer esto:
user input
SERVER OUTPUT
user input - INCOMPLETE
SERVER OUTPUT
user input
SERVER OUTPUT
pensé que podría mejorar esta imprimiendo caracteres de retroceso en lugar de " - INCOMPLETE"
('\ b'), pero eso no parece hacer cualquier cosa en mi terminal (gnome-terminal en Ubuntu Hardy). printf("ABC\b");
simplemente imprime ABC
, por el motivo que sea.
Entonces, ¿cómo puedo borrar la línea de entrada incompleta? Ya sea por impresión de espacios invertidos de alguna manera (puedo averiguar cuántos para imprimir - es strlen(rl_line_buffer)
), o mediante el uso de algunas instalaciones de Readline que todavía no conozco?
Algunos terminales/emuladores de terminal tienen un comportamiento diferente para el carácter de retroceso. pmg tiene la idea correcta. –
Esto funciona en mi terminal. Pero sin una mejor comprensión de por qué funciona y cómo (no portátil) es, he elegido usar '\ r' en su lugar (como se sugiere en otra respuesta). –
Cambié de opinión después de usar el código '\ r' por un tiempo ... Me gusta esto mejor, porque no requiere sobreimpresión con espacios al final (prefiero hacer la sobreimpresión antes de la salida del servidor, por lo que la solución me sienta mejor, sin mencionar que es la respuesta más directa a mi pregunta original). –