Open maingoh opened 4 years ago
Not be blocking as in that they could finish the message whilst the warning was there, or just as in being of small size?
Anyhow, if you want non-blocking dynamic messages, toolbars are the way to go: https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html#adding-a-bottom-toolbar
Not be blocking as in that they could finish the message whilst the warning was there, or just as in being of small size?
They could finish and validate the input. Basically I would like to print something from the validator because it is triggered while typing, but in the bottom (so either in the validator section or bottom toolbar).
I can probably change the style and raise a ValidationError but it will be blocking. About the toolbar, can I edit it or add it from the document ? Could we dynamically add a new toolbar if one is already existing ?
When a function is given, it will be called every time the prompt is rendered, so the bottom toolbar can be used to display dynamic information.
Oh, my bad I misread ! Thank you :)
What is the cleanest way to do so, can I share the state between the validator and the toolbar function without using a global variable ? Maybe we could pass the document to the toolbar function and in some way share some user data ?
Hi.
Try this:
from prompt_toolkit.application import get_app
from prompt_toolkit import prompt, HTML
def example_callable():
document = get_app().current_buffer.document
currline = document.current_line
return HTML(f'Current line: <b><style bg="ansired">{currline}</style></b>!')
text = prompt('> ', bottom_toolbar=example_callable)
print(text)
Oh thank you, I didn't see about the get_app
function, maybe we could add an example like this in the documentation in Asking for input
section to show how to access the current text from anywhere.
One more question :smile: how can I dynamically change the style of the toolbar ?
I would like that sometimes it get's hidden (nothing to display, so no white background) and sometimes the background (foreground since it is reversed) get changed. But it seems the style for the bottom-toolbar
class is static (can only be send from the prompt function), can we do it from the callable ?
If I try to change the style in HTML, it only changes the background of the text but not of the full row/line.
I managed to do what I wanted, the key was to disable the reverse
style of the toolbar at the beginning:
from prompt_toolkit.application import get_app
from prompt_toolkit import prompt, HTML
from prompt_toolkit.styles import Style
def toolbar_callable():
document = get_app().current_buffer.document
currline = document.current_line
if currline == 'bad':
return HTML('<b bg="orange">WARNING: you are doing bad !</b>')
return '' # Nothing to display, everything is fine
normal_style = Style.from_dict({
'bottom-toolbar': 'noreverse',
})
prompt("How are you doing: ", bottom_toolbar=toolbar_callable,
style=normal_style)
Also I managed to pass variables to the toolbar_callable
using functools.partial
.
This is however not so intuitive for someone new to the library. It would be very helpful to have a more dynamic way to update styles from anywere, a bit like in javascript using selectors.
Something like:
def toolbar_callable():
app = get_app()
# select a container from the attribute
toolbar = app.select_by_class('bottom-toolbar')[0]
toolbar.set_style('fg: red bg: white') # add a style on the toolbar or edit directly the toolbar
# or updating the style for all containers using the class attribute
app.styles.update('bottom-toolbar', 'fg: red bg: black')
This is probably quite a lot of work but would be nice no ?
I would like to print a warning from
validator.validate()
, using a different color/style. This warning would not be blocking for the user. I tried to dig a bit into the code but couldn't find how to do it, is it easily doable ?