Search code examples
pythontextareaprompt-toolkit

How do you add pageup/pagedown keybindings to TextArea in python-prompt-toolkit?


Let's use calculator.py for example.

To add a scrollbar that works with the mouse wheel, you would change:

output_field = TextArea(style="class:output-field", text=help_text)

calculator.py without scrollbar

to:

output_field = TextArea(style="class:output-field", text=help_text, scrollbar=True)

calculator.py with scrollbar

But what would you add or change to scroll the TextArea with the page up and page down keys?

# The key bindings.
kb = KeyBindings()

@kb.add("pageup")
def _(event):
    # What goes here?
    pass

@kb.add("pagedown")
def _(event):
    # What goes here?
    pass

Solution

  • Change focus

    The simplest way would probably be to import focus_next (or focus_previous)

    from prompt_toolkit.key_binding.bindings.focus import focus_next
    

    and bind it to Control-Space (or anything else).

    # The key bindings.
    kb = KeyBindings()
    
    kb.add("c-space")(focus_next)
    

    Keep focus

    You could also, to seemingly keep the focus on input_field, import scroll_page_up and scroll_page_down

    from prompt_toolkit.key_binding.bindings.page_navigation import scroll_page_up, scroll_page_down
    

    then switch focus to output_field, call scroll_page_up/scroll_page_down and finally change focus back to input_field.

    # The key bindings.
    kb = KeyBindings()
    
    @kb.add("pageup")
    def _(event):
        w = event.app.layout.current_window
        event.app.layout.focus(output_field.window)
        scroll_page_up(event)
        event.app.layout.focus(w)
    
    @kb.add("pagedown")
    def _(event):
        w = event.app.layout.current_window
        event.app.layout.focus(output_field.window)
        scroll_page_down(event)
        event.app.layout.focus(w)