Mit GNU Readline; wie kann ich ncurses im selben Programm hinzufügen?
Frage
Der Titel ist etwas spezifischer als mein eigentliches Ziel:
Ich habe ein Befehlszeilenprogramm, das GNU Readline verwendet, in erster Linie für die Befehlsgeschichte und einige andere niceties (d.h. vorherige Befehle Aufwärtspfeil Abrufen). Gerade jetzt die Ausgabe des Programms mit der Benutzereingabe durchsetzt erscheint, die manchmal in Ordnung ist, aber der Ausgang ist asynchron (es kommt über eine Netzwerkverbindung in Reaktion auf die Eingabebefehle), und das nervt manchmal (zB wenn Zeilen ausgegeben werden, wenn der Benutzer Neueingabe ist die Eingabe).
Ich mag eine Funktion zu diesem Programm hinzuzufügen: ein separates „Fenster“ für die Ausgabe. Ich dachte über ncurses für diese Verwendung. Aber es scheint, von der ncurses FAQ dass die beiden Bibliotheken sind nicht leicht zu zusammen verwenden.
Ich halte könnte mit Editline oder
Lösung Ich habe einige der Suche getan, und es scheint, wie Sie kein Glück. Für ncurses Alternativen gibt es SLang , Newt und Turbo
Vision . Slang ist viel mehr als nur Bildschirm Handling und damit mehr
Komplex, aber vielleicht kann es für Ihre Zwecke verwendet werden ?. Newt verwendet den Bildschirm
und Handhabung ist viel einfacher, aber zu einfach und Single-Thread-Modus
für Ihre Zwecke denke ich. Turbo Vision ist die Textmodus-Grafikbibliothek von Borland, verwendet von
alle ihre Werkzeuge in den späten 80er / Anfang der 90er Jahre. Borland veröffentlicht die Quelle
Code, wenn der Markt für diese Art der Sache vermindert, und es gibt
jetzt ein Port für Linux (Seite beachten, dieses Projekt geschrieben zu haben scheint
seine eigenen Turbo-Vision-Implementierung). Dieser Port ist nicht tot (es haben
waren einige cvs-Updates in diesem Jahr, die kompiliert fein (die älteren Versionen
nicht)), aber keines der TV Beispiele, die ich war auf dem neuesten Stand zu finden und ich
hat bekam nur ein paar von ihnen, bevor er aufgibt auf den Rest zu kompilieren.
Dies ist ein bisschen schade, weil TV eine schöne Umgebung war zu verwenden.
TV ist btw C ++ (und ich nehme an, Sie sind mit C?). Für eine Alternative zu readline gibt es libkinput , die vielleicht Werken
zusammen mit ncurses (es sagt, es ncurses' term verwenden können. aber ich bin
nicht sicher, ob das bedeutet, dass es zusammen mit ncurses Nutzung existiert zusammen kann)? Vielleicht eine Option ist Readline- „extern“ zu Ihrem ncurses Programm auszuführen
mit rlwrap ?
Andere Tipps
Ich habe jetzt zusammen ein einfaches Beispielprogramm auf GitHub: https://github.com / ulfalizer / readline--and-ncurses .
Es unterstützt die nahtlose und effiziente Terminal Redimensionierung und multibyte / Kombination / Wide-Zeichen. Der Code hat hilfreiche Kommentare.
Screenshot unten:
Das hatte mich für ein paar Stunden den Kopf hämmern, so dass nur die Menschen zu retten einige Schmerzen Googeln:
Wenn Sie ncurses' builtin SIGWINCH
Handler mit KEY_RESIZE
verwenden, beachten Sie, dass Readline- die LINES
und COLUMNS
Umgebungsvariablen standardmäßig setzt. Diese überschreiben jede dynamische Größenberechnung (in der Regel mit ioctl()
TIOCGWINSZ
), dass ncurses sonst tun, was bedeutet, Sie halten die ursprüngliche Terminal Größe immer auch nach dem Terminal Größe ändern.
Dies kann durch Setzen rl_change_environment
vor der Initialisierung Readline- 0
verhindert werden.
Update:
Hier einige zusätzliche Informationen, die ich aus den Readline- Quellen entnommen:
Readline- des SIGWINCH
Handling-Code (die verwendet wird, wenn rl_catch_sigwinch
1) tut Update LINES
und COLUMNS
, die wie es scheint, sollte für ncurses ausreichend zu sein. Wenn jedoch die alternative Readline- Schnittstelle (die am meisten Sinn macht, wenn Readline- mit ncurses Combining), die Signalbehandlungsroutinen (einschließlich der für SIGWINCH
) wird nur für die Dauer eines jeden rl_callback_read_char()
Anruf installiert werden, jede Klemme zwischen zwei Anrufe, um die Größe was bedeutet, rl_callback_read_char()
wird von readline- nicht gesehen werden.
Ich habe erreicht, was man in einem Programm von mir beschrieben haben:
http://dpc.ucore.info/lab:xmppconsole
Hier finden Sie die Datei Umgang mit io:
So stellt sich heraus, dass gdb sowohl readline- und ncurses verwendet. Wenn Sie dabei daran interessiert sind, dann empfehle ich, dass Sie ihre Umsetzung überprüfen: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c
Ich bin nicht sicher, welche Version Sie versuchen. Ab heute (2012.09.14) Es ist sehr einfach, wir müssen nur folgende Funktionszeiger unsere benutzerdefinierte Funktion einzuhaken.
rl_getch_function rl_redisplay_function rl_completion_display_matches_hook
Ich habe etwas vernünftig hier .