Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage with an external event loop #15

Closed
mox-mox opened this issue Dec 9, 2017 · 4 comments
Closed

Usage with an external event loop #15

mox-mox opened this issue Dec 9, 2017 · 4 comments

Comments

@mox-mox
Copy link

mox-mox commented Dec 9, 2017

I am looking for a line editing library that I can use together with an event loop. That means no blocking readline function and no direct access to stdin.
Instead, I would call readline() with one or more the user pressed, readline should process these keys and return.
Is this possible with editline, or if not, could you give an estimate on how much work it would be to implement something like this?

@troglobit
Copy link
Owner

Funny, I'm actually working on exactly that right at this very moment! 😎

The interface is almost working and follows that of the GNU Readline API.

Please stand by, will have something for your to test within a couple of days.

@troglobit
Copy link
Owner

There, please try it out if you have the chance.

@mox-mox
Copy link
Author

mox-mox commented Dec 11, 2017

After reading the code, it seems to me that editline expects the user input to still be available in the stdin buffer.
Libuv will get available data and store it into its own buffer which gets passed to the callback.

void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)

If I set the terminal to UV_TTY_MODE_RAW, my callback will be called on every keypress (unless some other callback takes a while to complete and a user manages to press multiple keys in that time).
I might be able to ungetch() all that buffer, but I'm pretty sure this it not a sensible approach.

So is there some way to have the readline() function take a buffer that contains the key presses, process those keypresses and return wether the line is complete (aka we should interpret the line) if it is still waiting for more input?

@troglobit
Copy link
Owner

I've never used libuv, only libev, libevent and my own libuev, so I cannot give any insight in how to integrate them. However, in addition to the standard GNU readline() "alternate interface" implementation, there are a few other tricks you can use:

  • override the rl_getc_function, it is called by tty_get() when reading a character
  • override rl_instream, or patch rl_initialize()

The alternate interface requires that you call rl_callback_read_char() whenever your event loop alerts you of there being something to read. So if you create a "spoon feeder" function from that Libuev buffer and hook it to rl_getc_function you should be set.

Good Luck! 😃

troglobit added a commit that referenced this issue Mar 24, 2018
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants