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

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

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

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

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

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

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

Я сделал несколько поисков, и кажется, что вам не повезло.

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

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

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

Возможно, один из вариантов – запустить readline «извне» в вашу программу ncurses с помощью rlwrap ?

Теперь я собрал простую примерную программу на GitHub: https://github.com/ulfalizer/readline-and-ncurses .

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

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

Скриншот программы, сочетающей ncurses и readline

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

Если вы используете обработчик SIGWINCH ncurses с KEY_RESIZE , KEY_RESIZE , что readline устанавливает значения COLUMNS среды 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.

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

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

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

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

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

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

 rl_getch_function
 rl_redisplay_function
 rl_completion_display_matches_hook

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

Interesting Posts

Почему мне когда-либо понадобится использовать вложенные classы C #

MonoDroid: ошибка при вызове конструктора пользовательского представления – TwoDScrollView

Кластерный анализ в R: определение оптимального количества кластеров

Скопировать файл на общий сетевой диск

андроидный fragment. Как сохранить состояния представлений в fragmentе, когда другой fragment нажат поверх него

Сохранить изображение в папку документов приложений из UIView на IOS

Какие события DOM доступны для WebKit на Android?

Возвращать имена файлов в реестре в командной строке

Удалить значок / логотип из панели действий на Android

Драйвер принтера Nt4.0 не совместим с Vista?

Как добавить поддержку колесика мыши к компоненту, сгенерированному из TGraphicControl?

Автоматически изменять размер изображения / изображения в Word?

Entity Framework 4 CTP 4 / CTP 5 Общий шаблон хранилища и единица тестирования

DisplayFormat ApplyFormatInEditMode

Подмножество кадра данных между двумя датами

Давайте будем гением компьютера.