使用GNU Readline;如何在同一个程序中添加ncurses?

时间:2009-03-27 22:11:35

标签: readline ncurses editline

标题比我的实际目标更具体:

我有一个使用GNU Readline的命令行程序,主要用于命令历史记录(即使用向上箭头检索以前的命令)和其他一些细节。现在,程序的输出中间散布着用户的输入,有时候输出是正常的,但输出是异步的(它是通过网络连接来响应输入命令),有时会变得烦人(例如,如果用户输出行时)正在输入新的输入。)

我想为此程序添加一个功能:输出的单独“窗口”。我想过为此使用ncurses。但是从ncurses FAQ看来,这两个库并不容易一起使用。

我可能会考虑使用Editlinetecla而不是Readline,但我不清楚其中任何一个是否能解决我的问题。我还考虑使用除ncurses之外的其他东西,包括提供两种功能的库(文本模式窗口和命令历史记录),但我不知道什么是最好的。

哦,支持彩色文字可能会得到奖励积分。我怀疑我可以用Readline做到这一点,所以也许这是一个单独的问题,但如果我的问题的解决方案也可以很容易地为输出添加一点颜色,那就更好了。

我正在使用Ubuntu Hardy(Linux 2.6)。

6 个答案:

答案 0 :(得分:9)

我现在在GitHub上组合了一个简单的示例程序:https://github.com/ulfalizer/readline-and-ncurses

它支持无缝和高效的终端大小调整和多字节/组合/宽字符。该代码提供了有用的评论。

下面的截图:

Screenshot of program combining ncurses and readline

答案 1 :(得分:6)

我做了一些搜索,看起来你运气不好。

对于ncurses备选方案,有SLangNewtTurbo Vision。俚语不仅仅是屏幕处理,因此更多 复杂,但也许它可以用于你的目的?纽特使用屏幕 处理和更简单,但太简单和单线程模式 为了你的目的,我想。

Turbo vision是来自Borland的文本模式图形库,用于 他们所有的工具都在80年代末/ 90年代初期。 Borland发布了消息来源 代码当这种东西的市场减少,并且有 现在是linux的一个端口(旁注,this project似乎已经写好了 它自己的涡轮增压视觉实施)。那个港口没有死(有了 今年有一些cvs更新编译得很好(旧版本 没有)),但我发现的电视例子都不是我最新的 在放弃休息之前,他们只做了一些编译。 这有点遗憾,因为电视是一个可爱的环境。 TV是btw C ++(我假设你使用C?)。

对于readline的替代方法,有libkinput,这可能有效 和ncurses一起(它说它可以使用ncurses的terminfo。但我是 不确定这是否意味着它可以与ncurses一起使用共存)?

也许一个选项是在你的ncurses程序中“外部”运行readline 使用rlwrap

答案 2 :(得分:5)

这让我头疼了几个小时,所以只是为了拯救人们用谷歌搜索一些痛苦:

如果你在SIGWINCH使用ncurses的内置KEY_RESIZE处理程序,请注意,readline默认设置LINESCOLUMNS个环境变量。这些覆盖了ncurses否则会执行的任何动态大小计算(通常使用ioctl() TIOCGWINSZ),这意味着即使在调整终端大小后,您也将继续获得初始终端大小。

可以通过在初始化readline之前将rl_change_environment设置为0来阻止这种情况。

<强>更新

以下是我从readline来源收集到的一些其他信息:

readline的SIGWINCH处理代码(如果rl_catch_sigwinch为1时使用)会更新LINESCOLUMNS,这似乎对ncurses来说已经足够了。但是,当使用备用readline接口(在将readline与ncurses组合时最有意义)时,信号处理程序(包括SIGWINCH的信号处理程序)将仅在每次rl_callback_read_char()调用期间安装,意味着任何终端在两次调用rl_callback_read_char()之间调整大小都不会被readline看到。

答案 3 :(得分:3)

我已经实现了你在我的程序中所描述的内容:

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

以下是文件处理io:

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

答案 4 :(得分:3)

事实证明,gdb同时使用readline和ncurses。如果您对此感兴趣,我建议您查看其实施情况:http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c

答案 5 :(得分:2)

我不确定你试过哪个版本。截至今天(2012.09.14)它非常简单,我们只需要将自定义函数挂钩到以下函数指针。

rl_getch_function
rl_redisplay_function
rl_completion_display_matches_hook

我做了一些合理的here