En utilisant GNU Readline; comment puis-je ajouter ncurses dans le même programme?
Question
Le titre est un peu plus précis que mon objectif réel:
I ai un programme de ligne de commande qui utilise GNU Readline, principalement pour l'historique des commandes (à savoir la récupération des commandes précédentes à l'aide de flèche vers le haut) et d'autres finesses. En ce moment, l'entrée de la sortie du programme apparaissent entremêlées avec l'utilisateur, qui parfois est OK, mais la sortie est asynchrone (il vient via une connexion réseau en réponse aux commandes d'entrée), et qui devient ennuyeux parfois (par exemple, si les lignes sont émis lorsque l'utilisateur est de taper nouvelle entrée).
Je voudrais ajouter une fonctionnalité à ce programme: une « fenêtre » séparée pour la sortie. Je pensais à l'utilisation de ncurses pour cela. Mais il ressort de la ncurses FAQ que les deux bibliothèques ne sont pas faciles à utiliser ensemble.
Je pourrais envisager d'utiliser editline ou
La solution Je l'ai fait quelques recherches, et il semble que vous êtes hors de la chance. Pour des alternatives ncurses il y a SLang , Triton et Turbo
Vision . L'argot est beaucoup plus que l'écran juste manipulation et donc plus
complexe, mais peut-être il peut être utilisé pour votre but ?. Newt utilise l'écran
la manipulation et est beaucoup plus simple, mais trop simple et un seul mode fileté
pour votre but, je pense. Turbo Vision est le mode texte bibliothèque graphique de Borland, utilisé par
tous leurs outils dans les fin des années 80 / début des années 90. Borland a publié la source
code lorsque le marché pour ce genre de chose a diminué, et il y a
maintenant un port pour Linux (note de côté, ce projet semble avoir écrit
sa propre mise en œuvre de la vision du turbo). Ce port n'est pas mort (il y en
été quelques cvs met à jour cette année qui a compilé fines (les anciennes versions
n'a pas)), mais aucun des exemples de télévision que j'ai trouvé étaient à jour et je
ne seulement eu peu d'entre eux pour compiler avant d'abandonner le reste.
Ceci est un peu dommage, parce que la télévision était un environnement agréable à utiliser.
TV est btw C ++ (et je suppose que vous utilisez C?). Pour une alternative à readline, il est libkinput , qui fonctionne peut-être
avec ncurses (il dit qu'il peut utiliser le terminfo de ncurses. mais je suis
pas sûr si cela signifie qu'il peut coexiste avec l'utilisation de ncurses)? Peut-être une option consiste à exécuter readline « externe » à votre programme ncurses
en utilisant rlwrap ?
Autres conseils
Je l'ai maintenant mis en place un programme simple exemple sur GitHub: https://github.com / ulfalizer / readline-et-ncurses .
Il prend en charge le redimensionnement terminal transparente et efficace et multi-octets / combinaison / caractères larges. Le code a des commentaires utiles.
Capture d'écran ci-dessous:
Cela me avait cognant ma tête pendant quelques heures, donc juste pour sauver les gens googler une certaine douleur:
Si vous utilisez gestionnaire builtin SIGWINCH
de ncurses avec KEY_RESIZE
, sachez que readline définit les variables d'environnement et de LINES
COLUMNS
par défaut. Celles-ci remplacent tout calcul de taille dynamique (généralement avec ioctl()
TIOCGWINSZ
) Ncurses ne le feraient autrement, ce qui signifie que vous allez continuer à obtenir la taille initiale même après la borne redimensionnement du terminal.
Ceci peut être évité par la mise en rl_change_environment
à 0
avant d'initialiser readline.
Mise à jour:
Voici quelques informations supplémentaires je glané des sources readline:
code de gestion des SIGWINCH
de readline (qui est utilisée si rl_catch_sigwinch
est 1) fait la mise à jour LINES
et COLUMNS
, qui semble comme il devrait être suffisant pour ncurses. Cependant, lorsque vous utilisez l'interface readline alternative (ce qui est le plus logique lorsque l'on combine readline avec ncurses), les gestionnaires de signaux (y compris celui de SIGWINCH
) ne seront installés pour la durée de chaque appel rl_callback_read_char()
, ce qui signifie un terminal redimensionne entre deux appels à rl_callback_read_char()
ne sera pas vu par readline.
Je l'ai réalisé ce que vous avez décrit dans un programme de la mine:
http://dpc.ucore.info/lab:xmppconsole
Ce qui suit est le fichier de manipulation io:
Alors il se avère que gdb utilise à la fois readline et ncurses. Si vous êtes intéressés à faire cela, je vous recommande de vérifier leur mise en œuvre: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c
Je ne sais pas quelle version vous avez essayé. A partir d'aujourd'hui (14/09/2012) Il est très simple, il suffit de brancher notre fonction personnalisée à la suite des pointeurs de fonction.
rl_getch_function rl_redisplay_function rl_completion_display_matches_hook