Description
Feature or enhancement
Proposal:
Hello!
The InteractiveConsole class is defined in the code module. Its behavior is different from a normal console, and I don't see an easy way to replicate this.
The fact is that a regular Python REPL is able to understand that the "up arrow" button was pressed and get a line of text from the input history. Similarly, REPL understands that the "down arrow" has been pressed, which allows navigation through the input history.
I see that the standard implementation of this class allows you to override the method for text input:
def raw_input(self, prompt=""):
"""Write a prompt and read a line.
The returned line does not include the trailing newline.
When the user enters the EOF key sequence, EOFError is raised.
The base implementation uses the built-in function
input(); a subclass may replace this with a different
implementation.
"""
return input(prompt)
However, the standard library does not provide an easy way to implement input with the arrows pressed.
My suggestion is to complicate the internal implementation of the class by adding 2 additional methods there:
def pressed_up(self, buffer: list) -> bool:
return False
def pressed_down(self, buffer: list) -> bool:
return False
These methods should not do anything by default, but the user should be able to override them in order to add any actions related to pressing the arrows, for example, to call a line from the input history.
These methods should return a boolean value that answers the question "do I need to finish typing when the arrow is pressed?". If the answer is True
, then the raw_input
function should return a string that it concatenates from the characters in the buffer (the list that is passed to the input methods pressed_up and pressed_down). If the answer is False
, the raw_input
function should continue to read the input characters through stdout and put them into the buffer until it encounters a newline character.
At the same time, the function and external behavior of the raw_input
method for the entire surrounding code should not change as a result of all these modifications. It should still return the string read from stdin
. Only the internal implementation changes, which allows callbacks called when pressing special buttons on the keyboard to interact with the buffer of already entered characters and change it.
There is an alternative implementation of the same functionality. You can add only one additional method:
from enum import Enum
class PressedButton(Enum):
up = 1
down = 2
esc = 3
...
def pressed_button(self, buffer: list, button_index: PressedButton) -> bool:
return False
In this case, each time a button is pressed on a keyboard that does not represent a letter, the same callback is called, and in addition to the buffer (which does not differ from the previous version), an indicator of which button was pressed is transmitted there. All possible button options should be presented in the form of an enum
, which the user should be able to import from the module.
This mechanism is more general, but I assume that it may be a little more difficult to implement, and so far I don't see any useful ways to apply the additional features that it provides.
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response