(I'm talking about Python 3 input, previously known as raw_input.) I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this: input("What is the fish of the day? ", "trout a la creme") and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI. Under Linux, with readline, I can implement this relatively simply: _input = input def input(prompt, initial=''): readline.set_startup_hook(lambda: readline.insert_text(initial)) try: return _input(prompt) finally: readline.set_startup_hook(None) Aside: I'm a bit concerned about unconditionally setting the startup hook to None, rather than restoring whatever it was before I messed with it. But I see no way to save the startup hood from Python code. However this doesn't work under Windows, or any other system where readline is not available. Does anyone else think this would be a useful feature? I see a few questions about this in various places, such as StackOverflow: http://stackoverflow.com/questions/5403138/how-to-set-a-default-string-for-r... but I don't see that it has ever been requested on the bug tracker. Is it practical to include an editable initial value on systems without readline? If a platform-independent version is not practical, I don't think there's any point in only half-supporting it. -- Steven
On Tue, Apr 1, 2014 at 10:58 PM, Steven D'Aprano
I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this:
input("What is the fish of the day? ", "trout a la creme")
and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI.
Is it practical to include an editable initial value on systems without readline? If a platform-independent version is not practical, I don't think there's any point in only half-supporting it.
You could fudge it on a non-readline system by rewriting the prompt and turning blank into the default: _input = input def input(prompt, initial=''): if not initial: return _input(prompt) return _input("%s[%s] "%(prompt, initial)) or initial That's not the same as an *editable* initial value, but it's a visible default, which is a useful feature. However, the convention is usually to put the square brackets before the punctuation: What is the fish of the day [trout a la creme]? so it might be better to make something more sophisticated that recognizes question marks and colons and shifts the default marker before them. Sounds like a reasonable feature, to me. I've no idea about libedit, which is the most common non-readline system that has real editing; you might need to have several options and then a final fall-back that looks like the above, but it should be possible. How common is the square-brackets-means-default convention? Would, for instance, a Windows-only user understand it? ChrisA
On Tue, Apr 01, 2014 at 11:11:47PM +1100, Chris Angelico wrote:
On Tue, Apr 1, 2014 at 10:58 PM, Steven D'Aprano
wrote: I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this:
input("What is the fish of the day? ", "trout a la creme")
and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI. ....^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:-)
You could fudge it on a non-readline system by rewriting the prompt and turning blank into the default:
Yes, I have work-arounds. They aren't what you call elegant. Your suggestion, to wrap the default in square brackets: What is the fish of the day? [trout a la creme] requires the user to know that pressing Enter will return "trout a la creme", rather than it meaning that "trout a la creme" is optional, which is another common meaning for square brackets. That's actually what I do, except I prefer < > angle brackets. It also doesn't help them if they want to enter "trout a la creme with salad". Any change at all, even a single character, means that they have to type the entire string from scratch. Not user-friendly at all. Anyway, I'm not looking for work-arounds. I know how to program work-arounds :-) I'm asking if this is likely to be both practical and useful enough to be worth making an enhancement request.
Sounds like a reasonable feature, to me. I've no idea about libedit, which is the most common non-readline system that has real editing; you might need to have several options and then a final fall-back that looks like the above, but it should be possible.
libedit is, at least theoretically, identical in functionality to readline, only with different syntax. If the platform that Python is running on has no readline/libedit (which means Windows), or if the person building Python from source disables readline/libedit, the only editing tool which is available is Good Old Backspace. But that's better than nothing. I'm not asking for input() to duplicate all of readline, just to start with an optional initial value in the edit buffer. -- Steven
On Wed, Apr 2, 2014 at 12:01 AM, Steven D'Aprano
On Tue, Apr 01, 2014 at 11:11:47PM +1100, Chris Angelico wrote:
On Tue, Apr 1, 2014 at 10:58 PM, Steven D'Aprano
wrote: I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this:
input("What is the fish of the day? ", "trout a la creme")
and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI. ....^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:-)
Anyway, I'm not looking for work-arounds. I know how to program work-arounds :-) I'm asking if this is likely to be both practical and useful enough to be worth making an enhancement request.
Well, your subject line does say "default", which is a concept that can be rendered. "Editable default" is a much bigger feature, and requires actual editing keys. It would make a small amount of sense to have redirected input able to use defaults by having blank lines in the input.
Sounds like a reasonable feature, to me. I've no idea about libedit, which is the most common non-readline system that has real editing; you might need to have several options and then a final fall-back that looks like the above, but it should be possible.
libedit is, at least theoretically, identical in functionality to readline, only with different syntax.
If the platform that Python is running on has no readline/libedit (which means Windows), or if the person building Python from source disables readline/libedit, the only editing tool which is available is Good Old Backspace. But that's better than nothing. I'm not asking for input() to duplicate all of readline, just to start with an optional initial value in the edit buffer.
So what I'd see, then, is that your function would need three, maybe four, options: 1) Do we have readline? If so, do what you said up top. 2) Do we have libedit? If so, do the same thing with different syntax. 3) Can we pre-fill the input field? If so, do. 4) Put the default in brackets (square or angle) and translate blank into that. (Maybe say "Prompt? [blank=default] " for a bit more clarity.) If the third option is guaranteed as part of the implementation, then (obviously) the fourth isn't needed. This sounds like an excellent little feature. Burying that complexity away inside input() would help enormously with cross-platform usability; having the third and maybe fourth options there would mean that a programmer who uses readline on Linux can still be confident that his program will work, if a bit more clunkily, on Windows. I'm not offering this as a work-around but as a fall-back; answering your initial concern about platform-independence. Python is very good at hiding platform-specific details (import subprocess and don't concern yourself with CreateProcess() vs fork()/exec(), etc etc); abstracting away the difference between a really nice readline implementation and a messy-but-workable pure prompt implementation gives your program graceful degradation with a very simple notation (just add another arg to input()). ChrisA
On 1 April 2014 14:01, Steven D'Aprano
If the platform that Python is running on has no readline/libedit (which means Windows), or if the person building Python from source disables readline/libedit, the only editing tool which is available is Good Old Backspace. But that's better than nothing. I'm not asking for input() to duplicate all of readline, just to start with an optional initial value in the edit buffer.
Windows has much richer line editing capabilities than "plain old backspace" - sufficiently so that I end up very frustrated when working on Unix programs that don't have readline support, because they are *so* limited (no arrow keys? seriously?). Ignoring that point, though, pre-filled edit buffers are *extremely* uncommon on Windows, and I would imagine them being very surprising to a user. I'm not sure I've ever seen them on Unix either, though, so maybe the target audience for this has specialised or unusual expectations? Personally, I'm used to (and comfortable with) the "Enter a value [12]: " convention where this means that pressing enter without providing a value gives 12 (and I'd just implement that manually with if val='': val = '12'). I'm not sure how easy it would be to implement for Windows. I've never needed it, so I've never looked into it. -1 on it being a builtin capability of input(). -0 on it being a separate builtin or stdlib function (mainly because I don't think it's needed often enough to be worth it). It seems to me it'd be fine as a package on PyPI, or maybe a recipe. Paul.
On Tue, Apr 01, 2014 at 03:21:40PM +0100, Paul Moore wrote:
Windows has much richer line editing capabilities than "plain old backspace" - sufficiently so that I end up very frustrated when working on Unix programs that don't have readline support, because they are *so* limited (no arrow keys? seriously?).
Sorry, I didn't intend to put down the Windows editing experience, it's not something I've had much experience with in Python. And you are right, Python on Linux without readline support is *painful*.
Ignoring that point, though, pre-filled edit buffers are *extremely* uncommon on Windows, and I would imagine them being very surprising to a user. I'm not sure I've ever seen them on Unix either,
Pre-filled buffers are quite common in curses applications like the mail-client mutt or the editor nano. I'm hoping for something lightweight and cross-platform, which rules out curses.
though, so maybe the target audience for this has specialised or unusual expectations?
Well, yes, they would be users of console apps who expect user *friendly* text interfaces instead of the user-hostile ones most developers write *wink*
Personally, I'm used to (and comfortable with) the "Enter a value [12]: " convention where this means that pressing enter without providing a value gives 12 (and I'd just implement that manually with if val='': val = '12').
That's fine for the typical "[Y]/n" one letter inputs that are extremely common, and I don't have a problem with that. But for longer text, the inability to modify the default except by retyping the entire thing is a pretty major failure of the user interface. Imagine if the only way to get a default value in your GUI or web app's edit field was to put a label next to it: Leave the field blank to accept "Something" as the default. Type a thing here: _______________________________ I wouldn't accept that in my GUI apps, and I don't think that it's acceptable in console apps either.
I'm not sure how easy it would be to implement for Windows. I've never needed it, so I've never looked into it.
-1 on it being a builtin capability of input(). -0 on it being a separate builtin or stdlib function (mainly because I don't think it's needed often enough to be worth it). It seems to me it'd be fine as a package on PyPI, or maybe a recipe.
I obviously don't agree with you, but I appreciate the comments. Regardless of what happens in 3.5, I'll look at putting something up on PyPI, although chances are it will require readline support and won't be platform-independent. That will limit its use drastically. -- Steven
On Tue, Apr 1, 2014 at 9:16 AM, Steven D'Aprano
Leave the field blank to accept "Something" as the default. Type a thing here: _______________________________
I wouldn't accept that in my GUI apps, and I don't think that it's acceptable in console apps either.
Ah, but that's the difference. In GUI apps it's the standard approach (although it's amazing how many GUI apps tend to get edge cases wrong, and it doesn't combine well with the new trend to put dimmed "hint" text in the box instead). But in console apps it's *not* common, except perhaps in certain curses-based apps (which really are trying to emulate GUI apps using an older paradigm). I think it's fine for people to figure out how to do this using the available tools (e.g readline) and experiment. I don't think the idea is anywhere near the bar of adding to the stdlib. -- --Guido van Rossum (python.org/~guido)
On 1 April 2014 17:16, Steven D'Aprano
-1 on it being a builtin capability of input(). -0 on it being a separate builtin or stdlib function (mainly because I don't think it's needed often enough to be worth it). It seems to me it'd be fine as a package on PyPI, or maybe a recipe.
I obviously don't agree with you, but I appreciate the comments. Regardless of what happens in 3.5, I'll look at putting something up on PyPI, although chances are it will require readline support and won't be platform-independent. That will limit its use drastically.
Having a better idea of your use case (lighter-weight version of a curses-style interface) I can see why it would be useful. Although I didn't think anyone still write text-based UIs ;-) With that in mind, and *particularly* since the curses module is not supported on Windows, I'm persuaded that it's a useful idea (to have available *somewhere*). But probably only if it's cross-platform, and even then I'd wouldn't expect it to be part of the built in input(). After all getpass is an even more common requirement for user input, and *that* didn't warrant being built into input :-) Paul
01.04.14 17:21, Paul Moore написав(ла):
-1 on it being a builtin capability of input(). -0 on it being a separate builtin or stdlib function (mainly because I don't think it's needed often enough to be worth it). It seems to me it'd be fine as a package on PyPI, or maybe a recipe.
Seconded.
On Wed, 2 Apr 2014 00:01:47 +1100
Steven D'Aprano
Yes, I have work-arounds. They aren't what you call elegant. Your suggestion, to wrap the default in square brackets:
What is the fish of the day? [trout a la creme]
For the record, I would spell it "trout à la crème" or rather "truite à la crème". (you might also want to add some shallots, or perhaps they are implied :-)) cheers Antoine.
On Tue, Apr 1, 2014, at 7:58, Steven D'Aprano wrote:
However this doesn't work under Windows, or any other system where readline is not available.
It is possible, though awkward, to pre-populate the input buffer on Windows using WriteConsoleInput. There's probably a million other things that are higher priority to do with the windows console before this, though (starting with unicode support).
On 01/04/2014 12:58, Steven D'Aprano wrote:
However this doesn't work under Windows, or any other system where readline is not available.
Is pyreadline an option for you? Anything you could borrow from iPython or similar? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com
On 04/01/2014 07:58 AM, Steven D'Aprano wrote:
(I'm talking about Python 3 input, previously known as raw_input.)
I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this:
input("What is the fish of the day? ", "trout a la creme")
and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI.
Under Linux, with readline, I can implement this relatively simply:
One of the things I first looked for when learning python was a get_key_press function. Line input (or whole file input) is great for files, and can make reading data much faster than single character input. But for user input, single char input can be useful. If we could read the keyboard directly with a get_key_press function, then your request along with making curses cross platform, may be fairly easy to do. (The cross platform get_key_press function is the hard part.) Cheers, Ron
On 2 April 2014 02:45, Ron Adam
If we could read the keyboard directly with a get_key_press function, then your request along with making curses cross platform, may be fairly easy to do.
If the aim is cross-platform rich(er) console applications, wouldn't supporting curses on all environments be the easiest answer? AFAIK, there are curses ports for Windows, and it's native to all other platforms Python supports - so just shipping something like pdcurses in the Windows installer would do the trick. Or am I missing some fundamental reason why curses doesn't cover what's needed (and more)? Paul
On Apr 3, 2014, at 6:52, Paul Moore
If the aim is cross-platform rich(er) console applications, wouldn't supporting curses on all environments be the easiest answer? AFAIK, there are curses ports for Windows, and it's native to all other platforms Python supports - so just shipping something like pdcurses in the Windows installer would do the trick. Or am I missing some fundamental reason why curses doesn't cover what's needed (and more)?
First, is pdcurses still a live/working project? Does it work with Python's curses module? If so, that might be worth doing entirely independent of whether it covers what's needed for this thread. I suspect the main argument against it is that there are so few people writing curses apps in Python who care about Windows that nobody's bothered to even ask for it, much less do it. Meanwhile, if you go back to the start of this thread, really he wants normal terminal I/O with readline-like input or the platform's normal equivalent, except that he can pre-fill the input buffer. I think that would be a lot more work with curses than with readline. The question is whether there's a way to do it cross-platform, e.g., with cmd.exe line-editing. If so, that's probably easier than using curses. If not, then curses is certainly better than there being no way to do it, or than emulating line editing from scratch on top of console I/O and/or control sequences.
From: Ron Adam
On 04/01/2014 07:58 AM, Steven D'Aprano wrote:
I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this:
input("What is the fish of the day? ", "trout a la creme")
and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI.
Under Linux, with readline, I can implement this relatively simply:
One of the things I first looked for when learning python was a get_key_press function.
Line input (or whole file input) is great for files, and can make reading data much faster than single character input. But for user input, single char input can be useful.
If we could read the keyboard directly with a get_key_press function, then your request along with making curses cross platform, may be fairly easy to do. (The cross platform get_key_press function is the hard part.)
Are you serious? A get_key_press function is the _easy_ part. On Unix, you use termios to put stdin into raw mode then select or blocking-read stdin; on Windows, you use the msvcrt module to call the wrappers around the console I/O functions. But what do you think those functions return for, say, left arrow, or ctrl+end? (Even beyond non-character keys, even the characters don't necessarily show up as a single character, but as 1 or more bytes in the appropriate encoding (Unix) or 1 or more UTF-16 codes (Windows), so your state is less trivial than you're expecting…) And what are you going to do with a left-arrow key press when you get it? If your answer is "move the cursor left", how do you do that? On Windows you use console I/O functions; on Unix, you talk to termcap to figure out which control sequence to send and then send that; etc. And, once you've moved the cursor left, you probably want to insert rather than overwriting. And of course you need to be able to deal with input that wraps onto multiple lines; you may or may not have to do that wrapping yourself. And so on. And once you've solved all of that, and figured out how to keep track of buffers and cursor positions, then you just need to write code to emulate everything that each platform does for terminal line editing. To get an idea of how much work that is for each platform, look at the source to readline or libedit. This is exactly why Python doesn't do any of that; it just uses readline (or libedit's readline-compat mode) on Unix, lets cmd.exe do its thing on Windows, etc. (This also makes it relatively easy for IDEs to hook the behavior and, e.g., make input give you a GUI window with a Tk text entry box.)
On 04/03/2014 08:41 PM, Andrew Barnert wrote:
From: Ron Adam
Sent: Tuesday, April 1, 2014 6:45 PM
On 04/01/2014 07:58 AM, Steven D'Aprano wrote:
I often have the need to include a default or initial value when asking the user for input. In other words, I'd like to call this:
input("What is the fish of the day? ", "trout a la creme")
and have the prompt be "What is the fish of the day? " and the initial value in the edit buffer be "trout a la creme", fully editable with whatever line editing tools are available on the user's system. There are work-arounds for this lack, but they don't make a nice clean UI.
Under Linux, with readline, I can implement this relatively simply:
One of the things I first looked for when learning python was a get_key_press function.
Line input (or whole file input) is great for files, and can make reading data much faster than single character input. But for user input, single char input can be useful.
If we could read the keyboard directly with a get_key_press function, then your request along with making curses cross platform, may be fairly easy to do.
(The cross platform get_key_press function is the hard part.)
Are you serious?
Sure it's only a starting point, not a end solution by it self. I was including the parts you you mention below, taking into account the platform and console differences and returning a Unicode string. I wasn't thinking of simply reading and returning the raw key codes. Just get the input (including escape sequences) with out echoing it to the screen. Probably the most straight forward way would be to import a console class, and initiate an instance, then use methods on it to read the input and write the output. That way all the platform stuff can be abstracted away. A higher level function that uses that class, would handle updating the line buffer and write those updates out to the screen. (by calling methods on the instance.
A get_key_press function is the_easy_ part. On Unix, you use termios to put stdin into raw mode then select or blocking-read stdin; on Windows, you use the msvcrt module to call the wrappers around the console I/O functions.
But what do you think those functions return for, say, left arrow, or ctrl+end? (Even beyond non-character keys, even the characters don't necessarily show up as a single character, but as 1 or more bytes in the appropriate encoding (Unix) or 1 or more UTF-16 codes (Windows), so your state is less trivial than you're expecting…)
Yes, there are a lot of small details to work out. But I don't think any of those are impossible to manage.
And what are you going to do with a left-arrow key press when you get it? If your answer is "move the cursor left", how do you do that? On Windows you use console I/O functions; on Unix, you talk to termcap to figure out which control sequence to send and then send that; etc.
And, once you've moved the cursor left, you probably want to insert rather than overwriting. And of course you need to be able to deal with input that wraps onto multiple lines; you may or may not have to do that wrapping yourself. And so on.
And once you've solved all of that, and figured out how to keep track of buffers and cursor positions, then you just need to write code to emulate everything that each platform does for terminal line editing. To get an idea of how much work that is for each platform, look at the source to readline or libedit.
I agree although it's been a while sense I looked at the specific details.
This is exactly why Python doesn't do any of that; it just uses readline (or libedit's readline-compat mode) on Unix, lets cmd.exe do its thing on Windows, etc. (This also makes it relatively easy for IDEs to hook the behavior and, e.g., make input give you a GUI window with a Tk text entry box.)
Those will still work. I don't think anyone is suggesting replacing all of pythons console related code. Cheers, Ron
From: Ron Adam
On 04/03/2014 08:41 PM, Andrew Barnert wrote:
From: Ron Adam
If we could read the keyboard directly with a get_key_press
function, then your request along with making curses cross platform, may be fairly easy to do. (The cross platform get_key_press function is the hard part.)
Are you serious?
Sure it's only a starting point, not a end solution by it self. I was including the parts you you mention below, taking into account the platform and console differences and returning a Unicode string. I wasn't thinking of simply reading and returning the raw key codes. Just get the input (including escape sequences) with out echoing it to the screen.
Again, that's easy to do on both platforms, but it doesn't even begin to approach making the complete solution easy.
Probably the most straight forward way would be to import a console class, and initiate an instance, then use methods on it to read the input and write the output. That way all the platform stuff can be abstracted away.
A higher level function that uses that class, would handle updating the line buffer and write those updates out to the screen. (by calling methods on the instance.
There are only two things you could mean here. 1. The console class is basically a wrapper around readline or its equivalent, in which case we have no need for get_key_press or any of the other stuff you asked about. 2. The console class is just the low-level stuff that's implementable on all platforms, like reading and writing keys to the tty/console, and the higher-level function emulates readline and its platform equivalents on top of nothing but that low-level stuff. I suspect you mean #2. In which case, again, look at how much code readline is. You're talking about duplicating all of that code, just to solve part of the problem (readline is still depending on your terminal to do a lot of the work, which you don't get in raw mode), on just one platform.
A get_key_press function is the_easy_ part. On Unix, you use termios to put stdin into raw mode then select or blocking-read stdin; on Windows, you use the msvcrt module to call the wrappers around the console I/O functions.
But what do you think those functions return for, say, left arrow, or ctrl+end? (Even beyond non-character keys, even the characters don't necessarily show up as a single character, but as 1 or more bytes in the appropriate encoding (Unix) or 1 or more UTF-16 codes (Windows), so your state is less trivial than you're expecting…)
Yes, there are a lot of small details to work out. But I don't think any of those are impossible to manage.
Impossible, of course not. Just not remotely as easy as the part you called "the hard part".
This is exactly why Python doesn't do any of that; it just uses readline (or libedit's readline-compat mode) on Unix, lets cmd.exe do its thing on Windows, etc. (This also makes it relatively easy for IDEs to hook the behavior and, e.g., make input give you a GUI window with a Tk text entry box.)
Those will still work. I don't think anyone is suggesting replacing all of pythons console related code.
You're missing the point. Those work because they use the services provided by the OS, the terminal, the readline library, etc. Trying to duplicate everything that all those layers do on every platform is a lot of work, and a bad idea. It's not about whether you replace anything with that new code or use it in parallel, it's that you're trying to build that new code in the first place. (But also, it's actually not true that they'll still work, at least not in the same problem. Try setting the tty to raw mode and then using readline and see what happens…)
On 4 April 2014 07:01, Andrew Barnert
I suspect you mean #2. In which case, again, look at how much code readline is. You're talking about duplicating all of that code, just to solve part of the problem (readline is still depending on your terminal to do a lot of the work, which you don't get in raw mode), on just one platform.
There's also pyreadline, which is a Pure-Python (plus ctypes) implementation of readline for Windows. AFAIK, it's pretty robust (IPython uses it), but the experience is so different from "normal" console behaviour that it's a but unnerving to a die-hard Windows console user like me. (The problem is that Python's core detects that readline is present and uses it, so if you install it, you get it in your normal interpreter whether you want it or not - I believe they were looking at fixing that in pyreadline, but it's been a while since I checked so I don't know if that's been done yet). Paul
On Fri, Apr 4, 2014, at 2:01, Andrew Barnert wrote:
1. The console class is basically a wrapper around readline or its equivalent, in which case we have no need for get_key_press or any of the other stuff you asked about.
2. The console class is just the low-level stuff that's implementable on all platforms, like reading and writing keys to the tty/console, and the higher-level function emulates readline and its platform equivalents on top of nothing but that low-level stuff.
I suspect you mean #2. In which case, again, look at how much code readline is. You're talking about duplicating all of that code, just to solve part of the problem (readline is still depending on your terminal to do a lot of the work, which you don't get in raw mode), on just one platform.
A) You don't need any of it on windows, because the windows console's built-in editing functionality is good enough. Even this "default value" stuff wouldn't be hard - you just simulate a bunch of keypresses corresponding to the desired string. B) Any reasonable interface to the windows console won't use byte strings at all.
On 04/04/2014 02:01 AM, Andrew Barnert wrote:
From: Ron Adam
Sent: Thursday, April 3, 2014 9:25 PM
On 04/03/2014 08:41 PM, Andrew Barnert wrote:
From: Ron Adam
>If we could read the keyboard directly with a get_key_press > function, then >your request along with making curses cross platform, may be fairly >easy to do. >(The cross platform get_key_press function is the hard part.)
Are you serious?
Sure it's only a starting point, not a end solution by it self. I was including the parts you you mention below, taking into account the platform and console differences and returning a Unicode string. I wasn't thinking of simply reading and returning the raw key codes. Just get the input (including escape sequences) with out echoing it to the screen.
Again, that's easy to do on both platforms, but it doesn't even begin to approach making the complete solution easy.
I think you are thinking of a more complete solution than I am.
Probably the most straight forward way would be to import a console class, and initiate an instance, then use methods on it to read the input and write the output. That way all the platform stuff can be abstracted away.
A higher level function that uses that class, would handle updating the line buffer and write those updates out to the screen. (by calling methods on the instance.
There are only two things you could mean here.
1. The console class is basically a wrapper around readline or its equivalent, in which case we have no need for get_key_press or any of theother stuff you asked about.
2. The console class is just the low-level stuff that's implementable on all platforms, like reading and writing keys to the tty/console, and the higher-level function emulates readline and its platform equivalents on top of nothing but that low-level stuff.
I suspect you mean #2. In which case, again, look at how much code readline is. You're talking about duplicating all of that code, just to solve part of the problem (readline is still depending on your terminal to do a lot of the work, which you don't get in raw mode), on just one platform.
Which ever way would work best, but still result in a single API for all platforms. If number #1 can work, that would be fine, but I suspect there would be a lot of edge cases to resolve to get the wrappers to act alike, if it's even possible to do. I was thinking of just having the basics of #2 in place. Then wait a bit to see how it's used and not try to duplicate readline. Not everything needs the full features of readline. And it may be possible to switch to simple (option #2) input mode temporarily and then back to readline or it equivalent mode. (?) In any case. If you still think it's a bad idea, I'm fine with that.
This is exactly why Python doesn't do any of that; it just uses readline (or libedit's readline-compat mode) on Unix, lets cmd.exe do its thing on Windows, etc. (This also makes it relatively easy for IDEs to hook the behavior and, e.g., make input give you a GUI window with a Tk text entry box.)
Those will still work. I don't think anyone is suggesting replacing all of pythons console related code.
You're missing the point. Those work because they use the services provided by the OS, the terminal, the readline library, etc. Trying to duplicate everything that all those layers do on every platform is a lot of work, and a bad idea. It's not about whether you replace anything with that new code or use it in parallel, it's that you're trying to build that new code in the first place.
(But also, it's actually not true that they'll still work, at least not in the same problem. Try setting the tty to raw mode and then using readline and see what happens…)
Well.. don't do that. ;-) Cheers, Ron
On Thu, Apr 3, 2014, at 20:41, Andrew Barnert wrote:
A get_key_press function is the _easy_ part. On Unix, you use termios to put stdin into raw mode then select or blocking-read stdin; on Windows, you use the msvcrt module to call the wrappers around the console I/O functions.
A _good_ get_key_press function won't return bizarre character sequences for non-graphical keys in the first place. The msvcrt functions map a perfectly good high-level key event object into an information-losing abstraction designed to emulate a truly ancient MS-DOS API. "or 1 or more UTF-16 codes (Windows), so your state is less trivial than you're expecting…" Yeah, and just try distinguishing an arrow key from an _actual_ keypress of à followed by a letter.
participants (10)
-
Andrew Barnert
-
Antoine Pitrou
-
Chris Angelico
-
Guido van Rossum
-
Mark Lawrence
-
Paul Moore
-
random832@fastmail.us
-
Ron Adam
-
Serhiy Storchaka
-
Steven D'Aprano