readline ncurses editline

Usando GNU Readline; ¿Cómo puedo agregar ncurses en el mismo programa?



editline (6)

Ahora he creado un programa de ejemplo simple en GitHub: https://github.com/ulfalizer/readline-and-ncurses .

Admite redimensionamiento de terminales sin problemas y eficiente y caracteres multibyte / combinados / anchos. El código tiene comentarios útiles.

Captura de pantalla a continuación:

El título es un poco más específico que mi objetivo real:

Tengo un programa de línea de comandos que usa GNU Readline, principalmente para el historial de comandos (es decir, recuperar comandos anteriores usando la flecha hacia arriba) y algunas otras mejoras. En este momento, la salida del programa aparece entremezclada con la entrada del usuario, que a veces está bien, pero la salida es asíncrona (se produce a través de una conexión de red en respuesta a los comandos de entrada), y eso a veces resulta molesto (por ejemplo, si se emiten líneas cuando el usuario está escribiendo nueva entrada).

Me gustaría agregar una característica a este programa: una "ventana" separada para la salida. Pensé en usar ncurses para esto. Pero de las Preguntas frecuentes de ncurses se desprende que las dos bibliotecas no son fáciles de usar juntas.

Podría considerar usar Editline o tecla lugar de Readline, pero no está claro si alguno de ellos resolverá mi problema. También consideraría usar algo distinto de ncurses, incluida una biblioteca que proporcione ambos tipos de funcionalidad (ventanas de modo de texto e historial de comandos), pero no sé cuál podría ser la mejor.

Ah, y el soporte para texto en color podría obtener puntos de bonificación. Sospecho que puedo hacer eso con Readline, así que tal vez sea una preocupación aparte, pero si una solución a mi problema también facilita agregar un poco de color a la salida, tanto mejor.

Estoy usando Ubuntu Hardy (Linux 2.6).



Esto me hizo golpearme la cabeza durante unas horas, así que solo para salvar a la gente.

Si está utilizando el controlador SIGWINCH ncurses con KEY_RESIZE , tenga en cuenta que readline establece las variables de entorno LINES y COLUMNS de forma predeterminada. Estos anulan cualquier cálculo de tamaño dinámico (generalmente con ioctl() TIOCGWINSZ ) que de lo contrario haría ncurses, lo que significa que seguirá obteniendo el tamaño inicial del terminal incluso después de cambiar el tamaño del terminal.

Esto se puede evitar configurando rl_change_environment en 0 antes de inicializar readline.

Actualizar:

Aquí hay alguna información adicional que obtuve de las fuentes de readline:

El código de manejo SIGWINCH de readline (que se usa si rl_catch_sigwinch es 1) actualiza LINES y COLUMNS , lo que parece que debería ser suficiente para ncurses. Sin embargo, cuando se usa la interfaz de línea de lectura alternativa (lo que tiene más sentido cuando se combina la línea de lectura con ncurses), los manejadores de señales (incluido el de SIGWINCH ) solo se instalarán durante la llamada de rl_callback_read_char() , lo que significa que cualquier terminal rl_callback_read_char() tamaño entre dos Las llamadas a rl_callback_read_char() no serán vistas por readline.


He hecho algunas búsquedas, y parece que estás fuera de suerte.

Para alternativas de ncurses hay SLang , Newt y Turbo Vision . La jerga es mucho más que el manejo de la pantalla y, por lo tanto, más compleja, pero ¿quizás pueda usarse para su propósito? Newt utiliza el manejo de la pantalla y creo que es mucho más simple, pero demasiado simple y de modo de un solo hilo para su propósito.

Turbo Vision es la biblioteca de gráficos en modo texto de Borland, utilizada por todas sus herramientas a finales de los 80 y principios de los 90. Borland lanzó el código fuente cuando el mercado para ese tipo de cosas disminuyó, y ahora hay un puerto para Linux (nota al margen, este proyecto parece haber escrito su propia implementación de turbo visión). Ese puerto no está muerto (ha habido algunas actualizaciones de cvs este año que compilaron bien (las versiones anteriores no lo hicieron)), pero ninguno de los ejemplos de TV que encontré estaban actualizados y solo compilé algunos de ellos antes. renunciar al resto. Esto es un poco de vergüenza, porque la televisión era un ambiente encantador para usar. La TV es por cierto C ++ (y supongo que está utilizando C?).

Para una alternativa a readline, hay libkinput , que quizás funcione junto con ncurses (dice que puede usar el término ncurses ''pero no estoy seguro si eso significa que puede coexistir junto con el uso de ncurses)?

Tal vez una opción es ejecutar readline "externamente" a su programa ncurses usando rlwrap ?



No estoy seguro de qué versión probaste. A partir de hoy (2012.09.14) Es muy simple, solo necesitamos conectar nuestra función personalizada a los siguientes punteros de función.

rl_getch_function rl_redisplay_function rl_completion_display_matches_hook

Hice algo razonable here .