Support readline or equivalent alternatives
achimnol opened this issue ยท 9 comments
Googling leads me to this SO question but there is no reply yet.
Python already provides a binding module to GNU readline or libedit, but this does not work together with aioconsole since it does not have coroutine-based interfaces. Maybe we need a new lower-level wrapper for the readline library.
This issue is both question and feature request:
- Is there any plan to support readline or readline-style interactive prompts?
- Are there any known/fundamental technical issues related to supporting readline (except that the stdlib readline does not have coroutines)?
- Could we just make the user prompt to be synchronous while leaving user codes running between prompts asynchronous?
I don't know much about readline, but will supporting it allow us to use left/right arrow keys in the prompts?
@achimnol Thank you for creating an issue, this is very interesting.
I'm not knowledgeable enough about readline
to answer all your questions, I'll have to start an investigation. What I can tell you though is that aioconsole
aims at providing an asynchronous interface to arbitrary stdin/stdout
, with methods similar to the Stream API.
Meaning those streams can either come from:
- the console (standard unix streams)
- an application like IDLE (or Windows, FWIW)
- a TCP socket (for serving python prompts over the network)
As @dufferzafar pointed out, it would nice to have support of left/right arrow keys for all those use cases, but I have no idea whether this is doable yet. It would also be worth looking into prompt_toolkit as well, since it has asyncio support.
Any help is more than welcome by the way ๐
Yeah, I recently had to build an asyncio based CLI and found out that prompt_toolkit has support for it. I think that is our best bet to create an awesome async-cli.
Haven't looked into the specifics yet, but will definitely post anything I learn here.
I tried to add support for readline with low-level, callback-based readline API, but it segfaults mysteriously in the callback. I might investigate further, but this will surely only support read from terminal.
If you connect via TCP, you can just use socat readline tcp:host:port
to have basic readline support.
@lilydjwg How does the socat option work? I ran the echo example and I can connect fine w/ nc but when I try to say socat readline anything, I just get an error (using the latest version of socat):
socat readline tcp:127.0.0.1:9999
2017/10/27 11:21:45 socat[603] E unknown device/address "readline"
@TD22057 There seems to be a problem with socat and readline.
Instead you can use rlwrap:
# Works with local apython console
$ rlwrap apython
# Also works with a remote console
$ apython --serve locahost:8888
The console is being served on 127.0.0.1:8888
# with both netcat and socat
$ rlwrap nc localhost 8888
$ rlwrap socat - tcp:localhost 8888
I actually didn't know about rlwrap
and it seems to be a valid solution for remote consoles, and an acceptable workaround for local consoles. I'll update the documentation.
Thanks for your post.
rlwrap works perfectly and is exactly what I need for my application. Thanks for this very cool project.
Hi all,
I just implemented readline support (PR #9) for local console through the apython
script. It seems to work fine and it even provides some level of auto-completion (only for the built-ins).
The implementation is hackish but contained, and can even be disabled using the --no-readline
argument. It works by starting the actual program in a subprocess and controlling the standard streams in order to take advantage of the readline support provided by the input
built-in.
Feel free to review the PR if you're interested. Otherwise, I'll probably merge it next week (or not, if I change my mind and finally consider it's too hackish :) ).
Thanks for your inputs!