Pytanie Używanie GNU Readline; jak mogę dodać ncurses w tym samym programie?


Tytuł jest nieco bardziej szczegółowy niż mój rzeczywisty cel:

Mam program wiersza poleceń, który korzysta z Readline GNU, głównie dla historii poleceń (tj. Pobierania poprzednich poleceń za pomocą strzałki w górę) i innych innych elementów. W tej chwili dane wyjściowe programu pojawiają się na przemian z danymi wejściowymi użytkownika, co czasami jest w porządku, ale dane wyjściowe są asynchroniczne (przychodzi przez połączenie sieciowe w odpowiedzi na polecenia wejściowe), co czasami staje się denerwujące (np. Jeśli linie są wyprowadzane, gdy użytkownik pisze nowe wejście).

Chciałbym dodać funkcję do tego programu: osobne "okno" dla wyjścia. Myślałem o tym, żeby użyć ncurses. Ale wynika z ncurses FAQ że dwie biblioteki nie są łatwe do użycia razem.

Mogę rozważyć użycie Editline lub tecla zamiast Readline, ale nie jest dla mnie jasne, czy któreś z nich rozwiąże mój problem. Rozważę też użycie czegoś innego niż ncurses, w tym biblioteki, która zapewnia oba rodzaje funkcjonalności (okna tekstowe i historię poleceń), ale nie wiem, co może być najlepsze.

Och, a obsługa kolorowego tekstu może uzyskać dodatkowe punkty. Podejrzewam, że mogę to zrobić z Readline, więc może to osobny problem, ale jeśli rozwiązanie mojego problemu również ułatwia dodanie nieco koloru do wyjścia, tym lepiej.

Używam Ubuntu Hardy (Linux 2.6).


21
2018-03-27 22:11


pochodzenie


Znalazłeś rozwiązanie? - dpc.pw
Poddałem się (i utknąłem z readline). - John Zwinck


Odpowiedzi:


Szukałem trochę i wygląda na to, że nie masz szczęścia.

Dla alternatywy ncurses są Gwara, Traszka i Turbo Wizja. Slang to znacznie więcej niż obsługa ekranu złożony, ale może może być użyty do twojego celu ?. Newt używa ekranu obsługa i jest znacznie prostszy, ale zbyt prosty i tryb jednowątkowy dla twojego celu myślę.

Turbo vision to biblioteka graficzna w trybie tekstowym firmy Borland, używana przez wszystkie ich narzędzia w późnych latach 80-tych / wczesnych latach 90-tych. Borland zwolnił źródło kod, gdy rynek tego typu rzeczy zmniejszył się i jest teraz port dla Linuksa (uwaga boczna, ten projekt wydaje się, że napisałem własna implementacja turbo wizji). Ten port nie jest martwy (nie ma były niektóre aktualizacje cvs w tym roku, które skompilowane dobrze (starsze wersje nie)), ale żaden z przykładów TV, które znalazłem, nie był aktualny i ja tylko kilka z nich skompilowało, zanim zrezygnowało z pozostałych. To trochę szkoda, ponieważ telewizor był pięknym środowiskiem, z którego można korzystać. TV jest btw C ++ (i zakładam, że używasz C?).

Alternatywą dla readline jest libkinput, co może działa razem z ncurses (mówi, że może używać terminfo ncurses, ale ja jestem nie wiesz, czy to oznacza, że ​​może współistnieć z użyciem ncurses)?

Być może jedną z opcji jest uruchomienie readline "zewnętrznie" do programu ncurses za pomocą rlwrap?


6
2018-03-28 22:33



slang okazuje się być językiem samym w sobie. Również jest licencją GPL2 tylko dla najnowszej wersji. Spodziewałem się, że będzie to biblioteka. - matiu
Zauważ, że Newt jest warstwą nad SLangiem. Może być łatwiejszy w użyciu, ale jest to kolejna opcja. - Alexis Wilke


Złożyłem teraz prosty przykładowy program na GitHub: https://github.com/ulfalizer/readline-and-ncurses.

Obsługuje płynne i wydajne skalowanie terminali oraz wielobajtowe / kombinowane / szerokie znaki. Kod zawiera pomocne komentarze.

Zrzut ekranu poniżej:

Screenshot of program combining ncurses and readline


9
2018-02-25 02:14



Fantastyczny! Co to jest licencja na kod? Chciałbym w miarę możliwości zintegrować go z jakimś materiałem licencjonowanym na MIT. Dzięki! - cxw
Cieszę się, że to pomocne! Mogłabym go umieścić w MIT, gdyby to było najmniej kłopotów. W innym przypadku byłbym z ISC, a MIT wygląda podobnie. Mam również wersję, która uruchamia pętlę select () (lub epoll () w tym przypadku) przy okazji, dla github.com/ulfalizer/botniklas. Zjechałem na boczny tor i nie pchnąłem go jeszcze, ale mógłbym zrobić dla niego gałąź, gdybyś był zainteresowany. - Ulfalizer
Ta wersja instaluje program obsługi SIGWINCH (chociaż używa on signalfd () zamiast zwykłego programu obsługi) i pozwala readline czytać bezpośrednio ze standardowego wejścia. To także rozwiązuje problem z wyszukiwaniem i znakami wielobajtowymi. - Ulfalizer
To świetnie, ale dalej OS X El Capitan„s Terminal funkcja przewijania nie jest obsługiwana. Zamiast tego przewija historię readline. Może ma to coś wspólnego z tym: macissues.com/2014/06/10/... - Adam
@Adam: nie ma funkcji przewijania. Górne okno zostało dodane tylko po to, aby uzyskać bardziej interesujący układ i faktycznie zrobić coś z danymi wejściowymi z readline w tym przykładzie. - Ulfalizer


To kazało mi walić w głowę przez kilka godzin, więc tylko po to, aby ratować ludzi.

Jeśli używasz wbudowanego ncurses SIGWINCH obsługujący z KEY_RESIZE, należy pamiętać, że readline ustawia LINES i COLUMNS zmienne środowiskowe domyślnie. Zastępują one wszelkie obliczenia dynamiczne (zwykle z ioctl()  TIOCGWINSZ), co zrobiłby ncurses, co oznacza, że ​​otrzymasz początkowy rozmiar terminala nawet po zmianie rozmiaru terminalu.

Można temu zapobiec, ustawiając rl_change_environment do 0 przed inicjalizacją readline.

Aktualizacja:

Oto kilka dodatkowych informacji, które zebrałem ze źródeł readline:

readline SIGWINCH obsługa kodu (który jest używany, jeśli rl_catch_sigwinch jest 1) aktualizuje się LINES i COLUMNS, co wydaje się być wystarczające dla ncurses. Jednak w przypadku używania alternatywnego interfejsu readline (co jest najbardziej sensowne przy łączeniu readline z ncurses), procedury obsługi sygnału (w tym SIGWINCH) będą instalowane tylko na czas trwania każdego rl_callback_read_char() call, co oznacza, że ​​dowolny terminal zmienia rozmiar między dwoma wywołaniami rl_callback_read_char() nie będzie widoczny przez readline.


5
2018-02-17 21:15



Proszę wziąć pod uwagę formatowanie Twoja odpowiedź. Polecenia / kod są trudne do odczytania. - ryanyuyu
@dotctor Dzięki za sformatowanie go dla mnie! - Ulfalizer


Osiągnąłem to, co opisałeś w moim programie:

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

Poniżej przedstawiono obsługę plików io:

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


3
2018-06-09 18:54





Okazuje się, że gdb używa zarówno readline, jak i ncurses. Jeśli jesteś zainteresowany zrobieniem tego, polecam sprawdzenie ich implementacji: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c


3
2018-05-06 17:45



Wow, dzięki za to. Witamy w StackOverflow, Guillaume. :) - John Zwinck


Nie jestem pewien, którą wersję wypróbowałeś. Na dzień dzisiejszy (2012.09.14) Jest to bardzo proste, wystarczy podpiąć naszą funkcję niestandardową do następujących wskaźników funkcji.

rl_getch_function
rl_redisplay_function
rl_completion_display_matches_hook

Zrobiłem coś rozsądnego tutaj.


2
2017-09-14 05:34



Wszelkie pomysły na to, jak sprawić, by historia działała? - nccc
OK, dowiedziałem się. Trzeba wyświetlić rl_display_prompt, następnie rl_line_buffer i ustaw przesunięcie kursora na rl_point + strlen(rl_display_prompt). - nccc