Open RichardWarfield opened 5 years ago
Hi Richard,
That sounds like a nice project!
What you experience is expected. Prompt_toolkit has an event-loop based architecture, which means that any blocking call blocks the application (similar to asyncio). The solution would be to run the expensive code in a thread. From within the thread, you can invalidate the UI when done, so that bottom_toolbar
is called again. Something like the code below.
Make sure not to start a new thread, if there's already one running. The if not bottom_text
probably has to be replaced with a condition that determines when it has to recompute.
from prompt_toolkit.application import get_app
import prompt_toolkit
import threading
import time
bottom_text = ''
bottom_thread_running = False
def bottom_toolbar():
global bottom_thread_running
if not bottom_text and not bottom_thread_running:
bottom_thread_running = True
threading.Thread(target=bottom_toolbar_async).start()
return bottom_text
def bottom_toolbar_async():
global bottom_text, bottom_thread_running
time.sleep(5)
bottom_text = 'new text'
bottom_thread_running = False
get_app().invalidate()
if __name__=='__main__':
prompt_toolkit.shortcuts.prompt(bottom_toolbar=bottom_toolbar)
My (long term) plan is to upgrade prompt_toolkit to use asyncio natively. And then we can also consider coroutines for the bottom toolbar.
Hope that helps.
Thanks Jonathan for the prompt (pun not intended) reply and for putting together that code sample. I'll try it out.
It makes sense that the application should block during a long bottom_toolbar execution. But is it really expected that it should be impossible to interrupt/suspend with Ctrl-C/Ctrl-Z? It seems to me that perhaps the setting of icrnl should be restored before calling the bottom_toolbar callback. Perhaps using the cooked_mode
class in vt100.py?
I'm working on a front end to Haskell's GHCI based on prompt-toolkit, have noticed the following behavior.
If a call to the bottom_toolbar handler takes a long time, it seems that the application becomes entirely unresponsive and impossible to interrupt, even with Ctrl-C or Ctrl-Z (suspend).
By attaching a debugger externally I've determined that the issue seems to be that prompt-toolkit has the icrnl tty attribute disabled during the call to the handler. This prevents the tty from treating those Ctrl- combinations as expected.
Here's a simple reproducing example:
On a related note, it would be great if there were a way to have bottom_toolbar called asynchronously. My use case if that I'd like to display the type of the expression underlying the cursor in the bottom_toolbar, which involves a (sometimes) costly call to the Haskell interpreter backend.
Using prompt-toolkit 2.0.9 on Arch Linux with Python 3.7.