Использование GNU Readline; Как я могу добавить ncurses в той же программе? - PullRequest
21 голосов
/ 28 марта 2009

Название немного более конкретное, чем моя настоящая цель:

У меня есть программа командной строки, которая использует GNU Readline, в основном для истории команд (т.е. извлечения предыдущих команд с помощью стрелки вверх) и некоторых других тонкостей. Прямо сейчас выходные данные программы чередуются с пользовательским вводом, который иногда в порядке, но вывод асинхронный (он поступает через сетевое соединение в ответ на команды ввода), и это иногда раздражает (например, если строки выводятся, когда пользователь набирает новый ввод).

Я бы хотел добавить в эту программу функцию: отдельное «окно» для вывода. Я думал об использовании ncurses для этого. Но из ncurses FAQ видно, что две библиотеки нелегко использовать вместе.

Я мог бы рассмотреть возможность использования Editline или tecla вместо Readline, но мне не ясно, решит ли кто-нибудь из них мою проблему. Я также хотел бы рассмотреть возможность использования чего-то другого, кроме ncurses, включая библиотеку, которая предоставляет оба вида функциональных возможностей (окна текстового режима и историю команд), но я не знаю, что может быть лучше.

Да, и поддержка цветного текста может получить бонусные очки. Я подозреваю, что смогу сделать это с помощью Readline, так что, возможно, это отдельная задача, но если решение моей проблемы также позволяет добавить немного цвета к выводу, тем лучше.

Я использую Ubuntu Hardy (Linux 2.6).

Ответы [ 6 ]

9 голосов
/ 25 февраля 2015

Я сейчас собрал простой пример программы на GitHub: https://github.com/ulfalizer/readline-and-ncurses.

Он поддерживает плавное и эффективное изменение размера терминала и многобайтовые / комбинирующие / широкие символы. Код имеет полезные комментарии.

Снимок экрана ниже:

Screenshot of program combining ncurses and readline

6 голосов
/ 29 марта 2009

Я провел некоторые поиски, и, похоже, вам не повезло.

Для альтернатив ncurses есть SLang , Newt и Turbo Видение . Сленг - это гораздо больше, чем просто обработка экрана и, следовательно, больше сложный, но, может быть, он может быть использован для ваших целей? Тритон использует экран обработка и намного проще, но слишком простой и однопоточный режим для вашей цели я думаю.

Turbo vision - это графическая библиотека текстового режима от Borland, используемая все их инструменты в конце 80-х / начале 90-х годов. Borland выпустил источник код, когда рынок для такого рода вещи уменьшился, и есть теперь порт для Linux (примечание: этот проект , кажется, написал его собственная реализация Turbo Vision). Этот порт не мертв (там есть в этом году было несколько обновлений cvs, которые компилировались нормально (старые версии не сделал)), но ни один из телевизионных примеров, которые я нашел, не был современным, и я Я только собрал несколько из них, чтобы отказаться от остальных. Это немного стыдно, потому что телевидение было прекрасной средой для использования. Телевизор между прочим C ++ (и я предполагаю, что вы используете C?).

Для альтернативы readline есть libkinput , который, возможно, работает вместе с ncurses (он говорит, что может использовать terminfo ncurses. но я не уверен, означает ли это, что он может сосуществовать вместе с использованием ncurses)?

Возможно, один из вариантов - запустить readline "извне" для вашей программы ncurses. используя rlwrap ?

5 голосов
/ 18 февраля 2015

Это заставило меня удариться головой в течение нескольких часов, так что просто чтобы спасти людей, погуглив немного боли:

Если вы используете встроенный обработчик ncurses SIGWINCH с KEY_RESIZE, помните, что readline устанавливает переменные окружения LINES и COLUMNS по умолчанию. Они переопределяют любые вычисления динамического размера (обычно с ioctl() TIOCGWINSZ), которые иначе делала бы ncurses, что означает, что вы будете получать первоначальный размер терминала даже после изменения размера терминала.

Этого можно избежать, установив rl_change_environment в 0 перед инициализацией readline.

Обновление:

Вот некоторая дополнительная информация, которую я почерпнул из источников readline:

код обработки SIGWINCH readline (который используется, если rl_catch_sigwinch равен 1) действительно обновляет LINES и COLUMNS, что, по-видимому, должно быть достаточно для ncurses. Однако при использовании альтернативного интерфейса readline (что наиболее целесообразно при сочетании readline с ncurses), обработчики сигналов (в том числе для SIGWINCH) будут устанавливаться только на время каждого вызова rl_callback_read_char(), что означает изменение размера любого терминала между двумя вызовами на rl_callback_read_char() не будет видно readline.

3 голосов
/ 06 мая 2013

Получается, что GDB использует readline и ncurses. Если вы заинтересованы в этом, я рекомендую вам проверить их реализацию: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c

3 голосов
/ 09 июня 2010

Я достиг того, что вы описали в моей программе:

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

Ниже приведена обработка файла io:

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

2 голосов
/ 14 сентября 2012

Я не уверен, какую версию вы пробовали. На сегодняшний день (2012.09.14) Это очень просто, нам просто нужно привязать нашу пользовательскую функцию к указателям на следующие функции.

rl_getch_function
rl_redisplay_function
rl_completion_display_matches_hook

Я сделал что-то разумное здесь .

...