Skip to content
Draft
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
39 changes: 36 additions & 3 deletions src/prompt_toolkit/shortcuts/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
FormattedTextControl,
SearchBufferControl,
)
from prompt_toolkit.layout.dimension import Dimension
from prompt_toolkit.layout.dimension import AnyDimension, Dimension
from prompt_toolkit.layout.layout import Layout
from prompt_toolkit.layout.menus import CompletionsMenu, MultiColumnCompletionsMenu
from prompt_toolkit.layout.processors import (
Expand Down Expand Up @@ -307,6 +307,10 @@ class PromptSession(Generic[_T]):
This can also be a callable that returns (formatted) text.
:param bottom_toolbar: Formatted text or callable that returns formatted
text to be displayed at the bottom of the screen.
:param bottom_toolbar_height: Height of the bottom toolbar. Can be an
integer, a :class:`~prompt_toolkit.layout.Dimension`, or `None` for
dynamic height (useful for multiline content). Defaults to
``Dimension(min=1)``.
:param prompt_continuation: Text that needs to be displayed for a multiline
prompt continuation. This can either be formatted text or a callable
that takes a `prompt_width`, `line_number` and `wrap_count` as input
Expand All @@ -323,6 +327,10 @@ class PromptSession(Generic[_T]):
:param show_frame: `bool` or
:class:`~prompt_toolkit.filters.Filter`. When True, surround the input
with a frame.
:param validation_toolbar_height: Height of the validation toolbar. Can be
an integer, a :class:`~prompt_toolkit.layout.Dimension`, or `None` for
dynamic height (useful for multiline validation error messages).
Defaults to 1.
:param refresh_interval: (number; in seconds) When given, refresh the UI
every so many seconds.
:param input: `Input` object. (Note that the preferred way to change the
Expand Down Expand Up @@ -373,6 +381,8 @@ class PromptSession(Generic[_T]):
"tempfile_suffix",
"tempfile",
"show_frame",
"validation_toolbar_height",
"bottom_toolbar_height",
)

def __init__(
Expand Down Expand Up @@ -409,6 +419,7 @@ def __init__(
prompt_continuation: PromptContinuationText | None = None,
rprompt: AnyFormattedText = None,
bottom_toolbar: AnyFormattedText = None,
bottom_toolbar_height: AnyDimension = Dimension(min=1),
mouse_support: FilterOrBool = False,
input_processors: list[Processor] | None = None,
placeholder: AnyFormattedText | None = None,
Expand All @@ -418,6 +429,7 @@ def __init__(
tempfile: str | Callable[[], str] | None = None,
refresh_interval: float = 0,
show_frame: FilterOrBool = False,
validation_toolbar_height: AnyDimension = 1,
input: Input | None = None,
output: Output | None = None,
interrupt_exception: type[BaseException] = KeyboardInterrupt,
Expand All @@ -443,6 +455,7 @@ def __init__(
self.is_password = is_password
self.key_bindings = key_bindings
self.bottom_toolbar = bottom_toolbar
self.bottom_toolbar_height = bottom_toolbar_height
self.style = style
self.style_transformation = style_transformation
self.swap_light_and_dark_colors = swap_light_and_dark_colors
Expand Down Expand Up @@ -472,6 +485,7 @@ def __init__(
self.tempfile_suffix = tempfile_suffix
self.tempfile = tempfile
self.show_frame = show_frame
self.validation_toolbar_height = validation_toolbar_height
self.interrupt_exception = interrupt_exception
self.eof_exception = eof_exception

Expand Down Expand Up @@ -588,7 +602,7 @@ def display_placeholder() -> bool:
),
style="class:bottom-toolbar",
dont_extend_height=True,
height=Dimension(min=1),
height=self.bottom_toolbar_height,
),
filter=Condition(lambda: self.bottom_toolbar is not None)
& ~is_done
Expand Down Expand Up @@ -711,7 +725,10 @@ def multi_column_complete_style() -> bool:
filter=dyncond("show_frame"),
alternative_content=main_input_container,
),
ConditionalContainer(ValidationToolbar(), filter=~is_done),
ConditionalContainer(
ValidationToolbar(height=self.validation_toolbar_height),
filter=~is_done,
),
ConditionalContainer(
system_toolbar, dyncond("enable_system_prompt") & ~is_done
),
Expand Down Expand Up @@ -885,6 +902,7 @@ def prompt(
is_password: bool | None = None,
key_bindings: KeyBindingsBase | None = None,
bottom_toolbar: AnyFormattedText | None = None,
bottom_toolbar_height: AnyDimension | None = None,
style: BaseStyle | None = None,
color_depth: ColorDepth | None = None,
cursor: AnyCursorShapeConfig | None = None,
Expand Down Expand Up @@ -913,6 +931,7 @@ def prompt(
tempfile_suffix: str | Callable[[], str] | None = None,
tempfile: str | Callable[[], str] | None = None,
show_frame: FilterOrBool | None = None,
validation_toolbar_height: AnyDimension | None = None,
# Following arguments are specific to the current `prompt()` call.
default: str | Document = "",
accept_default: bool = False,
Expand Down Expand Up @@ -1039,6 +1058,10 @@ class itself. For these, passing in ``None`` will keep the current
self.tempfile = tempfile
if show_frame is not None:
self.show_frame = show_frame
if validation_toolbar_height is not None:
self.validation_toolbar_height = validation_toolbar_height
if bottom_toolbar_height is not None:
self.bottom_toolbar_height = bottom_toolbar_height

self._add_pre_run_callables(pre_run, accept_default)
self.default_buffer.reset(
Expand Down Expand Up @@ -1125,6 +1148,7 @@ async def prompt_async(
is_password: bool | None = None,
key_bindings: KeyBindingsBase | None = None,
bottom_toolbar: AnyFormattedText | None = None,
bottom_toolbar_height: AnyDimension | None = None,
style: BaseStyle | None = None,
color_depth: ColorDepth | None = None,
cursor: CursorShapeConfig | None = None,
Expand Down Expand Up @@ -1153,6 +1177,7 @@ async def prompt_async(
tempfile_suffix: str | Callable[[], str] | None = None,
tempfile: str | Callable[[], str] | None = None,
show_frame: FilterOrBool = False,
validation_toolbar_height: AnyDimension | None = None,
# Following arguments are specific to the current `prompt()` call.
default: str | Document = "",
accept_default: bool = False,
Expand Down Expand Up @@ -1236,6 +1261,10 @@ async def prompt_async(
self.tempfile = tempfile
if show_frame is not None:
self.show_frame = show_frame
if validation_toolbar_height is not None:
self.validation_toolbar_height = validation_toolbar_height
if bottom_toolbar_height is not None:
self.bottom_toolbar_height = bottom_toolbar_height

self._add_pre_run_callables(pre_run, accept_default)
self.default_buffer.reset(
Expand Down Expand Up @@ -1401,6 +1430,7 @@ def prompt(
is_password: bool | None = None,
key_bindings: KeyBindingsBase | None = None,
bottom_toolbar: AnyFormattedText | None = None,
bottom_toolbar_height: AnyDimension | None = None,
style: BaseStyle | None = None,
color_depth: ColorDepth | None = None,
cursor: AnyCursorShapeConfig = None,
Expand Down Expand Up @@ -1429,6 +1459,7 @@ def prompt(
tempfile_suffix: str | Callable[[], str] | None = None,
tempfile: str | Callable[[], str] | None = None,
show_frame: FilterOrBool | None = None,
validation_toolbar_height: AnyDimension | None = None,
# Following arguments are specific to the current `prompt()` call.
default: str = "",
accept_default: bool = False,
Expand Down Expand Up @@ -1457,6 +1488,7 @@ def prompt(
is_password=is_password,
key_bindings=key_bindings,
bottom_toolbar=bottom_toolbar,
bottom_toolbar_height=bottom_toolbar_height,
style=style,
color_depth=color_depth,
cursor=cursor,
Expand Down Expand Up @@ -1485,6 +1517,7 @@ def prompt(
tempfile_suffix=tempfile_suffix,
tempfile=tempfile,
show_frame=show_frame,
validation_toolbar_height=validation_toolbar_height,
default=default,
accept_default=accept_default,
pre_run=pre_run,
Expand Down
8 changes: 5 additions & 3 deletions src/prompt_toolkit/widgets/toolbars.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
UIContent,
UIControl,
)
from prompt_toolkit.layout.dimension import Dimension
from prompt_toolkit.layout.dimension import AnyDimension, Dimension
from prompt_toolkit.layout.processors import BeforeInput
from prompt_toolkit.lexers import SimpleLexer
from prompt_toolkit.search import SearchDirection
Expand Down Expand Up @@ -342,7 +342,9 @@ def __pt_container__(self) -> Container:


class ValidationToolbar:
def __init__(self, show_position: bool = False) -> None:
def __init__(
self, show_position: bool = False, height: AnyDimension = 1
) -> None:
def get_formatted_text() -> StyleAndTextTuples:
buff = get_app().current_buffer

Expand All @@ -363,7 +365,7 @@ def get_formatted_text() -> StyleAndTextTuples:
self.control = FormattedTextControl(get_formatted_text)

self.container = ConditionalContainer(
content=Window(self.control, height=1), filter=has_validation_error
content=Window(self.control, height=height), filter=has_validation_error
)

def __pt_container__(self) -> Container:
Expand Down