Skip to content

Commit 7362119

Browse files
Added choice shortcut.
Additionally: - Bugfix in dimension.py: handling of zero sized dimensions. - Option for adding frames for prompt inputs. - Typing fix in `src/prompt_toolkit/input/win32.py`.
1 parent af26eec commit 7362119

27 files changed

+964
-115
lines changed

docs/images/choice-input.png

57.9 KB
Loading

docs/images/choice-with-frame.png

68.4 KB
Loading

docs/images/colored-choice.png

62.3 KB
Loading

docs/images/prompt-with-frame.png

50.5 KB
Loading

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Table of contents
6969
pages/upgrading/index
7070
pages/printing_text
7171
pages/asking_for_input
72+
pages/asking_for_a_choice
7273
pages/dialogs
7374
pages/progress_bars
7475
pages/full_screen_apps

docs/pages/asking_for_a_choice.rst

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
.. _asking_for_input:
2+
3+
Asking for a choice
4+
===================
5+
6+
Similar to how the :func:`~prompt_toolkit.shortcuts.prompt` function allows for
7+
text input, prompt_toolkit has a
8+
:func:`~prompt_toolkit.shortcuts.choice` function to ask for a choice
9+
from a list of options:
10+
11+
.. code:: python
12+
13+
from prompt_toolkit.shortcuts import choice
14+
15+
result = choice(
16+
message="Please choose a dish:",
17+
options=[
18+
("pizza", "Pizza with mushrooms"),
19+
("salad", "Salad with tomatoes"),
20+
("sushi", "Sushi"),
21+
],
22+
default="salad",
23+
)
24+
print(f"You have chosen: {result}")
25+
26+
.. image:: ../images/choice-input.png
27+
28+
29+
Coloring the options
30+
--------------------
31+
32+
It is possible to customize the colors and styles. The ``message`` parameter
33+
takes any :ref:`formatted text <formatted_text>`, and the labels (2nd argument
34+
from the options) can be :ref:`formatted text <formatted_text>` as well.
35+
Further, we can pass a :class:`~prompt_toolkit.styles.Style` instance using the
36+
:meth:`~prompt_toolkit.styles.Style.from_dict` function:
37+
38+
.. code:: python
39+
40+
from prompt_toolkit.formatted_text import HTML
41+
from prompt_toolkit.shortcuts import choice
42+
from prompt_toolkit.styles import Style
43+
44+
style = Style.from_dict(
45+
{
46+
"input-selection": "fg:#ff0000",
47+
"number": "fg:#884444 bold",
48+
"selected-option": "underline",
49+
}
50+
)
51+
52+
result = choice(
53+
message=HTML("<u>Please select a dish</u>:"),
54+
options=[
55+
("pizza", "Pizza with mushrooms"),
56+
(
57+
"salad",
58+
HTML("<ansigreen>Salad</ansigreen> with <ansired>tomatoes</ansired>"),
59+
),
60+
("sushi", "Sushi"),
61+
],
62+
style=style,
63+
)
64+
print(result)
65+
66+
.. image:: ../images/colored-choice.png
67+
68+
69+
Adding a frame
70+
--------------
71+
72+
The :func:`~prompt_toolkit.shortcuts.choice` function takes a
73+
``show_frame`` argument. When ``True``, the input is displayed within a frame.
74+
It is also possible to pass a :ref:`filter <filters>`, like ``~is_done``, so
75+
that the frame is only displayed when asking for input, but hidden once the
76+
input is accepted.
77+
78+
.. code:: python
79+
80+
from prompt_toolkit.shortcuts import choice
81+
from prompt_toolkit.filters import is_done
82+
from prompt_toolkit.styles import Style
83+
84+
style = Style.from_dict(
85+
{
86+
"frame.border": "#884444",
87+
"selected-option": "bold",
88+
}
89+
)
90+
result = choice(
91+
message="Please select a dish:",
92+
options=[
93+
("pizza", "Pizza with mushrooms"),
94+
("salad", "Salad with tomatoes"),
95+
("sushi", "Sushi"),
96+
],
97+
style=style,
98+
show_frame=~is_done,
99+
)
100+
print(result)
101+
102+
.. image:: ../images/choice-with-frame.png

docs/pages/asking_for_input.rst

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ of the foreground.
656656
from prompt_toolkit.formatted_text import HTML
657657
658658
def bottom_toolbar():
659-
return HTML("This is a <b><style bg="ansired">Toolbar</style></b>!")
659+
return HTML('This is a <b><style bg="ansired">Toolbar</style></b>!')
660660
661661
text = prompt("> ", bottom_toolbar=bottom_toolbar)
662662
print(f"You said: {text}")
@@ -997,6 +997,42 @@ input mode.
997997
prompt(">", cursor=ModalCursorShapeConfig())
998998
999999
1000+
Adding a frame
1001+
--------------
1002+
1003+
A frame can be displayed around the input by passing ``show_frame=True`` as a
1004+
parameter. The color of the frame can be chosen by styling the ``frame.border``
1005+
element:
1006+
1007+
.. code:: python
1008+
1009+
from prompt_toolkit import prompt
1010+
from prompt_toolkit.styles import Style
1011+
1012+
style = Style.from_dict(
1013+
{
1014+
"frame.border": "#884444",
1015+
}
1016+
)
1017+
1018+
answer = prompt("Say something > ", style=style, show_frame=True)
1019+
print(f"You said: {answer}")
1020+
1021+
.. image:: ../images/prompt-with-frame.png
1022+
1023+
It is also possible to pass a :ref:`filter <filters>`, for instance
1024+
``show_frame=~is_done``, so that the frame is only displayed when asking for
1025+
input, but hidden once the input is accepted.
1026+
1027+
.. code:: python
1028+
1029+
from prompt_toolkit import prompt
1030+
from prompt_toolkit.filters import is_done
1031+
1032+
answer = prompt("Say something > ", show_frame=~is_done)
1033+
print(f"You said: {answer}")
1034+
1035+
10001036
Prompt in an `asyncio` application
10011037
----------------------------------
10021038

docs/pages/reference.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Shortcuts
9696
:members: prompt, PromptSession, confirm, CompleteStyle,
9797
create_confirm_session, clear, clear_title, print_formatted_text,
9898
set_title, ProgressBar, input_dialog, message_dialog, progress_dialog,
99-
radiolist_dialog, yes_no_dialog, button_dialog
99+
radiolist_dialog, yes_no_dialog, button_dialog, choice
100100

101101
.. automodule:: prompt_toolkit.shortcuts.progress_bar.formatters
102102
:members:

examples/choices/color.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from __future__ import annotations
2+
3+
from prompt_toolkit.formatted_text import HTML
4+
from prompt_toolkit.shortcuts import choice
5+
from prompt_toolkit.styles import Style
6+
7+
8+
def main() -> None:
9+
style = Style.from_dict(
10+
{
11+
"input-selection": "fg:#ff0000",
12+
"number": "fg:#884444 bold",
13+
"selected-option": "underline",
14+
"frame.border": "#884444",
15+
}
16+
)
17+
18+
result = choice(
19+
message=HTML("<u>Please select a dish</u>:"),
20+
options=[
21+
("pizza", "Pizza with mushrooms"),
22+
(
23+
"salad",
24+
HTML("<ansigreen>Salad</ansigreen> with <ansired>tomatoes</ansired>"),
25+
),
26+
("sushi", "Sushi"),
27+
],
28+
style=style,
29+
)
30+
print(result)
31+
32+
33+
if __name__ == "__main__":
34+
main()

examples/choices/default.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from __future__ import annotations
2+
3+
from prompt_toolkit.formatted_text import HTML
4+
from prompt_toolkit.shortcuts import choice
5+
6+
7+
def main() -> None:
8+
result = choice(
9+
message=HTML("<u>Please select a dish</u>:"),
10+
options=[
11+
("pizza", "Pizza with mushrooms"),
12+
("salad", "Salad with tomatoes"),
13+
("sushi", "Sushi"),
14+
],
15+
default="salad",
16+
)
17+
print(result)
18+
19+
20+
if __name__ == "__main__":
21+
main()

0 commit comments

Comments
 (0)