Reputation: 15755
I am trying to get user input into python. However if a user uses a key such as [Home] or Ctrl+A or Ctrl+k (typical shell commands) they get a character representing that key rather than the expected behaviour.
I currently have:
data = input("Enter your data here: ").strip()
However if the user uses the Ctrl+A to go to beginning of line, they instead get a ^A
character printed on the screen as part of their input.
Is there a way for me to get input in a way that would allow the user to use bash key combos like Ctrl+A?
Upvotes: 2
Views: 156
Reputation: 365717
The short version is to just add import readline
to the top of your script, and it will magically work.
More specifically, the readline
library provides a wrapper around libreadline
, which is the same library that lets your bash
shell, or the Python interactive interpreter, for that matter, do fancy input editing.
So, you could use readline
directly. If you want to do anything fancy, you should read the docs, and also see rlcompleter
.
But for simple cases like this: by default, just importing readline
will (in effect) patch input
for you,* and that's all you need.
So, assuming the user (and his distro) are using default settings, they will be able to use the same emacs-style keystrokes they use in bash. (And, if they've changed the settings, presumably they want to be able to use those settings in your program, not just in bash.)
The only problem is that this only works if libreadline
was present when Python was built:
libedit
instead, which Apple includes.***cmd.exe
"DOS box", you automatically get DOS-style line editing, and can't get anything better... but fortunately, Windows users don't know what they're missing. :)* If you're wondering how it works under the covers, the code underlying input
is cleverly designed to be hooked by both readline
and IDLE, in a way that's flexible enough that you can even do nifty things like integrate it into an asyncio
event loop. So, readline
doesn't really patch input
; instead, it just registers a hook. Which is cool, and worth reading the source for, but it's not relevant to your question.
** And if it is, there's not much you can do about it except just install libreadline
and rebuild Python. On *BSD, I guess you could configure Python to build the OS X libedit
wrapper, but I don't know why you'd bother.
*** If you're using a pre-built Python from Apple or (until recently) python.org, you'll be using this workaround. Most apps and most users won't be affected by the difference, but there can be some annoyances with it. The way to force a solution to those annoyances is to depend on a newer version of readline
off PyPI, which will fail if your users haven't installed libreadline
.
Upvotes: 2