diff options
| author | monster <[email protected]> | 2022-07-07 14:41:37 +0300 | 
|---|---|---|
| committer | monster <[email protected]> | 2022-07-07 14:41:37 +0300 | 
| commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
| tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets | |
| parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
fix ya.make
Diffstat (limited to 'contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets')
5 files changed, 0 insertions, 1896 deletions
| diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/__init__.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/__init__.py deleted file mode 100644 index 552d3559488..00000000000 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/__init__.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Collection of reusable components for building full screen applications. -These are higher level abstractions on top of the `prompt_toolkit.layout` -module. - -Most of these widgets implement the ``__pt_container__`` method, which makes it -possible to embed these in the layout like any other container. -""" -from .base import ( -    Box, -    Button, -    Checkbox, -    CheckboxList, -    Frame, -    HorizontalLine, -    Label, -    ProgressBar, -    RadioList, -    Shadow, -    TextArea, -    VerticalLine, -) -from .dialogs import Dialog -from .menus import MenuContainer, MenuItem -from .toolbars import ( -    ArgToolbar, -    CompletionsToolbar, -    FormattedTextToolbar, -    SearchToolbar, -    SystemToolbar, -    ValidationToolbar, -) - -__all__ = [ -    # Base. -    "TextArea", -    "Label", -    "Button", -    "Frame", -    "Shadow", -    "Box", -    "VerticalLine", -    "HorizontalLine", -    "CheckboxList", -    "RadioList", -    "Checkbox", -    "ProgressBar", -    # Toolbars. -    "ArgToolbar", -    "CompletionsToolbar", -    "FormattedTextToolbar", -    "SearchToolbar", -    "SystemToolbar", -    "ValidationToolbar", -    # Dialogs. -    "Dialog", -    # Menus. -    "MenuContainer", -    "MenuItem", -] diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/base.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/base.py deleted file mode 100644 index bd2d3322094..00000000000 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/base.py +++ /dev/null @@ -1,982 +0,0 @@ -""" -Collection of reusable components for building full screen applications. - -All of these widgets implement the ``__pt_container__`` method, which makes -them usable in any situation where we are expecting a `prompt_toolkit` -container object. - -.. warning:: - -    At this point, the API for these widgets is considered unstable, and can -    potentially change between minor releases (we try not too, but no -    guarantees are made yet). The public API in -    `prompt_toolkit.shortcuts.dialogs` on the other hand is considered stable. -""" -from functools import partial -from typing import Callable, Generic, List, Optional, Sequence, Tuple, TypeVar, Union - -from prompt_toolkit.application.current import get_app -from prompt_toolkit.auto_suggest import AutoSuggest, DynamicAutoSuggest -from prompt_toolkit.buffer import Buffer, BufferAcceptHandler -from prompt_toolkit.completion import Completer, DynamicCompleter -from prompt_toolkit.document import Document -from prompt_toolkit.filters import ( -    Condition, -    FilterOrBool, -    has_focus, -    is_done, -    is_true, -    to_filter, -) -from prompt_toolkit.formatted_text import ( -    AnyFormattedText, -    StyleAndTextTuples, -    Template, -    to_formatted_text, -) -from prompt_toolkit.formatted_text.utils import fragment_list_to_text -from prompt_toolkit.history import History -from prompt_toolkit.key_binding.key_bindings import KeyBindings -from prompt_toolkit.key_binding.key_processor import KeyPressEvent -from prompt_toolkit.keys import Keys -from prompt_toolkit.layout.containers import ( -    AnyContainer, -    ConditionalContainer, -    Container, -    DynamicContainer, -    Float, -    FloatContainer, -    HSplit, -    VSplit, -    Window, -    WindowAlign, -) -from prompt_toolkit.layout.controls import ( -    BufferControl, -    FormattedTextControl, -    GetLinePrefixCallable, -) -from prompt_toolkit.layout.dimension import AnyDimension -from prompt_toolkit.layout.dimension import Dimension as D -from prompt_toolkit.layout.dimension import to_dimension -from prompt_toolkit.layout.margins import ( -    ConditionalMargin, -    NumberedMargin, -    ScrollbarMargin, -) -from prompt_toolkit.layout.processors import ( -    AppendAutoSuggestion, -    BeforeInput, -    ConditionalProcessor, -    PasswordProcessor, -    Processor, -) -from prompt_toolkit.lexers import DynamicLexer, Lexer -from prompt_toolkit.mouse_events import MouseEvent, MouseEventType -from prompt_toolkit.utils import get_cwidth -from prompt_toolkit.validation import DynamicValidator, Validator - -from .toolbars import SearchToolbar - -__all__ = [ -    "TextArea", -    "Label", -    "Button", -    "Frame", -    "Shadow", -    "Box", -    "VerticalLine", -    "HorizontalLine", -    "RadioList", -    "CheckboxList", -    "Checkbox",  # backward compatibility -    "ProgressBar", -] - -E = KeyPressEvent - - -class Border: -    "Box drawing characters. (Thin)" -    HORIZONTAL = "\u2500" -    VERTICAL = "\u2502" -    TOP_LEFT = "\u250c" -    TOP_RIGHT = "\u2510" -    BOTTOM_LEFT = "\u2514" -    BOTTOM_RIGHT = "\u2518" - - -class TextArea: -    """ -    A simple input field. - -    This is a higher level abstraction on top of several other classes with -    sane defaults. - -    This widget does have the most common options, but it does not intend to -    cover every single use case. For more configurations options, you can -    always build a text area manually, using a -    :class:`~prompt_toolkit.buffer.Buffer`, -    :class:`~prompt_toolkit.layout.BufferControl` and -    :class:`~prompt_toolkit.layout.Window`. - -    Buffer attributes: - -    :param text: The initial text. -    :param multiline: If True, allow multiline input. -    :param completer: :class:`~prompt_toolkit.completion.Completer` instance -        for auto completion. -    :param complete_while_typing: Boolean. -    :param accept_handler: Called when `Enter` is pressed (This should be a -        callable that takes a buffer as input). -    :param history: :class:`~prompt_toolkit.history.History` instance. -    :param auto_suggest: :class:`~prompt_toolkit.auto_suggest.AutoSuggest` -        instance for input suggestions. - -    BufferControl attributes: - -    :param password: When `True`, display using asterisks. -    :param focusable: When `True`, allow this widget to receive the focus. -    :param focus_on_click: When `True`, focus after mouse click. -    :param input_processors: `None` or a list of -        :class:`~prompt_toolkit.layout.Processor` objects. -    :param validator: `None` or a :class:`~prompt_toolkit.validation.Validator` -        object. - -    Window attributes: - -    :param lexer: :class:`~prompt_toolkit.lexers.Lexer` instance for syntax -        highlighting. -    :param wrap_lines: When `True`, don't scroll horizontally, but wrap lines. -    :param width: Window width. (:class:`~prompt_toolkit.layout.Dimension` object.) -    :param height: Window height. (:class:`~prompt_toolkit.layout.Dimension` object.) -    :param scrollbar: When `True`, display a scroll bar. -    :param style: A style string. -    :param dont_extend_width: When `True`, don't take up more width then the -                              preferred width reported by the control. -    :param dont_extend_height: When `True`, don't take up more width then the -                               preferred height reported by the control. -    :param get_line_prefix: None or a callable that returns formatted text to -        be inserted before a line. It takes a line number (int) and a -        wrap_count and returns formatted text. This can be used for -        implementation of line continuations, things like Vim "breakindent" and -        so on. - -    Other attributes: - -    :param search_field: An optional `SearchToolbar` object. -    """ - -    def __init__( -        self, -        text: str = "", -        multiline: FilterOrBool = True, -        password: FilterOrBool = False, -        lexer: Optional[Lexer] = None, -        auto_suggest: Optional[AutoSuggest] = None, -        completer: Optional[Completer] = None, -        complete_while_typing: FilterOrBool = True, -        validator: Optional[Validator] = None, -        accept_handler: Optional[BufferAcceptHandler] = None, -        history: Optional[History] = None, -        focusable: FilterOrBool = True, -        focus_on_click: FilterOrBool = False, -        wrap_lines: FilterOrBool = True, -        read_only: FilterOrBool = False, -        width: AnyDimension = None, -        height: AnyDimension = None, -        dont_extend_height: FilterOrBool = False, -        dont_extend_width: FilterOrBool = False, -        line_numbers: bool = False, -        get_line_prefix: Optional[GetLinePrefixCallable] = None, -        scrollbar: bool = False, -        style: str = "", -        search_field: Optional[SearchToolbar] = None, -        preview_search: FilterOrBool = True, -        prompt: AnyFormattedText = "", -        input_processors: Optional[List[Processor]] = None, -    ) -> None: - -        if search_field is None: -            search_control = None -        elif isinstance(search_field, SearchToolbar): -            search_control = search_field.control - -        if input_processors is None: -            input_processors = [] - -        # Writeable attributes. -        self.completer = completer -        self.complete_while_typing = complete_while_typing -        self.lexer = lexer -        self.auto_suggest = auto_suggest -        self.read_only = read_only -        self.wrap_lines = wrap_lines -        self.validator = validator - -        self.buffer = Buffer( -            document=Document(text, 0), -            multiline=multiline, -            read_only=Condition(lambda: is_true(self.read_only)), -            completer=DynamicCompleter(lambda: self.completer), -            complete_while_typing=Condition( -                lambda: is_true(self.complete_while_typing) -            ), -            validator=DynamicValidator(lambda: self.validator), -            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest), -            accept_handler=accept_handler, -            history=history, -        ) - -        self.control = BufferControl( -            buffer=self.buffer, -            lexer=DynamicLexer(lambda: self.lexer), -            input_processors=[ -                ConditionalProcessor( -                    AppendAutoSuggestion(), has_focus(self.buffer) & ~is_done -                ), -                ConditionalProcessor( -                    processor=PasswordProcessor(), filter=to_filter(password) -                ), -                BeforeInput(prompt, style="class:text-area.prompt"), -            ] -            + input_processors, -            search_buffer_control=search_control, -            preview_search=preview_search, -            focusable=focusable, -            focus_on_click=focus_on_click, -        ) - -        if multiline: -            if scrollbar: -                right_margins = [ScrollbarMargin(display_arrows=True)] -            else: -                right_margins = [] -            if line_numbers: -                left_margins = [NumberedMargin()] -            else: -                left_margins = [] -        else: -            height = D.exact(1) -            left_margins = [] -            right_margins = [] - -        style = "class:text-area " + style - -        # If no height was given, guarantee height of at least 1. -        if height is None: -            height = D(min=1) - -        self.window = Window( -            height=height, -            width=width, -            dont_extend_height=dont_extend_height, -            dont_extend_width=dont_extend_width, -            content=self.control, -            style=style, -            wrap_lines=Condition(lambda: is_true(self.wrap_lines)), -            left_margins=left_margins, -            right_margins=right_margins, -            get_line_prefix=get_line_prefix, -        ) - -    @property -    def text(self) -> str: -        """ -        The `Buffer` text. -        """ -        return self.buffer.text - -    @text.setter -    def text(self, value: str) -> None: -        self.document = Document(value, 0) - -    @property -    def document(self) -> Document: -        """ -        The `Buffer` document (text + cursor position). -        """ -        return self.buffer.document - -    @document.setter -    def document(self, value: Document) -> None: -        self.buffer.set_document(value, bypass_readonly=True) - -    @property -    def accept_handler(self) -> Optional[BufferAcceptHandler]: -        """ -        The accept handler. Called when the user accepts the input. -        """ -        return self.buffer.accept_handler - -    @accept_handler.setter -    def accept_handler(self, value: BufferAcceptHandler) -> None: -        self.buffer.accept_handler = value - -    def __pt_container__(self) -> Container: -        return self.window - - -class Label: -    """ -    Widget that displays the given text. It is not editable or focusable. - -    :param text: Text to display. Can be multiline. All value types accepted by -        :class:`prompt_toolkit.layout.FormattedTextControl` are allowed, -        including a callable. -    :param style: A style string. -    :param width: When given, use this width, rather than calculating it from -        the text size. -    :param dont_extend_width: When `True`, don't take up more width than -                              preferred, i.e. the length of the longest line of -                              the text, or value of `width` parameter, if -                              given. `True` by default -    :param dont_extend_height: When `True`, don't take up more width than the -                               preferred height, i.e. the number of lines of -                               the text. `False` by default. -    """ - -    def __init__( -        self, -        text: AnyFormattedText, -        style: str = "", -        width: AnyDimension = None, -        dont_extend_height: bool = True, -        dont_extend_width: bool = False, -        align: Union[WindowAlign, Callable[[], WindowAlign]] = WindowAlign.LEFT, -        # There is no cursor navigation in a label, so it makes sense to always -        # wrap lines by default. -        wrap_lines: FilterOrBool = True, -    ) -> None: - -        self.text = text - -        def get_width() -> AnyDimension: -            if width is None: -                text_fragments = to_formatted_text(self.text) -                text = fragment_list_to_text(text_fragments) -                if text: -                    longest_line = max(get_cwidth(line) for line in text.splitlines()) -                else: -                    return D(preferred=0) -                return D(preferred=longest_line) -            else: -                return width - -        self.formatted_text_control = FormattedTextControl(text=lambda: self.text) - -        self.window = Window( -            content=self.formatted_text_control, -            width=get_width, -            height=D(min=1), -            style="class:label " + style, -            dont_extend_height=dont_extend_height, -            dont_extend_width=dont_extend_width, -            align=align, -            wrap_lines=wrap_lines, -        ) - -    def __pt_container__(self) -> Container: -        return self.window - - -class Button: -    """ -    Clickable button. - -    :param text: The caption for the button. -    :param handler: `None` or callable. Called when the button is clicked. No -        parameters are passed to this callable. Use for instance Python's -        `functools.partial` to pass parameters to this callable if needed. -    :param width: Width of the button. -    """ - -    def __init__( -        self, -        text: str, -        handler: Optional[Callable[[], None]] = None, -        width: int = 12, -        left_symbol: str = "<", -        right_symbol: str = ">", -    ) -> None: - -        self.text = text -        self.left_symbol = left_symbol -        self.right_symbol = right_symbol -        self.handler = handler -        self.width = width -        self.control = FormattedTextControl( -            self._get_text_fragments, -            key_bindings=self._get_key_bindings(), -            focusable=True, -        ) - -        def get_style() -> str: -            if get_app().layout.has_focus(self): -                return "class:button.focused" -            else: -                return "class:button" - -        # Note: `dont_extend_width` is False, because we want to allow buttons -        #       to take more space if the parent container provides more space. -        #       Otherwise, we will also truncate the text. -        #       Probably we need a better way here to adjust to width of the -        #       button to the text. - -        self.window = Window( -            self.control, -            align=WindowAlign.CENTER, -            height=1, -            width=width, -            style=get_style, -            dont_extend_width=False, -            dont_extend_height=True, -        ) - -    def _get_text_fragments(self) -> StyleAndTextTuples: -        width = self.width - ( -            get_cwidth(self.left_symbol) + get_cwidth(self.right_symbol) -        ) -        text = (f"{{:^{width}}}").format(self.text) - -        def handler(mouse_event: MouseEvent) -> None: -            if ( -                self.handler is not None -                and mouse_event.event_type == MouseEventType.MOUSE_UP -            ): -                self.handler() - -        return [ -            ("class:button.arrow", self.left_symbol, handler), -            ("[SetCursorPosition]", ""), -            ("class:button.text", text, handler), -            ("class:button.arrow", self.right_symbol, handler), -        ] - -    def _get_key_bindings(self) -> KeyBindings: -        "Key bindings for the Button." -        kb = KeyBindings() - -        @kb.add(" ") -        @kb.add("enter") -        def _(event: E) -> None: -            if self.handler is not None: -                self.handler() - -        return kb - -    def __pt_container__(self) -> Container: -        return self.window - - -class Frame: -    """ -    Draw a border around any container, optionally with a title text. - -    Changing the title and body of the frame is possible at runtime by -    assigning to the `body` and `title` attributes of this class. - -    :param body: Another container object. -    :param title: Text to be displayed in the top of the frame (can be formatted text). -    :param style: Style string to be applied to this widget. -    """ - -    def __init__( -        self, -        body: AnyContainer, -        title: AnyFormattedText = "", -        style: str = "", -        width: AnyDimension = None, -        height: AnyDimension = None, -        key_bindings: Optional[KeyBindings] = None, -        modal: bool = False, -    ) -> None: - -        self.title = title -        self.body = body - -        fill = partial(Window, style="class:frame.border") -        style = "class:frame " + style - -        top_row_with_title = VSplit( -            [ -                fill(width=1, height=1, char=Border.TOP_LEFT), -                fill(char=Border.HORIZONTAL), -                fill(width=1, height=1, char="|"), -                # Notice: we use `Template` here, because `self.title` can be an -                # `HTML` object for instance. -                Label( -                    lambda: Template(" {} ").format(self.title), -                    style="class:frame.label", -                    dont_extend_width=True, -                ), -                fill(width=1, height=1, char="|"), -                fill(char=Border.HORIZONTAL), -                fill(width=1, height=1, char=Border.TOP_RIGHT), -            ], -            height=1, -        ) - -        top_row_without_title = VSplit( -            [ -                fill(width=1, height=1, char=Border.TOP_LEFT), -                fill(char=Border.HORIZONTAL), -                fill(width=1, height=1, char=Border.TOP_RIGHT), -            ], -            height=1, -        ) - -        @Condition -        def has_title() -> bool: -            return bool(self.title) - -        self.container = HSplit( -            [ -                ConditionalContainer(content=top_row_with_title, filter=has_title), -                ConditionalContainer(content=top_row_without_title, filter=~has_title), -                VSplit( -                    [ -                        fill(width=1, char=Border.VERTICAL), -                        DynamicContainer(lambda: self.body), -                        fill(width=1, char=Border.VERTICAL), -                        # Padding is required to make sure that if the content is -                        # too small, the right frame border is still aligned. -                    ], -                    padding=0, -                ), -                VSplit( -                    [ -                        fill(width=1, height=1, char=Border.BOTTOM_LEFT), -                        fill(char=Border.HORIZONTAL), -                        fill(width=1, height=1, char=Border.BOTTOM_RIGHT), -                    ], -                    # specifying height here will increase the rendering speed. -                    height=1, -                ), -            ], -            width=width, -            height=height, -            style=style, -            key_bindings=key_bindings, -            modal=modal, -        ) - -    def __pt_container__(self) -> Container: -        return self.container - - -class Shadow: -    """ -    Draw a shadow underneath/behind this container. -    (This applies `class:shadow` the the cells under the shadow. The Style -    should define the colors for the shadow.) - -    :param body: Another container object. -    """ - -    def __init__(self, body: AnyContainer) -> None: -        self.container = FloatContainer( -            content=body, -            floats=[ -                Float( -                    bottom=-1, -                    height=1, -                    left=1, -                    right=-1, -                    transparent=True, -                    content=Window(style="class:shadow"), -                ), -                Float( -                    bottom=-1, -                    top=1, -                    width=1, -                    right=-1, -                    transparent=True, -                    content=Window(style="class:shadow"), -                ), -            ], -        ) - -    def __pt_container__(self) -> Container: -        return self.container - - -class Box: -    """ -    Add padding around a container. - -    This also makes sure that the parent can provide more space than required by -    the child. This is very useful when wrapping a small element with a fixed -    size into a ``VSplit`` or ``HSplit`` object. The ``HSplit`` and ``VSplit`` -    try to make sure to adapt respectively the width and height, possibly -    shrinking other elements. Wrapping something in a ``Box`` makes it flexible. - -    :param body: Another container object. -    :param padding: The margin to be used around the body. This can be -        overridden by `padding_left`, padding_right`, `padding_top` and -        `padding_bottom`. -    :param style: A style string. -    :param char: Character to be used for filling the space around the body. -        (This is supposed to be a character with a terminal width of 1.) -    """ - -    def __init__( -        self, -        body: AnyContainer, -        padding: AnyDimension = None, -        padding_left: AnyDimension = None, -        padding_right: AnyDimension = None, -        padding_top: AnyDimension = None, -        padding_bottom: AnyDimension = None, -        width: AnyDimension = None, -        height: AnyDimension = None, -        style: str = "", -        char: Union[None, str, Callable[[], str]] = None, -        modal: bool = False, -        key_bindings: Optional[KeyBindings] = None, -    ) -> None: - -        if padding is None: -            padding = D(preferred=0) - -        def get(value: AnyDimension) -> D: -            if value is None: -                value = padding -            return to_dimension(value) - -        self.padding_left = get(padding_left) -        self.padding_right = get(padding_right) -        self.padding_top = get(padding_top) -        self.padding_bottom = get(padding_bottom) -        self.body = body - -        self.container = HSplit( -            [ -                Window(height=self.padding_top, char=char), -                VSplit( -                    [ -                        Window(width=self.padding_left, char=char), -                        body, -                        Window(width=self.padding_right, char=char), -                    ] -                ), -                Window(height=self.padding_bottom, char=char), -            ], -            width=width, -            height=height, -            style=style, -            modal=modal, -            key_bindings=None, -        ) - -    def __pt_container__(self) -> Container: -        return self.container - - -_T = TypeVar("_T") - - -class _DialogList(Generic[_T]): -    """ -    Common code for `RadioList` and `CheckboxList`. -    """ - -    open_character: str = "" -    close_character: str = "" -    container_style: str = "" -    default_style: str = "" -    selected_style: str = "" -    checked_style: str = "" -    multiple_selection: bool = False -    show_scrollbar: bool = True - -    def __init__( -        self, -        values: Sequence[Tuple[_T, AnyFormattedText]], -        default_values: Optional[Sequence[_T]] = None, -    ) -> None: -        assert len(values) > 0 -        default_values = default_values or [] - -        self.values = values -        # current_values will be used in multiple_selection, -        # current_value will be used otherwise. -        keys: List[_T] = [value for (value, _) in values] -        self.current_values: List[_T] = [ -            value for value in default_values if value in keys -        ] -        self.current_value: _T = ( -            default_values[0] -            if len(default_values) and default_values[0] in keys -            else values[0][0] -        ) - -        # Cursor index: take first selected item or first item otherwise. -        if len(self.current_values) > 0: -            self._selected_index = keys.index(self.current_values[0]) -        else: -            self._selected_index = 0 - -        # Key bindings. -        kb = KeyBindings() - -        @kb.add("up") -        def _up(event: E) -> None: -            self._selected_index = max(0, self._selected_index - 1) - -        @kb.add("down") -        def _down(event: E) -> None: -            self._selected_index = min(len(self.values) - 1, self._selected_index + 1) - -        @kb.add("pageup") -        def _pageup(event: E) -> None: -            w = event.app.layout.current_window -            if w.render_info: -                self._selected_index = max( -                    0, self._selected_index - len(w.render_info.displayed_lines) -                ) - -        @kb.add("pagedown") -        def _pagedown(event: E) -> None: -            w = event.app.layout.current_window -            if w.render_info: -                self._selected_index = min( -                    len(self.values) - 1, -                    self._selected_index + len(w.render_info.displayed_lines), -                ) - -        @kb.add("enter") -        @kb.add(" ") -        def _click(event: E) -> None: -            self._handle_enter() - -        @kb.add(Keys.Any) -        def _find(event: E) -> None: -            # We first check values after the selected value, then all values. -            values = list(self.values) -            for value in values[self._selected_index + 1 :] + values: -                text = fragment_list_to_text(to_formatted_text(value[1])).lower() - -                if text.startswith(event.data.lower()): -                    self._selected_index = self.values.index(value) -                    return - -        # Control and window. -        self.control = FormattedTextControl( -            self._get_text_fragments, key_bindings=kb, focusable=True -        ) - -        self.window = Window( -            content=self.control, -            style=self.container_style, -            right_margins=[ -                ConditionalMargin( -                    margin=ScrollbarMargin(display_arrows=True), -                    filter=Condition(lambda: self.show_scrollbar), -                ), -            ], -            dont_extend_height=True, -        ) - -    def _handle_enter(self) -> None: -        if self.multiple_selection: -            val = self.values[self._selected_index][0] -            if val in self.current_values: -                self.current_values.remove(val) -            else: -                self.current_values.append(val) -        else: -            self.current_value = self.values[self._selected_index][0] - -    def _get_text_fragments(self) -> StyleAndTextTuples: -        def mouse_handler(mouse_event: MouseEvent) -> None: -            """ -            Set `_selected_index` and `current_value` according to the y -            position of the mouse click event. -            """ -            if mouse_event.event_type == MouseEventType.MOUSE_UP: -                self._selected_index = mouse_event.position.y -                self._handle_enter() - -        result: StyleAndTextTuples = [] -        for i, value in enumerate(self.values): -            if self.multiple_selection: -                checked = value[0] in self.current_values -            else: -                checked = value[0] == self.current_value -            selected = i == self._selected_index - -            style = "" -            if checked: -                style += " " + self.checked_style -            if selected: -                style += " " + self.selected_style - -            result.append((style, self.open_character)) - -            if selected: -                result.append(("[SetCursorPosition]", "")) - -            if checked: -                result.append((style, "*")) -            else: -                result.append((style, " ")) - -            result.append((style, self.close_character)) -            result.append((self.default_style, " ")) -            result.extend(to_formatted_text(value[1], style=self.default_style)) -            result.append(("", "\n")) - -        # Add mouse handler to all fragments. -        for i in range(len(result)): -            result[i] = (result[i][0], result[i][1], mouse_handler) - -        result.pop()  # Remove last newline. -        return result - -    def __pt_container__(self) -> Container: -        return self.window - - -class RadioList(_DialogList[_T]): -    """ -    List of radio buttons. Only one can be checked at the same time. - -    :param values: List of (value, label) tuples. -    """ - -    open_character = "(" -    close_character = ")" -    container_style = "class:radio-list" -    default_style = "class:radio" -    selected_style = "class:radio-selected" -    checked_style = "class:radio-checked" -    multiple_selection = False - -    def __init__( -        self, -        values: Sequence[Tuple[_T, AnyFormattedText]], -        default: Optional[_T] = None, -    ) -> None: -        if default is None: -            default_values = None -        else: -            default_values = [default] - -        super().__init__(values, default_values=default_values) - - -class CheckboxList(_DialogList[_T]): -    """ -    List of checkbox buttons. Several can be checked at the same time. - -    :param values: List of (value, label) tuples. -    """ - -    open_character = "[" -    close_character = "]" -    container_style = "class:checkbox-list" -    default_style = "class:checkbox" -    selected_style = "class:checkbox-selected" -    checked_style = "class:checkbox-checked" -    multiple_selection = True - - -class Checkbox(CheckboxList[str]): -    """Backward compatibility util: creates a 1-sized CheckboxList - -    :param text: the text -    """ - -    show_scrollbar = False - -    def __init__(self, text: AnyFormattedText = "", checked: bool = False) -> None: -        values = [("value", text)] -        super().__init__(values=values) -        self.checked = checked - -    @property -    def checked(self) -> bool: -        return "value" in self.current_values - -    @checked.setter -    def checked(self, value: bool) -> None: -        if value: -            self.current_values = ["value"] -        else: -            self.current_values = [] - - -class VerticalLine: -    """ -    A simple vertical line with a width of 1. -    """ - -    def __init__(self) -> None: -        self.window = Window( -            char=Border.VERTICAL, style="class:line,vertical-line", width=1 -        ) - -    def __pt_container__(self) -> Container: -        return self.window - - -class HorizontalLine: -    """ -    A simple horizontal line with a height of 1. -    """ - -    def __init__(self) -> None: -        self.window = Window( -            char=Border.HORIZONTAL, style="class:line,horizontal-line", height=1 -        ) - -    def __pt_container__(self) -> Container: -        return self.window - - -class ProgressBar: -    def __init__(self) -> None: -        self._percentage = 60 - -        self.label = Label("60%") -        self.container = FloatContainer( -            content=Window(height=1), -            floats=[ -                # We first draw the label, then the actual progress bar.  Right -                # now, this is the only way to have the colors of the progress -                # bar appear on top of the label. The problem is that our label -                # can't be part of any `Window` below. -                Float(content=self.label, top=0, bottom=0), -                Float( -                    left=0, -                    top=0, -                    right=0, -                    bottom=0, -                    content=VSplit( -                        [ -                            Window( -                                style="class:progress-bar.used", -                                width=lambda: D(weight=int(self._percentage)), -                            ), -                            Window( -                                style="class:progress-bar", -                                width=lambda: D(weight=int(100 - self._percentage)), -                            ), -                        ] -                    ), -                ), -            ], -        ) - -    @property -    def percentage(self) -> int: -        return self._percentage - -    @percentage.setter -    def percentage(self, value: int) -> None: -        self._percentage = value -        self.label.text = f"{value}%" - -    def __pt_container__(self) -> Container: -        return self.container diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/dialogs.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/dialogs.py deleted file mode 100644 index 920582b4e68..00000000000 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/dialogs.py +++ /dev/null @@ -1,106 +0,0 @@ -""" -Collection of reusable components for building full screen applications. -""" -from typing import Optional, Sequence, Union - -from prompt_toolkit.filters import has_completions, has_focus -from prompt_toolkit.formatted_text import AnyFormattedText -from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous -from prompt_toolkit.key_binding.key_bindings import KeyBindings -from prompt_toolkit.layout.containers import ( -    AnyContainer, -    DynamicContainer, -    HSplit, -    VSplit, -) -from prompt_toolkit.layout.dimension import AnyDimension -from prompt_toolkit.layout.dimension import Dimension as D - -from .base import Box, Button, Frame, Shadow - -__all__ = [ -    "Dialog", -] - - -class Dialog: -    """ -    Simple dialog window. This is the base for input dialogs, message dialogs -    and confirmation dialogs. - -    Changing the title and body of the dialog is possible at runtime by -    assigning to the `body` and `title` attributes of this class. - -    :param body: Child container object. -    :param title: Text to be displayed in the heading of the dialog. -    :param buttons: A list of `Button` widgets, displayed at the bottom. -    """ - -    def __init__( -        self, -        body: AnyContainer, -        title: AnyFormattedText = "", -        buttons: Optional[Sequence[Button]] = None, -        modal: bool = True, -        width: AnyDimension = None, -        with_background: bool = False, -    ) -> None: - -        self.body = body -        self.title = title - -        buttons = buttons or [] - -        # When a button is selected, handle left/right key bindings. -        buttons_kb = KeyBindings() -        if len(buttons) > 1: -            first_selected = has_focus(buttons[0]) -            last_selected = has_focus(buttons[-1]) - -            buttons_kb.add("left", filter=~first_selected)(focus_previous) -            buttons_kb.add("right", filter=~last_selected)(focus_next) - -        frame_body: AnyContainer -        if buttons: -            frame_body = HSplit( -                [ -                    # Add optional padding around the body. -                    Box( -                        body=DynamicContainer(lambda: self.body), -                        padding=D(preferred=1, max=1), -                        padding_bottom=0, -                    ), -                    # The buttons. -                    Box( -                        body=VSplit(buttons, padding=1, key_bindings=buttons_kb), -                        height=D(min=1, max=3, preferred=3), -                    ), -                ] -            ) -        else: -            frame_body = body - -        # Key bindings for whole dialog. -        kb = KeyBindings() -        kb.add("tab", filter=~has_completions)(focus_next) -        kb.add("s-tab", filter=~has_completions)(focus_previous) - -        frame = Shadow( -            body=Frame( -                title=lambda: self.title, -                body=frame_body, -                style="class:dialog.body", -                width=(None if with_background is None else width), -                key_bindings=kb, -                modal=modal, -            ) -        ) - -        self.container: Union[Box, Shadow] -        if with_background: -            self.container = Box(body=frame, style="class:dialog", width=width) -        else: -            self.container = frame - -    def __pt_container__(self) -> AnyContainer: -        return self.container diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/menus.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/menus.py deleted file mode 100644 index 6827ebecc7c..00000000000 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/menus.py +++ /dev/null @@ -1,374 +0,0 @@ -from typing import Callable, Iterable, List, Optional, Sequence, Union - -from prompt_toolkit.application.current import get_app -from prompt_toolkit.filters import Condition -from prompt_toolkit.formatted_text.base import OneStyleAndTextTuple, StyleAndTextTuples -from prompt_toolkit.key_binding.key_bindings import KeyBindings, KeyBindingsBase -from prompt_toolkit.key_binding.key_processor import KeyPressEvent -from prompt_toolkit.keys import Keys -from prompt_toolkit.layout.containers import ( -    AnyContainer, -    ConditionalContainer, -    Container, -    Float, -    FloatContainer, -    HSplit, -    Window, -) -from prompt_toolkit.layout.controls import FormattedTextControl -from prompt_toolkit.mouse_events import MouseEvent, MouseEventType -from prompt_toolkit.utils import get_cwidth -from prompt_toolkit.widgets import Shadow - -from .base import Border - -__all__ = [ -    "MenuContainer", -    "MenuItem", -] - -E = KeyPressEvent - - -class MenuContainer: -    """ -    :param floats: List of extra Float objects to display. -    :param menu_items: List of `MenuItem` objects. -    """ - -    def __init__( -        self, -        body: AnyContainer, -        menu_items: List["MenuItem"], -        floats: Optional[List[Float]] = None, -        key_bindings: Optional[KeyBindingsBase] = None, -    ) -> None: - -        self.body = body -        self.menu_items = menu_items -        self.selected_menu = [0] - -        # Key bindings. -        kb = KeyBindings() - -        @Condition -        def in_main_menu() -> bool: -            return len(self.selected_menu) == 1 - -        @Condition -        def in_sub_menu() -> bool: -            return len(self.selected_menu) > 1 - -        # Navigation through the main menu. - -        @kb.add("left", filter=in_main_menu) -        def _left(event: E) -> None: -            self.selected_menu[0] = max(0, self.selected_menu[0] - 1) - -        @kb.add("right", filter=in_main_menu) -        def _right(event: E) -> None: -            self.selected_menu[0] = min( -                len(self.menu_items) - 1, self.selected_menu[0] + 1 -            ) - -        @kb.add("down", filter=in_main_menu) -        def _down(event: E) -> None: -            self.selected_menu.append(0) - -        @kb.add("c-c", filter=in_main_menu) -        @kb.add("c-g", filter=in_main_menu) -        def _cancel(event: E) -> None: -            "Leave menu." -            event.app.layout.focus_last() - -        # Sub menu navigation. - -        @kb.add("left", filter=in_sub_menu) -        @kb.add("c-g", filter=in_sub_menu) -        @kb.add("c-c", filter=in_sub_menu) -        def _back(event: E) -> None: -            "Go back to parent menu." -            if len(self.selected_menu) > 1: -                self.selected_menu.pop() - -        @kb.add("right", filter=in_sub_menu) -        def _submenu(event: E) -> None: -            "go into sub menu." -            if self._get_menu(len(self.selected_menu) - 1).children: -                self.selected_menu.append(0) - -            # If This item does not have a sub menu. Go up in the parent menu. -            elif ( -                len(self.selected_menu) == 2 -                and self.selected_menu[0] < len(self.menu_items) - 1 -            ): -                self.selected_menu = [ -                    min(len(self.menu_items) - 1, self.selected_menu[0] + 1) -                ] -                if self.menu_items[self.selected_menu[0]].children: -                    self.selected_menu.append(0) - -        @kb.add("up", filter=in_sub_menu) -        def _up_in_submenu(event: E) -> None: -            "Select previous (enabled) menu item or return to main menu." -            # Look for previous enabled items in this sub menu. -            menu = self._get_menu(len(self.selected_menu) - 2) -            index = self.selected_menu[-1] - -            previous_indexes = [ -                i -                for i, item in enumerate(menu.children) -                if i < index and not item.disabled -            ] - -            if previous_indexes: -                self.selected_menu[-1] = previous_indexes[-1] -            elif len(self.selected_menu) == 2: -                # Return to main menu. -                self.selected_menu.pop() - -        @kb.add("down", filter=in_sub_menu) -        def _down_in_submenu(event: E) -> None: -            "Select next (enabled) menu item." -            menu = self._get_menu(len(self.selected_menu) - 2) -            index = self.selected_menu[-1] - -            next_indexes = [ -                i -                for i, item in enumerate(menu.children) -                if i > index and not item.disabled -            ] - -            if next_indexes: -                self.selected_menu[-1] = next_indexes[0] - -        @kb.add("enter") -        def _click(event: E) -> None: -            "Click the selected menu item." -            item = self._get_menu(len(self.selected_menu) - 1) -            if item.handler: -                event.app.layout.focus_last() -                item.handler() - -        # Controls. -        self.control = FormattedTextControl( -            self._get_menu_fragments, key_bindings=kb, focusable=True, show_cursor=False -        ) - -        self.window = Window(height=1, content=self.control, style="class:menu-bar") - -        submenu = self._submenu(0) -        submenu2 = self._submenu(1) -        submenu3 = self._submenu(2) - -        @Condition -        def has_focus() -> bool: -            return get_app().layout.current_window == self.window - -        self.container = FloatContainer( -            content=HSplit( -                [ -                    # The titlebar. -                    self.window, -                    # The 'body', like defined above. -                    body, -                ] -            ), -            floats=[ -                Float( -                    xcursor=True, -                    ycursor=True, -                    content=ConditionalContainer( -                        content=Shadow(body=submenu), filter=has_focus -                    ), -                ), -                Float( -                    attach_to_window=submenu, -                    xcursor=True, -                    ycursor=True, -                    allow_cover_cursor=True, -                    content=ConditionalContainer( -                        content=Shadow(body=submenu2), -                        filter=has_focus -                        & Condition(lambda: len(self.selected_menu) >= 1), -                    ), -                ), -                Float( -                    attach_to_window=submenu2, -                    xcursor=True, -                    ycursor=True, -                    allow_cover_cursor=True, -                    content=ConditionalContainer( -                        content=Shadow(body=submenu3), -                        filter=has_focus -                        & Condition(lambda: len(self.selected_menu) >= 2), -                    ), -                ), -                # -- -            ] -            + (floats or []), -            key_bindings=key_bindings, -        ) - -    def _get_menu(self, level: int) -> "MenuItem": -        menu = self.menu_items[self.selected_menu[0]] - -        for i, index in enumerate(self.selected_menu[1:]): -            if i < level: -                try: -                    menu = menu.children[index] -                except IndexError: -                    return MenuItem("debug") - -        return menu - -    def _get_menu_fragments(self) -> StyleAndTextTuples: -        focused = get_app().layout.has_focus(self.window) - -        # This is called during the rendering. When we discover that this -        # widget doesn't have the focus anymore. Reset menu state. -        if not focused: -            self.selected_menu = [0] - -        # Generate text fragments for the main menu. -        def one_item(i: int, item: MenuItem) -> Iterable[OneStyleAndTextTuple]: -            def mouse_handler(mouse_event: MouseEvent) -> None: -                hover = mouse_event.event_type == MouseEventType.MOUSE_MOVE -                if ( -                    mouse_event.event_type == MouseEventType.MOUSE_DOWN -                    or hover -                    and focused -                ): -                    # Toggle focus. -                    app = get_app() -                    if not hover: -                        if app.layout.has_focus(self.window): -                            if self.selected_menu == [i]: -                                app.layout.focus_last() -                        else: -                            app.layout.focus(self.window) -                    self.selected_menu = [i] - -            yield ("class:menu-bar", " ", mouse_handler) -            if i == self.selected_menu[0] and focused: -                yield ("[SetMenuPosition]", "", mouse_handler) -                style = "class:menu-bar.selected-item" -            else: -                style = "class:menu-bar" -            yield style, item.text, mouse_handler - -        result: StyleAndTextTuples = [] -        for i, item in enumerate(self.menu_items): -            result.extend(one_item(i, item)) - -        return result - -    def _submenu(self, level: int = 0) -> Window: -        def get_text_fragments() -> StyleAndTextTuples: -            result: StyleAndTextTuples = [] -            if level < len(self.selected_menu): -                menu = self._get_menu(level) -                if menu.children: -                    result.append(("class:menu", Border.TOP_LEFT)) -                    result.append(("class:menu", Border.HORIZONTAL * (menu.width + 4))) -                    result.append(("class:menu", Border.TOP_RIGHT)) -                    result.append(("", "\n")) -                    try: -                        selected_item = self.selected_menu[level + 1] -                    except IndexError: -                        selected_item = -1 - -                    def one_item( -                        i: int, item: MenuItem -                    ) -> Iterable[OneStyleAndTextTuple]: -                        def mouse_handler(mouse_event: MouseEvent) -> None: -                            if item.disabled: -                                # The arrow keys can't interact with menu items that are disabled. -                                # The mouse shouldn't be able to either. -                                return -                            hover = mouse_event.event_type == MouseEventType.MOUSE_MOVE -                            if ( -                                mouse_event.event_type == MouseEventType.MOUSE_UP -                                or hover -                            ): -                                app = get_app() -                                if not hover and item.handler: -                                    app.layout.focus_last() -                                    item.handler() -                                else: -                                    self.selected_menu = self.selected_menu[ -                                        : level + 1 -                                    ] + [i] - -                        if i == selected_item: -                            yield ("[SetCursorPosition]", "") -                            style = "class:menu-bar.selected-item" -                        else: -                            style = "" - -                        yield ("class:menu", Border.VERTICAL) -                        if item.text == "-": -                            yield ( -                                style + "class:menu-border", -                                f"{Border.HORIZONTAL * (menu.width + 3)}", -                                mouse_handler, -                            ) -                        else: -                            yield ( -                                style, -                                f" {item.text}".ljust(menu.width + 3), -                                mouse_handler, -                            ) - -                        if item.children: -                            yield (style, ">", mouse_handler) -                        else: -                            yield (style, " ", mouse_handler) - -                        if i == selected_item: -                            yield ("[SetMenuPosition]", "") -                        yield ("class:menu", Border.VERTICAL) - -                        yield ("", "\n") - -                    for i, item in enumerate(menu.children): -                        result.extend(one_item(i, item)) - -                    result.append(("class:menu", Border.BOTTOM_LEFT)) -                    result.append(("class:menu", Border.HORIZONTAL * (menu.width + 4))) -                    result.append(("class:menu", Border.BOTTOM_RIGHT)) -            return result - -        return Window(FormattedTextControl(get_text_fragments), style="class:menu") - -    @property -    def floats(self) -> Optional[List[Float]]: -        return self.container.floats - -    def __pt_container__(self) -> Container: -        return self.container - - -class MenuItem: -    def __init__( -        self, -        text: str = "", -        handler: Optional[Callable[[], None]] = None, -        children: Optional[List["MenuItem"]] = None, -        shortcut: Optional[Sequence[Union[Keys, str]]] = None, -        disabled: bool = False, -    ) -> None: - -        self.text = text -        self.handler = handler -        self.children = children or [] -        self.shortcut = shortcut -        self.disabled = disabled -        self.selected_item = 0 - -    @property -    def width(self) -> int: -        if self.children: -            return max(get_cwidth(c.text) for c in self.children) -        else: -            return 0 diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/toolbars.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/toolbars.py deleted file mode 100644 index 402ecaa9824..00000000000 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/widgets/toolbars.py +++ /dev/null @@ -1,374 +0,0 @@ -from typing import Any, Optional - -from prompt_toolkit.application.current import get_app -from prompt_toolkit.buffer import Buffer -from prompt_toolkit.enums import SYSTEM_BUFFER -from prompt_toolkit.filters import ( -    Condition, -    FilterOrBool, -    emacs_mode, -    has_arg, -    has_completions, -    has_focus, -    has_validation_error, -    to_filter, -    vi_mode, -    vi_navigation_mode, -) -from prompt_toolkit.formatted_text import ( -    AnyFormattedText, -    StyleAndTextTuples, -    fragment_list_len, -    to_formatted_text, -) -from prompt_toolkit.key_binding.key_bindings import ( -    ConditionalKeyBindings, -    KeyBindings, -    KeyBindingsBase, -    merge_key_bindings, -) -from prompt_toolkit.key_binding.key_processor import KeyPressEvent -from prompt_toolkit.key_binding.vi_state import InputMode -from prompt_toolkit.keys import Keys -from prompt_toolkit.layout.containers import ConditionalContainer, Container, Window -from prompt_toolkit.layout.controls import ( -    BufferControl, -    FormattedTextControl, -    SearchBufferControl, -    UIContent, -    UIControl, -) -from prompt_toolkit.layout.dimension import Dimension -from prompt_toolkit.layout.processors import BeforeInput -from prompt_toolkit.lexers import SimpleLexer -from prompt_toolkit.search import SearchDirection - -__all__ = [ -    "ArgToolbar", -    "CompletionsToolbar", -    "FormattedTextToolbar", -    "SearchToolbar", -    "SystemToolbar", -    "ValidationToolbar", -] - -E = KeyPressEvent - - -class FormattedTextToolbar(Window): -    def __init__(self, text: AnyFormattedText, style: str = "", **kw: Any) -> None: -        # Note: The style needs to be applied to the toolbar as a whole, not -        #       just the `FormattedTextControl`. -        super().__init__( -            FormattedTextControl(text, **kw), -            style=style, -            dont_extend_height=True, -            height=Dimension(min=1), -        ) - - -class SystemToolbar: -    """ -    Toolbar for a system prompt. - -    :param prompt: Prompt to be displayed to the user. -    """ - -    def __init__( -        self, -        prompt: AnyFormattedText = "Shell command: ", -        enable_global_bindings: FilterOrBool = True, -    ) -> None: - -        self.prompt = prompt -        self.enable_global_bindings = to_filter(enable_global_bindings) - -        self.system_buffer = Buffer(name=SYSTEM_BUFFER) - -        self._bindings = self._build_key_bindings() - -        self.buffer_control = BufferControl( -            buffer=self.system_buffer, -            lexer=SimpleLexer(style="class:system-toolbar.text"), -            input_processors=[ -                BeforeInput(lambda: self.prompt, style="class:system-toolbar") -            ], -            key_bindings=self._bindings, -        ) - -        self.window = Window( -            self.buffer_control, height=1, style="class:system-toolbar" -        ) - -        self.container = ConditionalContainer( -            content=self.window, filter=has_focus(self.system_buffer) -        ) - -    def _get_display_before_text(self) -> StyleAndTextTuples: -        return [ -            ("class:system-toolbar", "Shell command: "), -            ("class:system-toolbar.text", self.system_buffer.text), -            ("", "\n"), -        ] - -    def _build_key_bindings(self) -> KeyBindingsBase: -        focused = has_focus(self.system_buffer) - -        # Emacs -        emacs_bindings = KeyBindings() -        handle = emacs_bindings.add - -        @handle("escape", filter=focused) -        @handle("c-g", filter=focused) -        @handle("c-c", filter=focused) -        def _cancel(event: E) -> None: -            "Hide system prompt." -            self.system_buffer.reset() -            event.app.layout.focus_last() - -        @handle("enter", filter=focused) -        async def _accept(event: E) -> None: -            "Run system command." -            await event.app.run_system_command( -                self.system_buffer.text, -                display_before_text=self._get_display_before_text(), -            ) -            self.system_buffer.reset(append_to_history=True) -            event.app.layout.focus_last() - -        # Vi. -        vi_bindings = KeyBindings() -        handle = vi_bindings.add - -        @handle("escape", filter=focused) -        @handle("c-c", filter=focused) -        def _cancel_vi(event: E) -> None: -            "Hide system prompt." -            event.app.vi_state.input_mode = InputMode.NAVIGATION -            self.system_buffer.reset() -            event.app.layout.focus_last() - -        @handle("enter", filter=focused) -        async def _accept_vi(event: E) -> None: -            "Run system command." -            event.app.vi_state.input_mode = InputMode.NAVIGATION -            await event.app.run_system_command( -                self.system_buffer.text, -                display_before_text=self._get_display_before_text(), -            ) -            self.system_buffer.reset(append_to_history=True) -            event.app.layout.focus_last() - -        # Global bindings. (Listen to these bindings, even when this widget is -        # not focussed.) -        global_bindings = KeyBindings() -        handle = global_bindings.add - -        @handle(Keys.Escape, "!", filter=~focused & emacs_mode, is_global=True) -        def _focus_me(event: E) -> None: -            "M-'!' will focus this user control." -            event.app.layout.focus(self.window) - -        @handle("!", filter=~focused & vi_mode & vi_navigation_mode, is_global=True) -        def _focus_me_vi(event: E) -> None: -            "Focus." -            event.app.vi_state.input_mode = InputMode.INSERT -            event.app.layout.focus(self.window) - -        return merge_key_bindings( -            [ -                ConditionalKeyBindings(emacs_bindings, emacs_mode), -                ConditionalKeyBindings(vi_bindings, vi_mode), -                ConditionalKeyBindings(global_bindings, self.enable_global_bindings), -            ] -        ) - -    def __pt_container__(self) -> Container: -        return self.container - - -class ArgToolbar: -    def __init__(self) -> None: -        def get_formatted_text() -> StyleAndTextTuples: -            arg = get_app().key_processor.arg or "" -            if arg == "-": -                arg = "-1" - -            return [ -                ("class:arg-toolbar", "Repeat: "), -                ("class:arg-toolbar.text", arg), -            ] - -        self.window = Window(FormattedTextControl(get_formatted_text), height=1) - -        self.container = ConditionalContainer(content=self.window, filter=has_arg) - -    def __pt_container__(self) -> Container: -        return self.container - - -class SearchToolbar: -    """ -    :param vi_mode: Display '/' and '?' instead of I-search. -    :param ignore_case: Search case insensitive. -    """ - -    def __init__( -        self, -        search_buffer: Optional[Buffer] = None, -        vi_mode: bool = False, -        text_if_not_searching: AnyFormattedText = "", -        forward_search_prompt: AnyFormattedText = "I-search: ", -        backward_search_prompt: AnyFormattedText = "I-search backward: ", -        ignore_case: FilterOrBool = False, -    ) -> None: - -        if search_buffer is None: -            search_buffer = Buffer() - -        @Condition -        def is_searching() -> bool: -            return self.control in get_app().layout.search_links - -        def get_before_input() -> AnyFormattedText: -            if not is_searching(): -                return text_if_not_searching -            elif ( -                self.control.searcher_search_state.direction == SearchDirection.BACKWARD -            ): -                return "?" if vi_mode else backward_search_prompt -            else: -                return "/" if vi_mode else forward_search_prompt - -        self.search_buffer = search_buffer - -        self.control = SearchBufferControl( -            buffer=search_buffer, -            input_processors=[ -                BeforeInput(get_before_input, style="class:search-toolbar.prompt") -            ], -            lexer=SimpleLexer(style="class:search-toolbar.text"), -            ignore_case=ignore_case, -        ) - -        self.container = ConditionalContainer( -            content=Window(self.control, height=1, style="class:search-toolbar"), -            filter=is_searching, -        ) - -    def __pt_container__(self) -> Container: -        return self.container - - -class _CompletionsToolbarControl(UIControl): -    def create_content(self, width: int, height: int) -> UIContent: -        all_fragments: StyleAndTextTuples = [] - -        complete_state = get_app().current_buffer.complete_state -        if complete_state: -            completions = complete_state.completions -            index = complete_state.complete_index  # Can be None! - -            # Width of the completions without the left/right arrows in the margins. -            content_width = width - 6 - -            # Booleans indicating whether we stripped from the left/right -            cut_left = False -            cut_right = False - -            # Create Menu content. -            fragments: StyleAndTextTuples = [] - -            for i, c in enumerate(completions): -                # When there is no more place for the next completion -                if fragment_list_len(fragments) + len(c.display_text) >= content_width: -                    # If the current one was not yet displayed, page to the next sequence. -                    if i <= (index or 0): -                        fragments = [] -                        cut_left = True -                    # If the current one is visible, stop here. -                    else: -                        cut_right = True -                        break - -                fragments.extend( -                    to_formatted_text( -                        c.display_text, -                        style=( -                            "class:completion-toolbar.completion.current" -                            if i == index -                            else "class:completion-toolbar.completion" -                        ), -                    ) -                ) -                fragments.append(("", " ")) - -            # Extend/strip until the content width. -            fragments.append(("", " " * (content_width - fragment_list_len(fragments)))) -            fragments = fragments[:content_width] - -            # Return fragments -            all_fragments.append(("", " ")) -            all_fragments.append( -                ("class:completion-toolbar.arrow", "<" if cut_left else " ") -            ) -            all_fragments.append(("", " ")) - -            all_fragments.extend(fragments) - -            all_fragments.append(("", " ")) -            all_fragments.append( -                ("class:completion-toolbar.arrow", ">" if cut_right else " ") -            ) -            all_fragments.append(("", " ")) - -        def get_line(i: int) -> StyleAndTextTuples: -            return all_fragments - -        return UIContent(get_line=get_line, line_count=1) - - -class CompletionsToolbar: -    def __init__(self) -> None: -        self.container = ConditionalContainer( -            content=Window( -                _CompletionsToolbarControl(), height=1, style="class:completion-toolbar" -            ), -            filter=has_completions, -        ) - -    def __pt_container__(self) -> Container: -        return self.container - - -class ValidationToolbar: -    def __init__(self, show_position: bool = False) -> None: -        def get_formatted_text() -> StyleAndTextTuples: -            buff = get_app().current_buffer - -            if buff.validation_error: -                row, column = buff.document.translate_index_to_position( -                    buff.validation_error.cursor_position -                ) - -                if show_position: -                    text = "{} (line={} column={})".format( -                        buff.validation_error.message, -                        row + 1, -                        column + 1, -                    ) -                else: -                    text = buff.validation_error.message - -                return [("class:validation-toolbar", text)] -            else: -                return [] - -        self.control = FormattedTextControl(get_formatted_text) - -        self.container = ConditionalContainer( -            content=Window(self.control, height=1), filter=has_validation_error -        ) - -    def __pt_container__(self) -> Container: -        return self.container | 
