I am trying to use prompt_toolkit so I can get input from the user without waiting for them to press Enter. I managed to create events and associate them with keys, but I can't figure out how to actually manipulate my program from within the events.
from prompt_toolkit import prompt
from prompt_toolkit.application import run_in_terminal
from prompt_toolkit.key_binding import KeyBindings
i = 2
bindings = KeyBindings()
@bindings.add('c-t')
def _(event):
    " Say 'hello' when `c-t` is pressed. "
    def print_hello():
        print('hello world')
    run_in_terminal(print_hello)
@bindings.add('c-x')
def _(event):
    " Exit when `c-x` is pressed. "
    event.app.exit()
@bindings.add('d')
def _(event):
    i *= 2
text = prompt('> ', key_bindings=bindings)
print(f'You said: {text}')
print(f'i is now {i}')
I expect this program to:
- Print "hello world" when Ctrl + T is pressed.
 - Exit when Ctrl + X is pressed.
 - Double the value of 
iwhen d is pressed. 
It does 1 and 2, but 3 gives Exception local variable 'i' referenced before assignment. But even in the Python documentation we see the example (https://docs.python.org/3/reference/executionmodel.html):
i = 10
def f():
    print(i)
i = 42
f()
So how do I make a key binding that alters my variable?