Exemple #1
0
def meta_enter_message(python_input: "PythonInput") -> Container:
    """
    Create the `Layout` for the 'Meta+Enter` message.
    """
    def get_text_fragments() -> StyleAndTextTuples:
        return [("class:accept-message", " [Meta+Enter] Execute ")]

    @Condition
    def extra_condition() -> bool:
        " Only show when... "
        b = python_input.default_buffer

        return (python_input.show_meta_enter_message
                and (not b.document.is_cursor_at_the_end
                     or python_input.accept_input_on_enter is None)
                and "\n" in b.text)

    visible = ~is_done & has_focus(DEFAULT_BUFFER) & extra_condition

    return ConditionalContainer(content=Window(
        FormattedTextControl(get_text_fragments)),
                                filter=visible)
Exemple #2
0
def show_sidebar_button_info(my_app: "sqlApp") -> Container:
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """

    @if_mousedown
    def toggle_sidebar(mouse_event: MouseEvent) -> None:
        " Click handler for the menu. "
        my_app.show_sidebar = not my_app.show_sidebar

    # TO DO: app version rather than python
    version = sys.version_info
    tokens: StyleAndTextTuples = [
            ("class:status-toolbar.key", "[C-t]", toggle_sidebar),
            ("class:status-toolbar", " Object Browser", toggle_sidebar),
            ("class:status-toolbar", " - "),
            ("class:status-toolbar.cli-version", "odbcli %s" % __version__),
            ("class:status-toolbar", " "),
            ]
    width = fragment_list_width(tokens)

    def get_text_fragments() -> StyleAndTextTuples:
        # Python version
        return tokens

    return ConditionalContainer(
            content=Window(
                FormattedTextControl(get_text_fragments),
                style="class:status-toolbar",
                height=Dimension.exact(1),
                width=Dimension.exact(width),
                ),
            filter=~is_done
            & Condition(
                lambda: not my_app.show_exit_confirmation
            )
            & renderer_height_is_known
            )
Exemple #3
0
 def create_tutorial_layout(self):
     """ layout for example tutorial """
     lexer, _, _ = get_lexers(self.shell_ctx.lexer, None, None)
     layout_full = HSplit([
         FloatContainer(
             Window(
                 BufferControl(
                     input_processors=self.input_processors,
                     lexer=lexer,
                     preview_search=Always()),
                 get_height=get_height),
             [
                 Float(xcursor=True,
                       ycursor=True,
                       content=CompletionsMenu(
                           max_height=MAX_COMPLETION,
                           scroll_offset=1,
                           extra_filter=(HasFocus(DEFAULT_BUFFER))))]),
         ConditionalContainer(
             HSplit([
                 get_hline(),
                 get_param(lexer),
                 get_hline(),
                 Window(
                     content=BufferControl(
                         buffer_name='example_line',
                         lexer=lexer
                     ),
                 ),
                 Window(
                     TokenListControl(
                         get_tutorial_tokens,
                         default_char=Char(' ', Token.Toolbar)),
                     height=LayoutDimension.exact(1)),
             ]),
             filter=~IsDone() & RendererHeightIsKnown()
         )
     ])
     return layout_full
Exemple #4
0
def meta_enter_message(python_input):
    """
    Create the `Layout` for the 'Meta+Enter` message.
    """
    def get_tokens(cli):
        return [(Token.AcceptMessage, ' [Meta+Enter] Execute ')]

    def extra_condition(cli):
        " Only show when... "
        b = cli.buffers[DEFAULT_BUFFER]

        return (
            python_input.show_meta_enter_message and
            (not b.document.is_cursor_at_the_end or
                python_input.accept_input_on_enter is None) and
            b.is_multiline())

    visible = ~IsDone() & HasFocus(DEFAULT_BUFFER) & Condition(extra_condition)

    return ConditionalContainer(
        content=Window(TokenListControl(get_tokens)),
        filter=visible)
def select_prompt(message, options, mark='>'):
    control = SelectControl(options)

    def get_formatted_text():
        return control.select_option_text(mark)

    layout = Layout(
        HSplit([
            Window(
                height=Dimension.exact(1),
                content=FormattedTextControl(lambda: message + '\n',
                                             show_cursor=False),
            ),
            Window(height=Dimension.exact(len(control.options)),
                   content=FormattedTextControl(get_formatted_text)),
            ConditionalContainer(Window(control), filter=~IsDone())
        ]))

    app = Application(layout=layout,
                      key_bindings=control.key_bindings,
                      full_screen=False)
    return app.run()
    def __init__(self,
                 search_buffer=None,
                 vi_mode=False,
                 text_if_not_searching='',
                 forward_search_prompt='I-search: ',
                 backward_search_prompt='I-search backward: ',
                 ignore_case=False):
        assert search_buffer is None or isinstance(search_buffer, Buffer)

        if search_buffer is None:
            search_buffer = Buffer()

        @Condition
        def is_searching():
            return self.control in get_app().layout.search_links

        def get_before_input():
            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)
Exemple #7
0
def show_sidebar_button_info(python_input):
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    def toggle_sidebar(cli, mouse_event):
        " Click handler for the menu. "
        if mouse_event.event_type == MouseEventTypes.MOUSE_DOWN:
            python_input.show_sidebar = not python_input.show_sidebar
        else:
            return NotImplemented

    token = Token.Toolbar.Status

    version = sys.version_info
    tokens = [
        (token.Key, '[F2]', toggle_sidebar),
        (token, ' Menu', toggle_sidebar),
        (token, ' - '),
        (token.PythonVersion,
         '%s %i.%i.%i' % (platform.python_implementation(), version[0],
                          version[1], version[2])),
        (token, ' '),
    ]
    width = token_list_width(tokens)

    def get_tokens(cli):
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(TokenListControl(get_tokens,
                                        default_char=Char(token=token)),
                       height=LayoutDimension.exact(1),
                       width=LayoutDimension.exact(width)),
        filter=~IsDone() & RendererHeightIsKnown()
        & Condition(lambda cli: python_input.show_status_bar and
                    not python_input.show_exit_confirmation))
Exemple #8
0
def create_exit_confirmation(
    python_input: "PythonInput", style="class:exit-confirmation"
) -> Container:
    """
    Create `Layout` for the exit message.
    """

    def get_text_fragments() -> StyleAndTextTuples:
        # Show "Do you really want to exit?"
        return [
            (style, "\n %s ([y]/n) " % python_input.exit_message),
            ("[SetCursorPosition]", ""),
            (style, "  \n"),
        ]

    visible = ~is_done & Condition(lambda: python_input.show_exit_confirmation)

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments, focusable=True), style=style
        ),
        filter=visible,
    )
    def __init__(self, prompt='Shell command: ', enable_global_bindings=True):
        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 __init__(self, show_position=False):
        def get_formatted_text():
            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 = '%s (line=%s column=%s)' % (
                        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)
Exemple #11
0
    def __init__(self,
                 app=None,
                 show=False,
                 height=Dimension(preferred=22),
                 width=Dimension(preferred=25)):
        self.app = app
        self.show = show
        self.cursor_line = 0
        self.lexer = DisassemblyLexer(self)
        self.buffer = Buffer(document=Document(),
                             multiline=True)
        self.control = BufferControl(buffer=self.buffer,
                                     focusable=True,
                                     lexer=self.lexer,
                                     focus_on_click=True)
        self.window = Window(content=self.control,
                             height=height,
                             wrap_lines=False,
                             scroll_offsets = ScrollOffsets(top=0))

        self.info = InfoLine('[Disassembly]', width=240)
        self.container = ConditionalContainer(
            content=HSplit([self.info.get_ui(), self.window]),
            filter=Condition(lambda: self.show))
 def __init__(self):
     self.container = ConditionalContainer(content=Window(
         _CompletionsToolbarControl(),
         height=1,
         style='class:completion-toolbar'),
                                           filter=has_completions)
Exemple #13
0
    def __init__(
        self,
        message: InquirerPyMessage,
        style: InquirerPyStyle = None,
        vi_mode: bool = False,
        default: InquirerPyDefault = 0,
        float_allowed: bool = False,
        max_allowed: Union[int, float] = None,
        min_allowed: Union[int, float] = None,
        decimal_symbol: str = ". ",
        replace_mode: bool = False,
        qmark: str = INQUIRERPY_QMARK_SEQUENCE,
        amark: str = "?",
        instruction: str = "",
        long_instruction: str = "",
        validate: InquirerPyValidate = None,
        invalid_message: str = "Invalid input",
        transformer: Callable[[str], Any] = None,
        filter: Callable[[str], Any] = None,
        keybindings: InquirerPyKeybindings = None,
        wrap_lines: bool = True,
        raise_keyboard_interrupt: bool = True,
        mandatory: bool = True,
        mandatory_message: str = "Mandatory prompt",
        session_result: InquirerPySessionResult = None,
    ) -> None:
        super().__init__(
            message=message,
            style=style,
            vi_mode=vi_mode,
            qmark=qmark,
            amark=amark,
            transformer=transformer,
            filter=filter,
            invalid_message=invalid_message,
            validate=validate,
            instruction=instruction,
            long_instruction=long_instruction,
            wrap_lines=wrap_lines,
            raise_keyboard_interrupt=raise_keyboard_interrupt,
            mandatory=mandatory,
            mandatory_message=mandatory_message,
            session_result=session_result,
        )

        self._float = float_allowed
        self._is_float = Condition(lambda: self._float)
        self._max = max_allowed
        self._min = min_allowed
        self._value_error_message = "Remove any non-integer value"
        self._decimal_symbol = decimal_symbol
        self._whole_replace = False
        self._integral_replace = False
        self._replace_mode = replace_mode

        self._leading_zero_pattern = re.compile(r"^(0*)[0-9]+.*")
        self._sn_pattern = re.compile(r"^.*E-.*")
        self._no_default = False

        if default is None:
            default = 0
            self._no_default = True

        if isinstance(default, Callable):
            default = cast(Callable, default)(session_result)
        if self._float:
            default = Decimal(str(float(cast(int, default))))
        if self._float:
            if not isinstance(default, float) and not isinstance(
                    default, Decimal):
                raise InvalidArgument(
                    f"{type(self).__name__} argument 'default' should return type of float or Decimal"
                )
        elif not isinstance(default, int):
            raise InvalidArgument(
                f"{type(self).__name__} argument 'default' should return type of int"
            )
        self._default = default

        if keybindings is None:
            keybindings = {}
        self.kb_maps = {
            "down": [
                {
                    "key": "down"
                },
                {
                    "key": "c-n",
                    "filter": ~self._is_vim_edit
                },
                {
                    "key": "j",
                    "filter": self._is_vim_edit
                },
            ],
            "up": [
                {
                    "key": "up"
                },
                {
                    "key": "c-p",
                    "filter": ~self._is_vim_edit
                },
                {
                    "key": "k",
                    "filter": self._is_vim_edit
                },
            ],
            "left": [
                {
                    "key": "left"
                },
                {
                    "key": "c-b",
                    "filter": ~self._is_vim_edit
                },
                {
                    "key": "h",
                    "filter": self._is_vim_edit
                },
            ],
            "right": [
                {
                    "key": "right"
                },
                {
                    "key": "c-f",
                    "filter": ~self._is_vim_edit
                },
                {
                    "key": "l",
                    "filter": self._is_vim_edit
                },
            ],
            "dot": [{
                "key": "."
            }],
            "focus": [{
                "key": Keys.Tab
            }, {
                "key": "s-tab"
            }],
            "input": [{
                "key": str(i)
            } for i in range(10)],
            "negative_toggle": [{
                "key": "-"
            }],
            **keybindings,
        }
        self.kb_func_lookup = {
            "down": [{
                "func": self._handle_down
            }],
            "up": [{
                "func": self._handle_up
            }],
            "left": [{
                "func": self._handle_left
            }],
            "right": [{
                "func": self._handle_right
            }],
            "focus": [{
                "func": self._handle_focus
            }],
            "input": [{
                "func": self._handle_input
            }],
            "negative_toggle": [{
                "func": self._handle_negative_toggle
            }],
            "dot": [{
                "func": self._handle_dot
            }],
        }

        @self.register_kb(Keys.Any)
        def _(_):
            pass

        self._whole_width = 1
        self._whole_buffer = Buffer(
            on_text_changed=self._on_whole_text_change,
            on_cursor_position_changed=self._on_cursor_position_change,
        )

        self._integral_width = 1
        self._integral_buffer = Buffer(
            on_text_changed=self._on_integral_text_change,
            on_cursor_position_changed=self._on_cursor_position_change,
        )

        self._whole_window = Window(
            height=LayoutDimension.exact(1) if not self._wrap_lines else None,
            content=BufferControl(
                buffer=self._whole_buffer,
                lexer=SimpleLexer("class:input"),
            ),
            width=lambda: Dimension(
                min=self._whole_width,
                max=self._whole_width,
                preferred=self._whole_width,
            ),
            dont_extend_width=True,
        )

        self._integral_window = Window(
            height=LayoutDimension.exact(1) if not self._wrap_lines else None,
            content=BufferControl(
                buffer=self._integral_buffer,
                lexer=SimpleLexer("class:input"),
            ),
            width=lambda: Dimension(
                min=self._integral_width,
                max=self._integral_width,
                preferred=self._integral_width,
            ),
        )

        self._layout = Layout(
            HSplit([
                VSplit(
                    [
                        Window(
                            height=LayoutDimension.exact(1)
                            if not self._wrap_lines else None,
                            content=FormattedTextControl(
                                self._get_prompt_message),
                            wrap_lines=self._wrap_lines,
                            dont_extend_height=True,
                            dont_extend_width=True,
                        ),
                        ConditionalContainer(self._whole_window,
                                             filter=~IsDone()),
                        ConditionalContainer(
                            Window(
                                height=LayoutDimension.exact(1)
                                if not self._wrap_lines else None,
                                content=FormattedTextControl(
                                    [("", self._decimal_symbol)]),
                                wrap_lines=self._wrap_lines,
                                dont_extend_height=True,
                                dont_extend_width=True,
                            ),
                            filter=self._is_float & ~IsDone(),
                        ),
                        ConditionalContainer(
                            self._integral_window,
                            filter=self._is_float & ~IsDone()),
                    ],
                    align=HorizontalAlign.LEFT,
                ),
                ConditionalContainer(
                    Window(content=DummyControl()),
                    filter=~IsDone() & self._is_displaying_long_instruction,
                ),
                ValidationWindow(
                    invalid_message=self._get_error_message,
                    filter=self._is_invalid & ~IsDone(),
                    wrap_lines=self._wrap_lines,
                ),
                InstructionWindow(
                    message=self._long_instruction,
                    filter=~IsDone() & self._is_displaying_long_instruction,
                    wrap_lines=self._wrap_lines,
                ),
            ]), )

        self.focus = self._whole_window

        self._application = Application(
            layout=self._layout,
            style=self._style,
            key_bindings=self._kb,
            after_render=self._after_render,
            editing_mode=self._editing_mode,
        )
Exemple #14
0
def question(message, **kwargs):
    # TODO disabled, dict choices
    if not 'choices' in kwargs:
        raise PromptParameterException('choices')

    choices = kwargs.pop('choices', None)
    default = kwargs.pop('default', None)
    qmark = kwargs.pop('qmark', '?')
    # TODO style defaults on detail level
    style = kwargs.pop('style', default_style)

    ic = InquirerControl(choices, default=default)

    def get_prompt_tokens(cli):
        tokens = []

        tokens.append((Token.QuestionMark, qmark))
        tokens.append((Token.Question, ' %s ' % message))
        if ic.answered:
            tokens.append((Token.Answer, ' ' + ic.get_selection()[0]))
        else:
            tokens.append((Token.Instruction, ' (Use arrow keys)'))
        return tokens

    # assemble layout
    layout = HSplit([
        Window(height=D.exact(1), content=TokenListControl(get_prompt_tokens)),
        ConditionalContainer(Window(ic), filter=~IsDone())
    ])

    # key bindings
    manager = KeyBindingManager.for_prompt()

    @manager.registry.add_binding(Keys.ControlQ, eager=True)
    @manager.registry.add_binding(Keys.ControlC, eager=True)
    def _(event):
        raise KeyboardInterrupt()
        # event.cli.set_return_value(None)

    @manager.registry.add_binding(Keys.Down, eager=True)
    def move_cursor_down(event):
        def _next():
            ic.selected_option_index = ((ic.selected_option_index + 1) %
                                        ic.choice_count)

        _next()
        while isinstance(ic.choices[ic.selected_option_index][0], Separator) or\
                ic.choices[ic.selected_option_index][2]:
            _next()

    @manager.registry.add_binding(Keys.Up, eager=True)
    def move_cursor_up(event):
        def _prev():
            ic.selected_option_index = ((ic.selected_option_index - 1) %
                                        ic.choice_count)

        _prev()
        while isinstance(ic.choices[ic.selected_option_index][0], Separator) or \
                ic.choices[ic.selected_option_index][2]:
            _prev()

    @manager.registry.add_binding(Keys.Enter, eager=True)
    def set_answer(event):
        ic.answered = True
        event.cli.set_return_value(ic.get_selection()[1])

    return Application(layout=layout,
                       key_bindings_registry=manager.registry,
                       mouse_support=True,
                       style=style)
Exemple #15
0
def python_sidebar(python_input):
    """
    Create the `Layout` for the sidebar with the configurable options.
    """
    def get_tokens(cli):
        tokens = []
        T = Token.Sidebar

        def append_category(category):
            tokens.extend([
                (T, '  '),
                (T.Title, '   %-36s' % category.title),
                (T, '\n'),
            ])

        def append(index, label, status):
            selected = index == python_input.selected_option_index

            @if_mousedown
            def select_item(cli, mouse_event):
                python_input.selected_option_index = index

            @if_mousedown
            def goto_next(cli, mouse_event):
                " Select item and go to next value. "
                python_input.selected_option_index = index
                option = python_input.selected_option
                option.activate_next()

            token = T.Selected if selected else T

            tokens.append((T, ' >' if selected else '  '))
            tokens.append((token.Label, '%-24s' % label, select_item))
            tokens.append((token.Status, ' ', select_item))
            tokens.append((token.Status, '%s' % status, goto_next))

            if selected:
                tokens.append((Token.SetCursorPosition, ''))

            tokens.append((token.Status, ' ' * (13 - len(status)), goto_next))
            tokens.append((T, '<' if selected else ''))
            tokens.append((T, '\n'))

        i = 0
        for category in python_input.options:
            append_category(category)

            for option in category.options:
                append(i, option.title, '%s' % option.get_current_value())
                i += 1

        tokens.pop()  # Remove last newline.

        return tokens

    class Control(TokenListControl):
        def move_cursor_down(self, cli):
            python_input.selected_option_index += 1

        def move_cursor_up(self, cli):
            python_input.selected_option_index -= 1

    return ConditionalContainer(content=Window(
        Control(get_tokens,
                Char(token=Token.Sidebar),
                has_focus=ShowSidebar(python_input) & ~IsDone()),
        width=LayoutDimension.exact(43),
        height=LayoutDimension(min=3),
        scroll_offsets=ScrollOffsets(top=1, bottom=1)),
                                filter=ShowSidebar(python_input) & ~IsDone())
Exemple #16
0
    def __init__(
        self,
        message: InquirerPyMessage,
        choices: InquirerPyListChoices,
        default: InquirerPyDefault = None,
        style: InquirerPyStyle = None,
        vi_mode: bool = False,
        qmark: str = "?",
        amark: str = "?",
        pointer: str = INQUIRERPY_POINTER_SEQUENCE,
        instruction: str = "",
        long_instruction: str = "",
        transformer: Callable[[Any], Any] = None,
        filter: Callable[[Any], Any] = None,
        height: Union[int, str] = None,
        max_height: Union[int, str] = None,
        multiselect: bool = False,
        marker: str = INQUIRERPY_POINTER_SEQUENCE,
        marker_pl: str = " ",
        border: bool = False,
        validate: InquirerPyValidate = None,
        invalid_message: str = "Invalid input",
        keybindings: Dict[str, List[Dict[str, Any]]] = None,
        show_cursor: bool = True,
        cycle: bool = True,
        wrap_lines: bool = True,
        raise_keyboard_interrupt: bool = True,
        mandatory: bool = True,
        mandatory_message: str = "Mandatory prompt",
        session_result: InquirerPySessionResult = None,
    ) -> None:
        if not hasattr(self, "_content_control"):
            self.content_control = InquirerPyListControl(
                choices=choices,
                default=default,
                pointer=pointer,
                marker=marker,
                session_result=session_result,
                multiselect=multiselect,
                marker_pl=marker_pl,
            )
        super().__init__(
            message=message,
            style=style,
            border=border,
            vi_mode=vi_mode,
            qmark=qmark,
            amark=amark,
            instruction=instruction,
            long_instruction=long_instruction,
            transformer=transformer,
            filter=filter,
            validate=validate,
            invalid_message=invalid_message,
            multiselect=multiselect,
            keybindings=keybindings,
            cycle=cycle,
            wrap_lines=wrap_lines,
            raise_keyboard_interrupt=raise_keyboard_interrupt,
            mandatory=mandatory,
            mandatory_message=mandatory_message,
            session_result=session_result,
        )
        self._show_cursor = show_cursor
        self._dimmension_height, self._dimmension_max_height = calculate_height(
            height, max_height, height_offset=self.height_offset)
        main_content_window = Window(
            content=self.content_control,
            height=Dimension(
                max=self._dimmension_max_height,
                preferred=self._dimmension_height,
            ),
            dont_extend_height=True,
        )

        if self._border:
            main_content_window = Frame(main_content_window)

        self._layout = FloatContainer(
            content=HSplit([
                MessageWindow(
                    message=self._get_prompt_message_with_cursor
                    if self._show_cursor else self._get_prompt_message,
                    filter=True,
                    wrap_lines=self._wrap_lines,
                    show_cursor=self._show_cursor,
                ),
                ConditionalContainer(main_content_window, filter=~IsDone()),
                ConditionalContainer(
                    Window(content=DummyControl()),
                    filter=~IsDone() & self._is_displaying_long_instruction,
                ),
                InstructionWindow(
                    message=self._long_instruction,
                    filter=~IsDone() & self._is_displaying_long_instruction,
                    wrap_lines=self._wrap_lines,
                ),
            ]),
            floats=[
                ValidationFloat(
                    invalid_message=self._get_error_message,
                    filter=self._is_invalid & ~IsDone(),
                    wrap_lines=self._wrap_lines,
                    left=0,
                    bottom=self._validation_window_bottom_offset,
                ),
            ],
        )

        self.application = Application(
            layout=Layout(self._layout),
            style=self._style,
            key_bindings=self._kb,
            after_render=self._after_render,
        )
Exemple #17
0
           height=1),
    # Display each row
    HSplit([
        VSplit([
            Window(FormattedTextControl(HTML(str(row))), width=2), *[
                Window(FormattedTextControl(get_cell(cell)), width=10)
                for cell in controller.view.get_visible_cells(row, row=True)
            ]
        ]) for row in controller.view.visible_rows()
    ],
           height=controller.view.rows_to_show),
    HorizontalLine(),
    Window(content=FormattedTextControl(
        controller.view.get_current_cell_formula),
           height=1),
    ConditionalContainer(content=cell_input_dialog,
                         filter=Condition(lambda: controller.input_mode))
])

root_container = HSplit([
    # Header for the columns name
    VSplit([
        Window(FormattedTextControl(), width=10), *[
            Window(FormattedTextControl(get_column_name(column)), width=10)
            for column in controller.view.visible_columns()
        ]
    ],
           height=1),
    # Display each row
    HSplit(
        [
            # For each cell in the row, display it's content
Exemple #18
0
def status_bar(python_input: "PythonInput") -> Container:
    """
    Create the `Layout` for the status bar.
    """
    TB = "class:status-toolbar"

    @if_mousedown
    def toggle_paste_mode(mouse_event: MouseEvent) -> None:
        python_input.paste_mode = not python_input.paste_mode

    @if_mousedown
    def enter_history(mouse_event: MouseEvent) -> None:
        python_input.enter_history()

    def get_text_fragments() -> StyleAndTextTuples:
        python_buffer = python_input.default_buffer

        result: StyleAndTextTuples = []
        append = result.append

        append((TB, " "))
        result.extend(get_inputmode_fragments(python_input))
        append((TB, " "))

        # Position in history.
        append((
            TB,
            "%i/%i " % (python_buffer.working_index + 1,
                        len(python_buffer._working_lines)),
        ))

        # Shortcuts.
        app = get_app()
        if (not python_input.vi_mode
                and app.current_buffer == python_input.search_buffer):
            append((TB, "[Ctrl-G] Cancel search [Enter] Go to this position."))
        elif bool(app.current_buffer.selection_state
                  ) and not python_input.vi_mode:
            # Emacs cut/copy keys.
            append(
                (TB,
                 "[Ctrl-W] Cut [Meta-W] Copy [Ctrl-Y] Paste [Ctrl-G] Cancel"))
        else:
            result.extend([
                (TB + " class:status-toolbar.key", "[F3]", enter_history),
                (TB, " History ", enter_history),
                (TB + " class:status-toolbar.key", "[F6]", toggle_paste_mode),
                (TB, " ", toggle_paste_mode),
            ])

            if python_input.paste_mode:
                append((TB + " class:paste-mode-on", "Paste mode (on)",
                        toggle_paste_mode))
            else:
                append((TB, "Paste mode", toggle_paste_mode))

        return result

    return ConditionalContainer(
        content=Window(content=FormattedTextControl(get_text_fragments),
                       style=TB),
        filter=~is_done
        & renderer_height_is_known
        & Condition(lambda: python_input.show_status_bar and not python_input.
                    show_exit_confirmation),
    )
Exemple #19
0
def question(message, **kwargs):
    # TODO extract common parts for list, checkbox, rawlist, expand
    if not 'choices' in kwargs:
        raise PromptParameterException('choices')
    # this does not implement default, use checked...
    # TODO
    # if 'default' in kwargs:
    #    raise ValueError('rawlist does not implement \'default\' '
    #                     'use \'checked\':True\' in choice!')
    qmark = kwargs.pop('qmark', '?')
    choices = kwargs.pop('choices', None)
    if len(choices) > 9:
        raise ValueError('rawlist supports only a maximum of 9 choices!')

    # TODO style defaults on detail level
    style = kwargs.pop('style', default_style)

    ic = InquirerControl(choices)

    def get_prompt_tokens():
        tokens = []

        tokens.append(('class:questionmark', qmark))
        tokens.append(('class:question', ' %s ' % message))
        if ic.answered:
            tokens.append(('class:answer', ' %s' % ic.get_selected_value()))
        return tokens

    # assemble layout
    layout = HSplit([
        Window(height=D.exact(1),
               content=FormattedTextControl(get_prompt_tokens)
               ),
        ConditionalContainer(
            Window(ic),
            filter=~IsDone()
        )
    ])

    # key bindings
    kb = KeyBindings()

    @kb.add('c-q', eager=True)
    @kb.add('c-c', eager=True)
    def _(event):
        raise KeyboardInterrupt()

    # add key bindings for choices
    for i, c in enumerate(ic.choices):
        if not isinstance(c, Separator):
            def _reg_binding(i, keys):
                # trick out late evaluation with a "function factory":
                # http://stackoverflow.com/questions/3431676/creating-functions-in-a-loop
                @kb.add(keys, eager=True)
                def select_choice(event):
                    ic.pointer_index = i

            _reg_binding(i, '%d' % c[0])

    @kb.add('enter', eager=True)
    def set_answer(event):
        ic.answered = True
        event.app.exit(result=ic.get_selected_value())

    return Application(
        layout=Layout(layout),
        key_bindings=kb,
        mouse_support=True,
        style=style
    )
Exemple #20
0
def generate_layout(input_field: TextArea,
                    output_field: TextArea,
                    log_field: TextArea,
                    right_pane_toggle: Button,
                    log_field_button: Button,
                    search_field: SearchToolbar,
                    timer: TextArea,
                    process_monitor: TextArea,
                    trade_monitor: TextArea,
                    command_tabs: Dict[str, CommandTab],
                    ):
    components = {}

    components["item_top_version"] = Window(FormattedTextControl(get_version), style="class:header")
    components["item_top_active"] = Window(FormattedTextControl(get_active_strategy), style="class:header")
    components["item_top_file"] = Window(FormattedTextControl(get_strategy_file), style="class:header")
    components["item_top_gateway"] = Window(FormattedTextControl(get_gateway_status), style="class:header")
    components["item_top_toggle"] = right_pane_toggle
    components["pane_top"] = VSplit([components["item_top_version"],
                                     components["item_top_active"],
                                     components["item_top_file"],
                                     components["item_top_gateway"],
                                     components["item_top_toggle"]], height=1)
    components["pane_bottom"] = VSplit([trade_monitor,
                                        process_monitor,
                                        timer], height=1)
    output_pane = Box(body=output_field, padding=0, padding_left=2, style="class:output-field")
    input_pane = Box(body=input_field, padding=0, padding_left=2, padding_top=1, style="class:input-field")
    components["pane_left"] = HSplit([output_pane, input_pane], width=Dimension(weight=1))
    if all(not t.is_selected for t in command_tabs.values()):
        log_field_button.window.style = "class:tab_button.focused"
    else:
        log_field_button.window.style = "class:tab_button"
    tab_buttons = [log_field_button]
    for tab in sorted(command_tabs.values(), key=lambda x: x.tab_index):
        if tab.button is not None:
            if tab.is_selected:
                tab.button.window.style = "class:tab_button.focused"
            else:
                tab.button.window.style = "class:tab_button"
            tab.close_button.window.style = tab.button.window.style
            tab_buttons.append(VSplit([tab.button, tab.close_button]))
    pane_right_field = log_field
    focused_right_field = [tab.output_field for tab in command_tabs.values() if tab.is_selected]
    if focused_right_field:
        pane_right_field = focused_right_field[0]
    components["pane_right_top"] = VSplit(tab_buttons, height=1, style="class:log-field", padding_char=" ", padding=2)
    components["pane_right"] = ConditionalContainer(
        Box(body=HSplit([components["pane_right_top"], pane_right_field, search_field], width=Dimension(weight=1)),
            padding=0, padding_left=2, style="class:log-field"),
        filter=True
    )
    components["hint_menus"] = [Float(xcursor=True,
                                      ycursor=True,
                                      transparent=True,
                                      content=CompletionsMenu(max_height=16,
                                                              scroll_offset=1))]

    root_container = HSplit([
        components["pane_top"],
        VSplit(
            [FloatContainer(components["pane_left"], components["hint_menus"]),
             components["pane_right"]]),
        components["pane_bottom"],
    ])
    return Layout(root_container, focused_element=input_field), components
Exemple #21
0
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """
    def get_text_fragments():
        result = []
        append = result.append
        Signature = 'class:signature-toolbar'

        if python_input.signatures:
            sig = python_input.signatures[0]  # Always take the first one.

            append((Signature, ' '))
            try:
                append((Signature, sig.full_name))
            except IndexError:
                # Workaround for #37: https://github.com/jonathanslenders/python-prompt-toolkit/issues/37
                # See also: https://github.com/davidhalter/jedi/issues/490
                return []

            append((Signature + ',operator', '('))

            try:
                enumerated_params = enumerate(sig.params)
            except AttributeError:
                # Workaround for #136: https://github.com/jonathanslenders/ptpython/issues/136
                # AttributeError: 'Lambda' object has no attribute 'get_subscope_by_name'
                return []

            for i, p in enumerated_params:
                # Workaround for #47: 'p' is None when we hit the '*' in the signature.
                #                     and sig has no 'index' attribute.
                # See: https://github.com/jonathanslenders/ptpython/issues/47
                #      https://github.com/davidhalter/jedi/issues/598
                description = (p.description if p else '*')  #or '*'
                sig_index = getattr(sig, 'index', 0)

                if i == sig_index:
                    # Note: we use `_Param.description` instead of
                    #       `_Param.name`, that way we also get the '*' before args.
                    append((Signature + ',current-name', str(description)))
                else:
                    append((Signature, str(description)))
                append((Signature + ',operator', ', '))

            if sig.params:
                # Pop last comma
                result.pop()

            append((Signature + ',operator', ')'))
            append((Signature, ' '))
        return result

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_text_fragments),
                       height=Dimension.exact(1)),
        filter=
        # Show only when there is a signature
        HasSignature(python_input) &
        # And there are no completions to be shown. (would cover signature pop-up.)
        ~(has_completions &
          (show_completions_menu(python_input)
           | show_multi_column_completions_menu(python_input)))
        # Signature needs to be shown.
        & ShowSignature(python_input) &
        # Not done yet.
        ~is_done)
Exemple #22
0
    def __init__(self, history):
        search_toolbar = SearchToolbar()

        self.help_buffer_control = BufferControl(
            buffer=history.help_buffer,
            lexer=PygmentsLexer(RstLexer))

        help_window = _create_popup_window(
            title='History Help',
            body=Window(
                content=self.help_buffer_control,
                right_margins=[ScrollbarMargin(display_arrows=True)],
                scroll_offsets=ScrollOffsets(top=2, bottom=2)))

        self.default_buffer_control = BufferControl(
            buffer=history.default_buffer,
            input_processors=[GrayExistingText(history.history_mapping)],
            lexer=PygmentsLexer(PythonLexer))

        self.history_buffer_control = BufferControl(
            buffer=history.history_buffer,
            lexer=PygmentsLexer(PythonLexer),
            search_buffer_control=search_toolbar.control,
            preview_search=True)

        history_window = Window(
            content=self.history_buffer_control,
            wrap_lines=False,
            left_margins=[HistoryMargin(history)],
            scroll_offsets=ScrollOffsets(top=2, bottom=2))

        self.root_container = HSplit([
            #  Top title bar.
            Window(
                content=FormattedTextControl(_get_top_toolbar_fragments),
                align=WindowAlign.CENTER,
                style='class:status-toolbar'),
            FloatContainer(
                content=VSplit([
                    # Left side: history.
                    history_window,
                    # Separator.
                    Window(width=D.exact(1),
                           char=BORDER.LIGHT_VERTICAL,
                           style='class:separator'),
                    # Right side: result.
                    Window(
                        content=self.default_buffer_control,
                        wrap_lines=False,
                        left_margins=[ResultMargin(history)],
                        scroll_offsets=ScrollOffsets(top=2, bottom=2)),
                ]),
                floats=[
                    # Help text as a float.
                    Float(width=60, top=3, bottom=2,
                          content=ConditionalContainer(
                              content=help_window, filter=has_focus(history.help_buffer))),
                ]
            ),
            # Bottom toolbars.
            ArgToolbar(),
            search_toolbar,
            Window(
                content=FormattedTextControl(
                    partial(_get_bottom_toolbar_fragments, history=history)),
                style='class:status-toolbar'),
        ])

        self.layout = Layout(self.root_container, history_window)
def create_layout(python_input, history_mapping):
    """
    Create and return a `Container` instance for the history
    application.
    """
    processors = [
        HighlightSearchProcessor(preview_search=True),
        HighlightSelectionProcessor()
    ]

    help_window = create_popup_window(
        title='History Help',
        body=Window(content=BufferControl(buffer_name=HELP_BUFFER,
                                          default_char=Char(token=Token),
                                          lexer=PygmentsLexer(RstLexer),
                                          input_processors=processors),
                    right_margins=[ScrollbarMargin()],
                    scroll_offsets=ScrollOffsets(top=2, bottom=2)))

    return HSplit([
        #  Top title bar.
        TokenListToolbar(get_tokens=_get_top_toolbar_tokens,
                         align_center=True,
                         default_char=Char(' ', Token.Toolbar.Status)),
        FloatContainer(
            content=VSplit([
                # Left side: history.
                Window(content=BufferControl(buffer_name=HISTORY_BUFFER,
                                             lexer=PygmentsLexer(PythonLexer),
                                             input_processors=processors),
                       wrap_lines=False,
                       left_margins=[HistoryMargin(history_mapping)],
                       scroll_offsets=ScrollOffsets(top=2, bottom=2)),
                # Separator.
                Window(width=D.exact(1),
                       content=FillControl(BORDER.LIGHT_VERTICAL,
                                           token=Token.Separator)),
                # Right side: result.
                Window(
                    content=BufferControl(buffer_name=DEFAULT_BUFFER,
                                          input_processors=processors +
                                          [GrayExistingText(history_mapping)],
                                          lexer=PygmentsLexer(PythonLexer)),
                    wrap_lines=False,
                    left_margins=[ResultMargin(history_mapping)],
                    scroll_offsets=ScrollOffsets(top=2, bottom=2)),
            ]),
            floats=[
                # Help text as a float.
                Float(
                    width=60,
                    top=3,
                    bottom=2,
                    content=ConditionalContainer(
                        # (We use InFocusStack, because it's possible to search
                        # through the help text as well, and at that point the search
                        # buffer has the focus.)
                        content=help_window,
                        filter=InFocusStack(HELP_BUFFER))),
            ]),
        # Bottom toolbars.
        ArgToolbar(),
        SearchToolbar(),
        TokenListToolbar(get_tokens=partial(_get_bottom_toolbar_tokens,
                                            python_input=python_input),
                         default_char=Char(' ', Token.Toolbar.Status)),
    ])
Exemple #24
0
def question(message, **kwargs):
    # TODO add bottom-bar (Move up and down to reveal more choices)
    # TODO extract common parts for list, checkbox, rawlist, expand
    # TODO validate
    if not 'choices' in kwargs:
        raise PromptParameterException('choices')
    # this does not implement default, use checked...
    if 'default' in kwargs:
        raise ValueError('Checkbox does not implement \'default\' '
                         'use \'checked\':True\' in choice!')

    choices = kwargs.pop('choices', None)
    validator = setup_simple_validator(kwargs)

    # TODO style defaults on detail level
    style = kwargs.pop('style', default_style)

    pointer_index = kwargs.pop('pointer_index', 0)
    ic = InquirerControl(choices, pointer_index)
    qmark = kwargs.pop('qmark', '?')

    def get_prompt_tokens(cli):
        tokens = []

        tokens.append((Token.QuestionMark, qmark))
        tokens.append((Token.Question, ' %s ' % message))
        if ic.answered:
            nbr_selected = len(ic.selected_options)
            if nbr_selected == 0:
                tokens.append((Token.Answer, ' done'))
            elif nbr_selected == 1:
                tokens.append((Token.Answer, ' [%s]' % ic.selected_options[0]))
            else:
                tokens.append(
                    (Token.Answer, ' done (%d selections)' % nbr_selected))
        else:
            tokens.append((Token.Instruction,
                           ' (<up>, <down> to move, <space> to select, <a> '
                           'to toggle, <i> to invert)'))
        return tokens

    # assemble layout
    layout = HSplit([
        Window(height=D.exact(1),
               content=TokenListControl(get_prompt_tokens,
                                        align_center=False)),
        ConditionalContainer(Window(ic,
                                    width=D.exact(43),
                                    height=D(min=3),
                                    scroll_offsets=ScrollOffsets(top=1,
                                                                 bottom=1)),
                             filter=~IsDone())
    ])

    # key bindings
    manager = KeyBindingManager.for_prompt()

    @manager.registry.add_binding(Keys.ControlQ, eager=True)
    @manager.registry.add_binding(Keys.ControlC, eager=True)
    def _(event):
        raise KeyboardInterrupt()
        # event.cli.set_return_value(None)

    @manager.registry.add_binding(' ', eager=True)
    def toggle(event):
        pointed_choice = ic.choices[ic.pointer_index][1]  # value
        if pointed_choice in ic.selected_options:
            ic.selected_options.remove(pointed_choice)
        else:
            ic.selected_options.append(pointed_choice)

    @manager.registry.add_binding('i', eager=True)
    def invert(event):
        inverted_selection = [
            c[1] for c in ic.choices if not isinstance(c, Separator)
            and c[1] not in ic.selected_options and not c[2]
        ]
        ic.selected_options = inverted_selection

    @manager.registry.add_binding('a', eager=True)
    def all(event):
        all_selected = True  # all choices have been selected
        for c in ic.choices:
            if not isinstance(c, Separator) and c[
                    1] not in ic.selected_options and not c[2]:
                # add missing ones
                ic.selected_options.append(c[1])
                all_selected = False
        if all_selected:
            ic.selected_options = []

    @manager.registry.add_binding(Keys.Down, eager=True)
    def move_cursor_down(event):
        def _next():
            ic.pointer_index = ((ic.pointer_index + 1) % ic.line_count)

        _next()
        while isinstance(ic.choices[ic.pointer_index], Separator) or \
                ic.choices[ic.pointer_index][2]:
            _next()

    @manager.registry.add_binding(Keys.Up, eager=True)
    def move_cursor_up(event):
        def _prev():
            ic.pointer_index = ((ic.pointer_index - 1) % ic.line_count)

        _prev()
        while isinstance(ic.choices[ic.pointer_index], Separator) or \
                ic.choices[ic.pointer_index][2]:
            _prev()

    @manager.registry.add_binding(Keys.Enter, eager=True)
    def set_answer(event):
        ic.answered = True
        # TODO use validator
        event.cli.set_return_value(ic.get_selected_values())

    return Application(layout=layout,
                       key_bindings_registry=manager.registry,
                       mouse_support=True,
                       style=style)
Exemple #25
0
    def __init__(self,
                 command=['/bin/bash'],
                 before_exec_func=None,
                 bell_func=None,
                 style='',
                 width=None,
                 height=None,
                 done_callback=None):

        self.terminal_control = _TerminalControl(
            command=command,
            before_exec_func=before_exec_func,
            bell_func=bell_func,
            done_callback=done_callback)

        self.terminal_window = _Window(terminal_control=self.terminal_control,
                                       content=self.terminal_control,
                                       wrap_lines=False)

        # Key bindigns for copy buffer.
        kb = KeyBindings()

        @kb.add('c-c')
        def _(event):
            self.exit_copy_mode()

        @kb.add('space')
        def _(event):
            " Reset selection. "
            event.current_buffer.start_selection()

        @kb.add('enter', filter=has_selection)
        def _(event):
            " Reset selection. "
            data = event.current_buffer.copy_selection()
            event.app.clipboard.set_data(data)

        self.search_toolbar = SearchToolbar(
            forward_search_prompt='Search down: ',
            backward_search_prompt='Search up: ')

        self.copy_buffer = Buffer(read_only=True)
        self.copy_buffer_control = BufferControl(
            buffer=self.copy_buffer,
            search_buffer_control=self.search_toolbar.control,
            include_default_input_processors=False,
            input_processors=[
                _UseStyledTextProcessor(self),
                HighlightSelectionProcessor(),
                HighlightSearchProcessor(),
                HighlightIncrementalSearchProcessor(),
            ],
            preview_search=
            True,  # XXX: not sure why we need twice preview_search.
            key_bindings=kb)

        self.copy_window = Window(content=self.copy_buffer_control,
                                  wrap_lines=False)

        self.is_copying = False
        self.styled_copy_lines = [
        ]  # List of lists of (style, text) tuples, for each line.

        @Condition
        def is_copying():
            return self.is_copying

        self.container = FloatContainer(
            content=HSplit(
                [
                    # Either show terminal window or copy buffer.
                    VSplit([  # XXX: this nested VSplit should not have been necessary,
                        # but the ConditionalContainer which width can become
                        # zero will collapse the other elements.
                        ConditionalContainer(self.terminal_window,
                                             filter=~is_copying),
                        ConditionalContainer(self.copy_window,
                                             filter=is_copying),
                    ]),
                    ConditionalContainer(self.search_toolbar,
                                         filter=is_copying),
                ],
                style=style,
                width=width,
                height=height),
            floats=[
                Float(top=0,
                      right=0,
                      height=1,
                      content=ConditionalContainer(Window(
                          content=FormattedTextControl(
                              text=self._copy_position_formatted_text),
                          style='class:copy-mode-cursor-position'),
                                                   filter=is_copying))
            ])
Exemple #26
0
def question(message, **kwargs):
    # TODO disabled, dict choices
    if not 'choices' in kwargs:
        raise PromptParameterException('choices')

    choices = kwargs.pop('choices', None)
    default = kwargs.pop('default', None)
    qmark = kwargs.pop('qmark', '?')
    # TODO style defaults on detail level
    style = kwargs.pop('style', default_style)

    ic = InquirerControl(choices, default=default)

    def get_prompt_tokens():
        tokens = []

        tokens.append(('class:questionmark', qmark))
        tokens.append(('class:question', ' %s ' % message))
        if ic.answered:
            tokens.append(('class:answer', ' ' + ic.get_selection()[0]))
        else:
            tokens.append(('class:instruction', ''))
        return tokens

    # assemble layout
    layout = HSplit([
        Window(height=D.exact(1),
               content=FormattedTextControl(get_prompt_tokens)),
        ConditionalContainer(Window(ic), filter=~IsDone())
    ])

    # key bindings
    kb = KeyBindings()

    @kb.add('c-q', eager=True)
    @kb.add('c-c', eager=True)
    def _(event):
        raise KeyboardInterrupt()
        # event.app.exit(result=None)

    @kb.add('down', eager=True)
    def move_cursor_down(event):
        def _next():
            ic.selected_option_index = ((ic.selected_option_index + 1) %
                                        ic.choice_count)

        _next()
        while isinstance(ic.choices[ic.selected_option_index][0], Separator) or\
                ic.choices[ic.selected_option_index][2]:
            _next()

    @kb.add('up', eager=True)
    def move_cursor_up(event):
        def _prev():
            ic.selected_option_index = ((ic.selected_option_index - 1) %
                                        ic.choice_count)

        _prev()
        while isinstance(ic.choices[ic.selected_option_index][0], Separator) or \
                ic.choices[ic.selected_option_index][2]:
            _prev()

    @kb.add('enter', eager=True)
    def set_answer(event):
        ic.answered = True
        event.app.exit(result="Select Task- %s" %
                       ic.choices[ic.selected_option_index][0])

    @kb.add('c-a', eager=True)
    def set_answer(event):
        ic.answered = True
        event.app.exit(result="Add Task")

    @kb.add('c-w', eager=True)
    def set_answer(event):
        ic.answered = True
        event.app.exit(result="Delete Task - %s" %
                       ic.choices[ic.selected_option_index][0])

    @kb.add('c-h', eager=True)
    def set_answer(event):
        ic.answered = True
        event.app.exit(result="Precedent Task - %s" %
                       ic.choices[ic.selected_option_index][0])

    return Application(layout=Layout(layout),
                       key_bindings=kb,
                       mouse_support=False,
                       style=style)
Exemple #27
0
def create_layout(python_input,
                  lexer=PythonLexer,
                  extra_body=None,
                  extra_toolbars=None,
                  extra_buffer_processors=None,
                  input_buffer_height=None):
    D = Dimension
    extra_body = [extra_body] if extra_body else []
    extra_toolbars = extra_toolbars or []
    extra_buffer_processors = extra_buffer_processors or []
    input_buffer_height = input_buffer_height or D(min=6)

    search_toolbar = SearchToolbar(python_input.search_buffer)

    def create_python_input_window():
        def menu_position():
            """
            When there is no autocompletion menu to be shown, and we have a signature,
            set the pop-up position at `bracket_start`.
            """
            b = python_input.default_buffer

            if b.complete_state is None and python_input.signatures:
                row, col = python_input.signatures[0].bracket_start
                index = b.document.translate_row_col_to_index(row - 1, col)
                return index

        return Window(
            BufferControl(
                buffer=python_input.default_buffer,
                search_buffer_control=search_toolbar.control,
                lexer=lexer,
                include_default_input_processors=False,
                input_processors=[
                    ConditionalProcessor(
                        processor=HighlightIncrementalSearchProcessor(),
                        filter=has_focus(SEARCH_BUFFER)
                        | has_focus(search_toolbar.control),
                    ),
                    HighlightSelectionProcessor(),
                    DisplayMultipleCursors(),
                    # Show matching parentheses, but only while editing.
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(
                            chars='[](){}'),
                        filter=has_focus(DEFAULT_BUFFER) & ~is_done
                        & Condition(lambda: python_input.
                                    highlight_matching_parenthesis)),
                    ConditionalProcessor(processor=AppendAutoSuggestion(),
                                         filter=~is_done)
                ] + extra_buffer_processors,
                menu_position=menu_position,

                # Make sure that we always see the result of an reverse-i-search:
                preview_search=True,
            ),
            left_margins=[PythonPromptMargin(python_input)],
            # Scroll offsets. The 1 at the bottom is important to make sure the
            # cursor is never below the "Press [Meta+Enter]" message which is a float.
            scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4),
            # As long as we're editing, prefer a minimal height of 6.
            height=(lambda: (None if get_app().is_done or python_input.
                             show_exit_confirmation else input_buffer_height)),
            wrap_lines=Condition(lambda: python_input.wrap_lines),
        )

    root_container = HSplit([
        VSplit([
            HSplit([
                FloatContainer(
                    content=HSplit([create_python_input_window()] +
                                   extra_body),
                    floats=[
                        Float(xcursor=True,
                              ycursor=True,
                              content=ConditionalContainer(
                                  content=CompletionsMenu(scroll_offset=(
                                      lambda: python_input.
                                      completion_menu_scroll_offset),
                                                          max_height=12),
                                  filter=show_completions_menu(python_input))),
                        Float(xcursor=True,
                              ycursor=True,
                              content=ConditionalContainer(
                                  content=MultiColumnCompletionsMenu(),
                                  filter=show_multi_column_completions_menu(
                                      python_input))),
                        Float(xcursor=True,
                              ycursor=True,
                              content=signature_toolbar(python_input)),
                        Float(left=2,
                              bottom=1,
                              content=exit_confirmation(python_input)),
                        Float(bottom=0,
                              right=0,
                              height=1,
                              content=meta_enter_message(python_input),
                              hide_when_covering_content=True),
                        Float(bottom=1,
                              left=1,
                              right=0,
                              content=python_sidebar_help(python_input)),
                    ]),
                ArgToolbar(),
                search_toolbar,
                SystemToolbar(),
                ValidationToolbar(),
                ConditionalContainer(content=CompletionsToolbar(),
                                     filter=show_completions_toolbar(
                                         python_input)),

                # Docstring region.
                ConditionalContainer(content=Window(
                    height=D.exact(1), char='\u2500', style='class:separator'),
                                     filter=HasSignature(python_input)
                                     & ShowDocstring(python_input) & ~is_done),
                ConditionalContainer(
                    content=Window(
                        BufferControl(
                            buffer=python_input.docstring_buffer,
                            lexer=SimpleLexer(style='class:docstring'),
                            #lexer=PythonLexer,
                        ),
                        height=D(max=12)),
                    filter=HasSignature(python_input)
                    & ShowDocstring(python_input) & ~is_done),
            ]),
            ConditionalContainer(content=HSplit([
                python_sidebar(python_input),
                Window(style='class:sidebar,separator', height=1),
                python_sidebar_navigation(python_input),
            ]),
                                 filter=ShowSidebar(python_input) & ~is_done)
        ]),
    ] + extra_toolbars + [
        VSplit([
            status_bar(python_input),
            show_sidebar_button_info(python_input),
        ])
    ])

    return Layout(root_container)
Exemple #28
0
    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="├"),
                fill(char=Border.HORIZONTAL),
                # 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(char=Border.HORIZONTAL),
                fill(width=1, height=1, char="┤"),
            ],
            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,
                ),
            ],
            width=width,
            height=height,
            style=style,
            key_bindings=key_bindings,
            modal=modal,
        )
Exemple #29
0
    def _create_layout(self):
        """
        Create `Layout` for this prompt.
        """
        dyncond = self._dyncond

        # Create functions that will dynamically split the prompt. (If we have
        # a multiline prompt.)
        has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \
            _split_multiline_prompt(self._get_prompt)

        default_buffer = self.default_buffer
        search_buffer = self.search_buffer

        # Create processors list.
        all_input_processors = [
            HighlightIncrementalSearchProcessor(),
            HighlightSelectionProcessor(),
            ConditionalProcessor(AppendAutoSuggestion(),
                                 has_focus(default_buffer) & ~is_done),
            ConditionalProcessor(PasswordProcessor(), dyncond('is_password')),
            DisplayMultipleCursors(),

            # Users can insert processors here.
            DynamicProcessor(
                lambda: merge_processors(self.input_processors or [])),

            # For single line mode, show the prompt before the input.
            ConditionalProcessor(
                merge_processors([
                    BeforeInput(get_prompt_text_2),
                    ShowArg(),
                ]), ~dyncond('multiline'))
        ]

        # Create bottom toolbars.
        bottom_toolbar = ConditionalContainer(
            Window(FormattedTextControl(lambda: self.bottom_toolbar,
                                        style='class:bottom-toolbar.text'),
                   style='class:bottom-toolbar',
                   dont_extend_height=True,
                   height=Dimension(min=1)),
            filter=~is_done & renderer_height_is_known
            & Condition(lambda: self.bottom_toolbar is not None))

        search_toolbar = SearchToolbar(
            search_buffer, ignore_case=dyncond('search_ignore_case'))

        search_buffer_control = SearchBufferControl(
            buffer=search_buffer,
            input_processors=[
                ReverseSearchProcessor(),
                ShowArg(),
            ],
            ignore_case=dyncond('search_ignore_case'))

        system_toolbar = SystemToolbar(
            enable_global_bindings=dyncond('enable_system_prompt'))

        def get_search_buffer_control():
            " Return the UIControl to be focused when searching start. "
            if _true(self.multiline):
                return search_toolbar.control
            else:
                return search_buffer_control

        default_buffer_control = BufferControl(
            buffer=default_buffer,
            search_buffer_control=get_search_buffer_control,
            input_processors=all_input_processors,
            include_default_input_processors=False,
            lexer=DynamicLexer(lambda: self.lexer),
            preview_search=True)

        default_buffer_window = Window(
            default_buffer_control,
            height=self._get_default_buffer_control_height,
            left_margins=[
                # In multiline mode, use the window margin to display
                # the prompt and continuation fragments.
                ConditionalMargin(
                    PromptMargin(get_prompt_text_2, self._get_continuation),
                    filter=dyncond('multiline'),
                )
            ],
            wrap_lines=dyncond('wrap_lines'))

        @Condition
        def multi_column_complete_style():
            return self.complete_style == CompleteStyle.MULTI_COLUMN

        # Build the layout.
        layout = HSplit([
            # The main input, with completion menus floating on top of it.
            FloatContainer(
                HSplit([
                    ConditionalContainer(
                        Window(FormattedTextControl(get_prompt_text_1),
                               dont_extend_height=True),
                        Condition(has_before_fragments)),
                    ConditionalContainer(
                        default_buffer_window,
                        Condition(lambda: get_app().layout.current_control !=
                                  search_buffer_control),
                    ),
                    ConditionalContainer(
                        Window(search_buffer_control),
                        Condition(lambda: get_app().layout.current_control ==
                                  search_buffer_control),
                    ),
                ]),
                [
                    # Completion menus.
                    Float(xcursor=True,
                          ycursor=True,
                          content=CompletionsMenu(
                              max_height=16,
                              scroll_offset=1,
                              extra_filter=has_focus(default_buffer)
                              & ~multi_column_complete_style)),
                    Float(xcursor=True,
                          ycursor=True,
                          content=MultiColumnCompletionsMenu(
                              show_meta=True,
                              extra_filter=has_focus(default_buffer)
                              & multi_column_complete_style)),
                    # The right prompt.
                    Float(right=0,
                          top=0,
                          hide_when_covering_content=True,
                          content=_RPrompt(lambda: self.rprompt)),
                ]),
            ConditionalContainer(ValidationToolbar(), filter=~is_done),
            ConditionalContainer(system_toolbar,
                                 dyncond('enable_system_prompt') & ~is_done),

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(
                Window(FormattedTextControl(self._get_arg_text), height=1),
                dyncond('multiline') & has_arg),
            ConditionalContainer(search_toolbar,
                                 dyncond('multiline') & ~is_done),
            bottom_toolbar,
        ])

        return Layout(layout, default_buffer_window)
            ]),
            buttons=[ok_button],
            width=D(preferred=80),
            modal=True)

    def __pt_container__(self):
        return self.dialog


body = HSplit([
    text_field,
    search_toolbar,
    ConditionalContainer(
        content=VSplit([
            Window(FormattedTextControl(get_statusbar_text), style='class:status'),
            Window(FormattedTextControl(get_statusbar_right_text),
                   style='class:status.right', width=9, align=WindowAlign.RIGHT),
        ], height=1),
        filter=Condition(lambda: ApplicationState.show_status_bar)),
])


# Global key bindings.
bindings = KeyBindings()


@bindings.add('c-c')
def _(event):
    " Focus menu. "
    event.app.layout.focus(root_container.window)