Использование GNU Readline; как я могу добавить ncurses в ту же программу?
Название немного более конкретное, чем моя фактическая цель:
У меня есть программа командной строки, которая использует GNU Readline, прежде всего для истории команд (т.е. для извлечения предыдущих команд с использованием стрелки вверх) и некоторых других тонкостей. Прямо сейчас выход программы появляется в чередовании с пользовательским входом, который иногда является ОК, но выход асинхронен (он поступает через сетевое соединение в ответ на команды ввода), и иногда это раздражает (например, если строки выводятся, когда пользователь вводит новый ввод).
Я хотел бы добавить функцию к этой программе: отдельное "окно" для вывода. Я думал об использовании ncurses для этого. Но из ncurses FAQ видно, что две библиотеки не просто использовать вместе.
Я мог бы использовать Editline или tecla вместо Readline, но мне непонятно, сможет ли кто-нибудь из них решить мою проблему. Я бы также подумал об использовании чего-то другого, кроме ncurses, включая библиотеку, которая обеспечивает обе функции (окна текстового режима и историю команд), но я не знаю, что может быть лучше.
О, и поддержка цветного текста может получить бонусные очки. Я подозреваю, что смогу сделать это с помощью Readline, поэтому, возможно, это отдельная проблема, но если решение моей проблемы также упростит добавление немного цвета к выходу, тем лучше.
Я использую Ubuntu Hardy (Linux 2.6).
Ответы
Ответ 1
Я сделал несколько поисков, и кажется, что вам не повезло.
Для альтернатив ncurses есть SLang, Newt и Turbo
Видение. Сленг - это гораздо больше, чем просто обработка экрана и, следовательно, больше
сложный, но, возможно, он может быть использован для вашей цели?. Ньют использует экран
и намного проще, но слишком простой и однопоточный режим
для вашей цели я думаю.
Turbo vision - это графическая библиотека текстового режима от Borland, используемая
все их инструменты в конце 80-х - начале 90-х годов. Borland выпустил источник
когда рынок для такого рода вещей уменьшился, и есть
теперь порт для linux (примечание стороны, этот проект, похоже, написал
его собственная реализация турбовидения). Этот порт не мертв (есть
были некоторые обновления cvs в этом году, которые были скомпилированы (старые версии
не было)), но ни один из примеров, которые я нашел, не был обновлен, и я
лишь немногие из них собрались, чтобы отказаться от остальных.
Это немного позор, потому что телевидение было прекрасной средой для использования.
TV есть btw С++ (и я предполагаю, что вы используете C?).
Для альтернативы readline существует libkinput, что, возможно, работает
вместе с ncurses (он говорит, что может использовать terminfo для ncurses, но я
не уверен, что это означает, что он может сосуществовать вместе с использованием ncurses)?
Возможно, одним из вариантов является запуск readline "извне" в вашу программу ncurses
используя rlwrap?
Ответ 2
Теперь я собрал простую примерную программу на GitHub: https://github.com/ulfalizer/readline-and-ncurses.
Он поддерживает бесшовное и эффективное изменение размеров терминалов и многобайтовые/комбинированные/широкие символы. Код содержит полезные комментарии.
Снимок экрана ниже:
![Screenshot of program combining ncurses and readline]()
Ответ 3
Это заставило меня постукивать головой в течение нескольких часов, так что просто чтобы спасти людей, Гуглинг немного боли:
Если вы используете обработчик ncurses builtin SIGWINCH
с KEY_RESIZE
, имейте в виду, что readline устанавливает переменные среды LINES
и COLUMNS
по умолчанию. Они переопределяют любые вычисления динамического размера (обычно с ioctl()
TIOCGWINSZ
), которые в противном случае выполнялись бы ncurses, что означает, что вы будете получать начальный размер терминала даже после изменения размера терминала.
Это можно предотвратить, установив rl_change_environment
в 0
перед инициализацией readline.
Update:
Вот некоторая дополнительная информация, которую я почерпнул из источников readline:
readline SIGWINCH
код обработки (который используется, если rl_catch_sigwinch
равен 1) обновляет LINES
и COLUMNS
, что, похоже, должно быть достаточным для ncurses. Однако при использовании альтернативного интерфейса readline (что имеет смысл при объединении readline с ncurses), обработчики сигналов (включая один для SIGWINCH
) будут установлены только на время каждого вызова rl_callback_read_char()
, что означает, что любой размер терминала между двумя вызовами rl_callback_read_char()
не будет видно по readline.
Ответ 4
Я достиг того, что вы описали в моей программе:
http://dpc.ucore.info/lab:xmppconsole
Ниже приведена обработка файлов io:
http://github.com/dpc/xmppconsole/blob/master/src/io.c
Ответ 5
Итак, получается, что gdb использует как readline, так и ncurses. Если вы заинтересованы в этом, я рекомендую вам проверить их реализацию: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c
Ответ 6
Я не уверен, какую версию вы попробовали. На сегодняшний день (2012.09.14) Это очень просто, нам просто нужно подключить нашу пользовательскую функцию к следующим указателям на функции.
rl_getch_function
rl_redisplay_function
rl_completion_display_matches_hook
Я сделал что-то разумное здесь.