I want to implement typeahead in a full screen app.
For example: if the user types a key while a list is loading, the key shouldn't be processed until the list is loaded and the item is focused.
# suppose the user types `nfoo\nbar\n` on a todo list
@kb.add("n") # create a new todo
async def _(event):
app.key_processor.pause()
await some_tasks()
p = await prepare_and_focus_prompt()
app.key_processor.resume()
name = await p.readline(on_accept=app.key_processor.pause)
# we have to pause key_processor immediately after `\n` so `bar\n` can be kept in `input_queue`
await some_tasks()
p2 = await prepare_and_focus_prompt()
app.key_processor.resume() # now `bar` would be processed by the second prompt.
desc = await p2.readline(on_accept=app.key_processor.pause)
# back to the list and resume key_processor
await create_item(name, desc)
await load_and_focus_list()
app.key_processor.resume() # any keys after `\n` should go to list window
Currently this is what I do:
Configure asyncio to run tasks eagerly: asyncio.get_running_loop().set_task_factory(asyncio.eager_task_factory)
Modify app._default_bindings to add an <any> handler, which will catch all unhandled keys.
Before loading the list, focus a dummy window so key presses can be cought by (2)
After the list is ready, focus the list item and send those keys to app.key_processor.feed_multiple.
Call key_processor.process_keys. However, you have to call it via aynscio.get_running_loop().call_later(0.1, app.key_processor.process_keys) or the app will freeze. I have no idea why.
I also noticed that there is an input.detach function. However, it doesn't work in a key binding handler since keys typed are already sent to key_processor.input_queue.
I want to implement typeahead in a full screen app.
For example: if the user types a key while a list is loading, the key shouldn't be processed until the list is loaded and the item is focused.
Currently this is what I do:
asyncio.get_running_loop().set_task_factory(asyncio.eager_task_factory)
app._default_bindings
to add an<any>
handler, which will catch all unhandled keys.app.key_processor.feed_multiple
.key_processor.process_keys
. However, you have to call it viaaynscio.get_running_loop().call_later(0.1, app.key_processor.process_keys)
or the app will freeze. I have no idea why.I also noticed that there is an
input.detach
function. However, it doesn't work in a key binding handler since keys typed are already sent tokey_processor.input_queue
.