Skip to content
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

Prompt in full screen application #652

Closed
tage64 opened this issue Jun 27, 2018 · 6 comments
Closed

Prompt in full screen application #652

tage64 opened this issue Jun 27, 2018 · 6 comments

Comments

@tage64
Copy link

tage64 commented Jun 27, 2018

Hi!
I want to create a full screen application. Then I want to ask the user for some input at some point in my code. I want to use the prompt function. It seems to me that I can't do that. I've tried run_in_terminal, but it doesn't worked in this case.
Is it possible to do that?
Tage!

@jonathanslenders
Copy link
Member

jonathanslenders commented Jun 27, 2018

Hi @Tagej,

The prompt function is not meant to run inside the full screen layout, but run_coroutine_in_terminal can handle that. It will hide the full screen layout; display the prompt; and go back. The reason to use that instead of run_in_terminal is because there is already an event loop running that you want to use. run_in_terminal is meant for running blocking functions. Spawning the event loop again from in there doesn't work.

It should look something like this:

from prompt_toolkit.application import run_coroutine_in_terminal
from prompt_toolkit.shortcuts import prompt

def display_prompt_in_app():
    future = run_coroutine_in_terminal(prompt('>', async_=True))

The async_ flag makes that prompt() returns a Future/coroutine. In the future, these are probably becoming asyncio Futures/coroutines, but keep in mind that right now, this is prompt_toolkit specific.

If you want to display an input field on top of the full screen application, then you can for instance consider using a Float/FloatContainer containing a prompt_toolkit.widgets.Dialog containing a prompt_toolkit.widgets.TextArea for the input field. You can show/hide this using a prompt_toolkit.layout.ConditionalContainer. TextArea has several attributes like lexer, completer, etc.. similar to the prompt() function.

Notice that the prompt_toolkit.widgets module is still pretty new. There's still missing documentation, and these classes have to evolve once we discover the best practices and missing features. I like to take the time for this to progress, but if you feel that anything is missing or wrong, don't hesitate to report that.
Hope that helps. :-)

@tage64
Copy link
Author

tage64 commented Jun 29, 2018

Hi @jonathanslenders
It don't work for me. Here's what I've tested:
`from functools import partial

from prompt_toolkit import prompt
from prompt_toolkit.application import run_coroutine_in_terminal,
run_in_terminal
from prompt_toolkit.eventloop import run_until_complete
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.keys import Keys

key_bindings = KeyBindings()
@key_bindings.add(Keys.ControlS)
def (event):
f = run_coroutine_in_terminal(partial(prompt, '> ', async
=True))
run_until_complete(f)
run_in_terminal(partial(print, f2.result()))
print(prompt('> ', key_bindings=key_bindings))
`

It raised an exception when I pressed control S. Try it out yourself.
Is it a bug? Or just bad code?
Tage

@decentral1se
Copy link
Contributor

Hey, I think I'd just like to chime in here and say that I am also building a full screen application (thanks for all the good work to get us here, it's a really nice API so far!) and that I want the full featured prompt(...) to run in one of my TextArea widgets - I am not seeing right now how that is possible and just dropping a body=prompt into existing containers is causing my interface to freeze when I run it. From reading above, this isn't possible right now? Anything that we can do to move it along? Any work arounds right now? Thanks again.

@decentral1se
Copy link
Contributor

Ah, I do see that we have https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/widgets/base.py#L87-L88 which can get me moving along for now. Sorry for the noise.

@decentral1se
Copy link
Contributor

Ah, here is an example which shows you how to build up your own widget that you can control the BufferControl with: https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/examples/full-screen/simple-demos/autocompletion.py. You can start to piece together a prompt and so on.

@rogerbassons
Copy link

My solution to this is @jonathanslenders TextArea/input field suggestion:

If you want to display an input field on top of the full screen application, then you can for instance consider using a Float/FloatContainer containing a prompt_toolkit.widgets.Dialog containing a prompt_toolkit.widgets.TextArea for the input field. You can show/hide this using a prompt_toolkit.layout.ConditionalContainer. TextArea has several attributes like lexer, completer, etc.. similar to the prompt() function.

Layout like this:

search_field = SearchToolbar()
input_field = TextArea(height=1, prompt='/', style='class:input-field', multiline=False, wrap_lines=False, search_field=search_field)
input_field.accept_handler = filterTable

root_container = HSplit([
    Window(content=FormattedTextControl(text=getFormattedTable(selected, filteredList), get_cursor_position=GetCursorPosition())),
    ConditionalContainer(content=input_field, filter=isSearching)
])
layout = Layout(container=root_container)

Inside filterTable function you can read user input with input_field.text attribute

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants