Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/images/choice-input.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/choice-with-frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/colored-choice.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/prompt-with-frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Table of contents
pages/upgrading/index
pages/printing_text
pages/asking_for_input
pages/asking_for_a_choice
pages/dialogs
pages/progress_bars
pages/full_screen_apps
Expand Down
145 changes: 145 additions & 0 deletions docs/pages/asking_for_a_choice.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
.. _asking_for_input:

Asking for a choice
===================

Similar to how the :func:`~prompt_toolkit.shortcuts.prompt` function allows for
text input, prompt_toolkit has a
:func:`~prompt_toolkit.shortcuts.choice` function to ask for a choice
from a list of options:

.. code:: python

from prompt_toolkit.shortcuts import choice

result = choice(
message="Please choose a dish:",
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
default="salad",
)
print(f"You have chosen: {result}")

.. image:: ../images/choice-input.png


Coloring the options
--------------------

It is possible to customize the colors and styles. The ``message`` parameter
takes any :ref:`formatted text <formatted_text>`, and the labels (2nd argument
from the options) can be :ref:`formatted text <formatted_text>` as well.
Further, we can pass a :class:`~prompt_toolkit.styles.Style` instance using the
:meth:`~prompt_toolkit.styles.Style.from_dict` function:

.. code:: python

from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice
from prompt_toolkit.styles import Style

style = Style.from_dict(
{
"input-selection": "fg:#ff0000",
"number": "fg:#884444 bold",
"selected-option": "underline",
}
)

result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
(
"salad",
HTML("<ansigreen>Salad</ansigreen> with <ansired>tomatoes</ansired>"),
),
("sushi", "Sushi"),
],
style=style,
)
print(f"You have chosen: {result}")

.. image:: ../images/colored-choice.png


Adding a frame
--------------

The :func:`~prompt_toolkit.shortcuts.choice` function takes a
``show_frame`` argument. When ``True``, the input is displayed within a frame.
It is also possible to pass a :ref:`filter <filters>`, like ``~is_done``, so
that the frame is only displayed when asking for input, but hidden once the
input is accepted.

.. code:: python

from prompt_toolkit.shortcuts import choice
from prompt_toolkit.filters import is_done
from prompt_toolkit.styles import Style

style = Style.from_dict(
{
"frame.border": "#884444",
"selected-option": "bold",
}
)
result = choice(
message="Please select a dish:",
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
style=style,
show_frame=~is_done,
)
print(f"You have chosen: {result}")

.. image:: ../images/choice-with-frame.png


Adding a bottom toolbar
-----------------------

Adding a bottom toolbar can be done by passing a ``bottom_toolbar`` argument to
:func:`~prompt_toolkit.shortcuts.choice`. This argument can be plain text,
:ref:`formatted text <formatted_text>` or a callable that returns plain or
formatted text.


.. code:: python

from prompt_toolkit.filters import is_done
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice
from prompt_toolkit.styles import Style

style = Style.from_dict(
{
"frame.border": "#ff4444",
"selected-option": "bold",
# ('noreverse' because the default toolbar style uses 'reverse')
"bottom-toolbar": "#ffffff bg:#333333 noreverse",
}
)

result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
style=style,
bottom_toolbar=HTML(
" Press <b>[Up]</b>/<b>[Down]</b> to select, <b>[Enter]</b> to accept."
),
show_frame=~is_done,
)
print(f"You have chosen: {result}")

.. image:: ../images/choice-with-frame-and-bottom-toolbar.png
38 changes: 37 additions & 1 deletion docs/pages/asking_for_input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ of the foreground.
from prompt_toolkit.formatted_text import HTML

def bottom_toolbar():
return HTML("This is a <b><style bg="ansired">Toolbar</style></b>!")
return HTML('This is a <b><style bg="ansired">Toolbar</style></b>!')

text = prompt("> ", bottom_toolbar=bottom_toolbar)
print(f"You said: {text}")
Expand Down Expand Up @@ -997,6 +997,42 @@ input mode.
prompt(">", cursor=ModalCursorShapeConfig())


Adding a frame
--------------

A frame can be displayed around the input by passing ``show_frame=True`` as a
parameter. The color of the frame can be chosen by styling the ``frame.border``
element:

.. code:: python

from prompt_toolkit import prompt
from prompt_toolkit.styles import Style

style = Style.from_dict(
{
"frame.border": "#884444",
}
)

answer = prompt("Say something > ", style=style, show_frame=True)
print(f"You said: {answer}")

.. image:: ../images/prompt-with-frame.png

It is also possible to pass a :ref:`filter <filters>`, for instance
``show_frame=~is_done``, so that the frame is only displayed when asking for
input, but hidden once the input is accepted.

.. code:: python

from prompt_toolkit import prompt
from prompt_toolkit.filters import is_done

answer = prompt("Say something > ", show_frame=~is_done)
print(f"You said: {answer}")


Prompt in an `asyncio` application
----------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Shortcuts
:members: prompt, PromptSession, confirm, CompleteStyle,
create_confirm_session, clear, clear_title, print_formatted_text,
set_title, ProgressBar, input_dialog, message_dialog, progress_dialog,
radiolist_dialog, yes_no_dialog, button_dialog
radiolist_dialog, yes_no_dialog, button_dialog, choice

.. automodule:: prompt_toolkit.shortcuts.progress_bar.formatters
:members:
Expand Down
34 changes: 34 additions & 0 deletions examples/choices/color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from __future__ import annotations

from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice
from prompt_toolkit.styles import Style


def main() -> None:
style = Style.from_dict(
{
"input-selection": "fg:#ff0000",
"number": "fg:#884444 bold",
"selected-option": "underline",
"frame.border": "#884444",
}
)

result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
(
"salad",
HTML("<ansigreen>Salad</ansigreen> with <ansired>tomatoes</ansired>"),
),
("sushi", "Sushi"),
],
style=style,
)
print(result)


if __name__ == "__main__":
main()
21 changes: 21 additions & 0 deletions examples/choices/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from __future__ import annotations

from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice


def main() -> None:
result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
default="salad",
)
print(result)


if __name__ == "__main__":
main()
40 changes: 40 additions & 0 deletions examples/choices/frame-and-bottom-toolbar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from __future__ import annotations

from prompt_toolkit.filters import is_done
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice
from prompt_toolkit.styles import Style


def main() -> None:
style = Style.from_dict(
{
"frame.border": "#ff4444",
"selected-option": "bold",
# We use 'noreverse' because the default style for 'bottom-toolbar'
# uses 'reverse'.
"bottom-toolbar": "#ffffff bg:#333333 noreverse",
}
)

result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
style=style,
bottom_toolbar=HTML(
" Press <b>[Up]</b>/<b>[Down]</b> to select, <b>[Enter]</b> to accept."
),
# Use `~is_done`, if you only want to show the frame while editing and
# hide it when the input is accepted.
# Use `True`, if you always want to show the frame.
show_frame=~is_done,
)
print(result)


if __name__ == "__main__":
main()
31 changes: 31 additions & 0 deletions examples/choices/gray-frame-on-accept.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from __future__ import annotations

from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice
from prompt_toolkit.styles import Style


def main() -> None:
style = Style.from_dict(
{
"selected-option": "bold",
"frame.border": "#ff4444",
"accepted frame.border": "#888888",
}
)

result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
style=style,
show_frame=True,
)
print(result)


if __name__ == "__main__":
main()
15 changes: 15 additions & 0 deletions examples/choices/many-choices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from __future__ import annotations

from prompt_toolkit.shortcuts import choice


def main() -> None:
result = choice(
message="Please select an option:",
options=[(i, f"Option {i}") for i in range(1, 100)],
)
print(result)


if __name__ == "__main__":
main()
21 changes: 21 additions & 0 deletions examples/choices/mouse-support.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from __future__ import annotations

from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.shortcuts import choice


def main() -> None:
result = choice(
message=HTML("<u>Please select a dish</u>:"),
options=[
("pizza", "Pizza with mushrooms"),
("salad", "Salad with tomatoes"),
("sushi", "Sushi"),
],
mouse_support=True,
)
print(result)


if __name__ == "__main__":
main()
Loading