Skip to content

InteractiveConsole does not support arrow buttons #109108

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

Closed
pomponchik opened this issue Sep 7, 2023 · 2 comments
Closed

InteractiveConsole does not support arrow buttons #109108

pomponchik opened this issue Sep 7, 2023 · 2 comments
Labels
type-feature A feature request or enhancement

Comments

@pomponchik
Copy link

pomponchik commented Sep 7, 2023

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

@pomponchik pomponchik added the type-feature A feature request or enhancement label Sep 7, 2023
@gaogaotiantian
Copy link
Member

gaogaotiantian commented Sep 7, 2023

Python REPL does not "know" that an "up arrow" is pressed. It is handled by GNU readline on Linux and Powershell(I think) on Windows. Python itself is not aware of the fact that the user pressed the arrow button. You have this feature in real Python REPL and InteractiveConsole - I don't see a problem here.

@serhiy-storchaka
Copy link
Member

You need to import readline to enable this.

try:
    import readline
except ImportError:
    pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants