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

发布于 2024-07-16 03:41:24 字数 791 浏览 6 评论 0原文

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

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

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

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

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

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

The title is a bit more specific than my actual goal:

I have a command-line program which uses GNU Readline, primarily for command history (i.e. retrieving previous commands using up-arrow) and some other niceties. Right now the program's output appears interspersed with the user's input, which sometimes is OK but the output is asynchronous (it comes via a network connection in response to the input commands), and that gets annoying sometimes (e.g. if lines are output when the user is typing new input).

I'd like to add a feature to this program: a separate "window" for the output. I thought about using ncurses for this. But it appears from the ncurses FAQ that the two libraries are not easy to use together.

I might consider using Editline or tecla instead of Readline, but it's not clear to me if either of those will solve my problem. I'd also consider using something other than ncurses, including a library which provides both kinds of functionality (text-mode windows and command history), but I don't know what might be best.

Oh, and support for colored text might get bonus points. I suspect I may be able to do that with Readline, so maybe it's a separate concern, but if a solution to my problem also makes it easy to add a bit of color to the output, so much the better.

I'm using Ubuntu Hardy (Linux 2.6).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

淡忘如思 2024-07-23 03:41:24

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

它支持无缝且高效的终端大小调整和多字节/组合/宽字符。 该代码有有用的注释。

截图如下:

ncurses 和 readline 结合的程序截图

I've now put together a simple example program on GitHub: https://github.com/ulfalizer/readline-and-ncurses.

It supports seamless and efficient terminal resizing and multibyte/combining/wide characters. The code has helpful comments.

Screenshot below:

Screenshot of program combining ncurses and readline

萌逼全场 2024-07-23 03:41:24

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

对于 ncurses 替代品,有 SLangNewtTurbo
愿景
。 俚语不仅仅是屏幕处理,因此更多
复杂,但也许它可以用于您的目的? 纽特使用屏幕
处理起来也简单很多,但是太简单而且是单线程模式
我认为是为了你的目的。

Turbo Vision 是 Borland 的文本模式图形库,由
他们所有的工具都是 80 年代末/90 年代初的。 Borland 发布了源码
当这类东西的市场减少时,就需要编写代码,并且有
现在是 Linux 的端口(旁注,这个项目似乎已经写了
它自己的涡轮视觉实现)。 该端口并没有死(有
今年有一些 cvs 更新,编译得很好(旧版本
没有)),但我发现的电视示例都不是最新的,我
在放弃其余部分之前,我只编译了其中的一些。
这有点遗憾,因为电视是一个很好的使用环境。
顺便说一句,电视是 C++ 的(我假设你正在使用 C?)。

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

也许一种选择是在 ncurses 程序“外部”运行 readline
使用rlwrap

I have done some searching, and it seems like you are out of luck.

For ncurses alternatives there are SLang, Newt and Turbo
Vision
. Slang is much more than just screen handling and thus more
complex, but maybe it can be used for your purpose?. Newt uses the screen
handling and is much simpler, but too simple and single-threaded-mode
for your purpose I think.

Turbo vision is the text mode graphics library from Borland, used by
all their tools in the late 80s/early 90s. Borland released the source
code when the market for that kind of thing diminished, and there is
now a port for linux (side note, this project seems to have written
its own turbo vision implementation). That port is not dead (there have
been some cvs updates this year which compiled fine (the older releases
did not)), but none of the TV examples I found were up to date and I
did only got a few of them to compile before giving up on the rest.
This is a bit of a shame, because TV was a lovely environment to use.
TV is btw C++ (and I assume you are using C?).

For an alternative to readline, there is libkinput, which maybe works
together with ncurses (it says it can use ncurses' terminfo. but I am
not sure if that means that it can co-exists together with ncurses usage)?

Maybe one option is to run readline "externally" to your ncurses program
using rlwrap?

溺深海 2024-07-23 03:41:24

这让我敲了几个小时的头,所以只是为了避免人们在谷歌上搜索一些痛苦:

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

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

更新:

以下是我从 readline 源中收集到的一些附加信息:

readline 的 SIGWINCH 处理代码(如果 rl_catch_sigwinch 为 1,则使用该代码)确实会更新 < code>LINES 和 COLUMNS,这对于 ncurses 来说似乎应该足够了。 然而,当使用备用 readline 接口时(这在将 readline 与 ncurses 结合使用时最有意义),信号处理程序(包括用于 SIGWINCH 的信号处理程序)将仅在每个 rl_callback_read_char 的持续时间内安装() 调用,这意味着 readline 不会看到两次调用 rl_callback_read_char() 之间的任何终端大小调整。

This had me banging my head for a few hours, so just to save people Googling some pain:

If you're using ncurses' builtin SIGWINCH handler with KEY_RESIZE, be aware that readline sets the LINES and COLUMNS environment variables by default. These override any dynamic size calculation (usually with ioctl() TIOCGWINSZ) that ncurses would otherwise do, meaning you'll keep getting the initial terminal size even after resizing the terminal.

This can be prevented by setting rl_change_environment to 0 before initializing readline.

Update:

Here's some additional information I gleaned from the readline sources:

readline's SIGWINCH handling code (which is used if rl_catch_sigwinch is 1) does update LINES and COLUMNS, which seems like it should be sufficient for ncurses. However, when using the alternate readline interface (which makes most sense when combining readline with ncurses), the signal handlers (including the one for SIGWINCH) will only be installed for the duration of each rl_callback_read_char() call, meaning any terminal resize between two calls to rl_callback_read_char() will not be seen by readline.

℡Ms空城旧梦 2024-07-23 03:41:24

原来gdb同时使用了readline和ncurses。 如果您有兴趣这样做,我建议您查看他们的实现: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c

So it turns out that gdb uses both readline and ncurses. If you're interested in doing this, I recommend that you check out their implementation: http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.c

小耗子 2024-07-23 03:41:24

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

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

以下是处理 io 的文件:

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

I've achieved what you've described in a program of mine:

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

The following is the file handling io:

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

鼻尖触碰 2024-07-23 03:41:24

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

rl_getch_function
rl_redisplay_function
rl_completion_display_matches_hook

在这里做了一些合理的事情。

I'm not sure which version you tried. As of today(2012.09.14) It is very simple, We just need to hook our custom function to following function pointers.

rl_getch_function
rl_redisplay_function
rl_completion_display_matches_hook

I did something reasonable here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文