Подтвердить что ты не робот

Использование GNU Readline; как я могу добавить ncurses в ту же программу?

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

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

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

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

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

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

4b9b3361

Ответ 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.

Ответ 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

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