Usando o GNU Readline; Como posso adicionar ncurses no mesmo programa?

O título é um pouco mais específico do que meu objective real:

Eu tenho um programa de linha de comando que usa o GNU Readline, principalmente para o histórico de comandos (ou seja, recuperar os comandos anteriores usando a seta para cima) e algumas outras sutilezas. Neste momento, a saída do programa aparece intercalada com a input do usuário, o que às vezes é OK, mas a saída é assíncrona (vem através de uma conexão de rede em resposta aos comandos de input) e fica irritante às vezes (por exemplo, se as linhas saem quando o usuário está digitando nova input).

Eu gostaria de adicionar um recurso para este programa: uma “janela” separada para a saída. Eu pensei em usar ncurses para isso. Mas parece que as duas bibliotecas não são fáceis de usar juntas.

Eu poderia considerar o uso de Editline ou tecla em vez de Readline, mas não está claro para mim se algum deles resolverá meu problema. Eu também consideraria usar algo diferente de ncurses, incluindo uma biblioteca que fornece os dois tipos de funcionalidade (janelas de modo de texto e histórico de comandos), mas não sei o que pode ser melhor.

Ah, e suporte para texto colorido pode ganhar pontos de bônus. Eu suspeito que eu possa fazer isso com o Readline, então talvez seja uma preocupação separada, mas se uma solução para o meu problema também torna fácil adicionar um pouco de cor à saída, tanto melhor.

Estou usando o Ubuntu Hardy (Linux 2.6).

Eu fiz algumas pesquisas, e parece que você está sem sorte.

Para alternativas de ncurses, existem o SLang , o Newt e o Turbo Vision . Gíria é muito mais do que apenas manipulação de canvas e, portanto, mais complexa, mas talvez ela possa ser usada para o seu propósito. Newt usa a manipulação de canvas e é muito mais simples, mas muito simples e de modo single-threaded para o seu propósito, eu acho.

Turbo vision é a biblioteca de charts em modo texto da Borland, usada por todas as suas ferramentas no final dos anos 80 e início dos anos 90. A Borland divulgou o código-fonte quando o mercado para esse tipo de coisa diminuiu, e agora há uma porta para o Linux (nota lateral, este projeto parece ter escrito sua própria implementação de turbo-visão). Essa porta não está morta (houve algumas atualizações do cvs este ano que foram bem compiladas (os lançamentos mais antigos não o fizeram)), mas nenhum dos exemplos de TV que encontrei estavam atualizados e eu só consegui alguns deles para compilar antes desistindo do resto. Isso é um pouco de vergonha, porque a TV era um ambiente adorável para usar. TV é btw C ++ (e eu suponho que você está usando C?).

Para uma alternativa à readline, existe o libkinput , que talvez funcione junto com ncurses (ele diz que pode usar o terminfo ncurses ‘. Mas não tenho certeza se isso significa que ele pode coexistir com o uso de ncurses)?

Talvez uma opção é executar readline “externamente” para o seu programa ncurses usando o rlwrap ?

Isso me fez bater a cabeça por algumas horas, então só para salvar as pessoas pesquisando alguma dor:

Se você estiver usando o manipulador SIGWINCH embutido SIGWINCH com KEY_RESIZE , esteja ciente de que readline define as variables ​​de ambiente LINES e COLUMNS por padrão. Eles substituem qualquer cálculo de tamanho dynamic (geralmente com ioctl() TIOCGWINSZ ) que o TIOCGWINSZ faria caso contrário, o que significa que você continuará recebendo o tamanho inicial do terminal mesmo depois de resize o terminal.

Isso pode ser evitado configurando-se o rl_change_environment como 0 antes de inicializar o readline.

Atualizar:

Aqui estão algumas informações adicionais que eu recolhi das fonts readline:

O código de manipulação SIGWINCH da readline (que é usado se rl_catch_sigwinch for 1) atualiza LINES e COLUMNS , o que parece ser suficiente para ncurses. No entanto, ao usar a interface readline alternativa (que faz mais sentido combinando readline com ncurses), os manipuladores de sinais (incluindo o de SIGWINCH ) só serão instalados durante a duração de cada chamada rl_callback_read_char() , significando que qualquer terminal é redimensionado entre dois. chamadas para rl_callback_read_char() não serão vistas pela readline.

Eu consegui o que você descreveu em um programa meu:

http://dpc.ucore.info/lab:xmppconsole

A seguir, o arquivo que manipula o io:

http://github.com/dpc/xmppconsole/blob/master/src/io.c

Então, acontece que o gdb usa readline e ncurses. Se você estiver interessado em fazer isso, recomendo que verifique sua implementação: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c

Não tenho certeza de qual versão você tentou. A partir de hoje (2012.09.14) É muito simples, só precisamos de ligar a nossa function personalizada aos seguintes pointers de function.

 rl_getch_function
 rl_redisplay_function
 rl_completion_display_matches_hook

Eu fiz algo razoável aqui .

Intereting Posts