Example #1
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.)
    """
    @if_mousedown
    def toggle_sidebar(cli, mouse_event):
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    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))
Example #2
0
def status_bar(python_input, *items):
    return StatusToolbar(
        items,
        default_char=Char(token=StatusToken),
        filter=~IsDone() & RendererHeightIsKnown() &
        Condition(lambda cli: python_input.show_bliss_bar and python_input.
                  bliss_bar.items and not python_input.show_exit_confirmation))
Example #3
0
def create_tutorial_layout(lex):
    """ layout for example tutorial """
    lexer, _, _ = get_lexers(lex, None, None)
    layout_full = HSplit([
        FloatContainer(
            Window(BufferControl(input_processors=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=D.exact(1)),
        ]),
                             filter=~IsDone() & RendererHeightIsKnown())
    ])
    return layout_full
Example #4
0
def status_bar(key_bindings_manager, python_input):
    """
    Create the `Layout` for the status bar.
    """
    TB = Token.Toolbar.Status

    @if_mousedown
    def toggle_paste_mode(cli, mouse_event):
        python_input.paste_mode = not python_input.paste_mode

    @if_mousedown
    def enter_history(cli, mouse_event):
        python_input.enter_history(cli)

    def get_tokens(cli):
        python_buffer = cli.buffers[DEFAULT_BUFFER]

        result = []
        append = result.append

        append((TB, ' '))
        result.extend(get_inputmode_tokens(cli, python_input))
        append((TB, ' '))

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

        # Shortcuts.
        if not python_input.vi_mode and cli.current_buffer_name == SEARCH_BUFFER:
            append((TB, '[Ctrl-G] Cancel search [Enter] Go to this position.'))
        elif bool(cli.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.Key, '[F3]', enter_history),
                (TB, ' History ', enter_history),
                (TB.Key, '[F6]', toggle_paste_mode),
                (TB, ' ', toggle_paste_mode),
            ])

            if python_input.paste_mode:
                append((TB.PasteModeOn, 'Paste mode (on)', toggle_paste_mode))
            else:
                append((TB, 'Paste mode', toggle_paste_mode))

        return result

    return TokenListToolbar(
        get_tokens,
        default_char=Char(token=TB),
        filter=~IsDone() & RendererHeightIsKnown()
        & Condition(lambda cli: python_input.show_status_bar and
                    not python_input.show_exit_confirmation))
Example #5
0
    def create_layout(self, exam_lex, toolbar_lex):
        """ creates the layout """
        lexer, exam_lex, toolbar_lex = get_lexers(self.shell_ctx.lexer,
                                                  exam_lex, toolbar_lex)

        if not any(
                isinstance(processor, DefaultPrompt)
                for processor in self.input_processors):
            self.input_processors.append(DefaultPrompt(self.get_prompt_tokens))

        layout_lower = ConditionalContainer(HSplit([
            get_anyhline(self.shell_ctx.config),
            get_descriptions(self.shell_ctx.config, exam_lex, lexer),
            get_examplehline(self.shell_ctx.config),
            get_example(self.shell_ctx.config, exam_lex),
            ConditionalContainer(get_hline(),
                                 filter=self.show_default | self.show_symbol),
            ConditionalContainer(Window(content=BufferControl(
                buffer_name='default_values', lexer=lexer)),
                                 filter=self.show_default),
            ConditionalContainer(get_hline(),
                                 filter=self.show_default & self.show_symbol),
            ConditionalContainer(Window(
                content=BufferControl(buffer_name='symbols', lexer=exam_lex)),
                                 filter=self.show_symbol),
            ConditionalContainer(Window(
                content=BufferControl(buffer_name='progress', lexer=lexer)),
                                 filter=self.show_progress),
            Window(content=BufferControl(buffer_name='bottom_toolbar',
                                         lexer=toolbar_lex), ),
        ]),
                                            filter=~IsDone()
                                            & RendererHeightIsKnown())

        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))))
                ]), layout_lower
        ])

        return layout_full
Example #6
0
    def __init__(self,
                 key_bindings_manager,
                 settings,
                 token=Token.Toolbar.Status):
        def get_tokens(cli):
            _, python_buffer = current_python_buffer(cli, settings)
            if not python_buffer:
                return []

            TB = token
            result = []
            append = result.append

            append((TB, ' '))
            result.extend(get_inputmode_tokens(TB, key_bindings_manager, cli))
            append((TB, '  '))

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

            # Shortcuts.
            if not key_bindings_manager.enable_vi_mode and cli.focus_stack.current == 'search':
                append((TB,
                        '[Ctrl-G] Cancel search [Enter] Go to this position.'))
            elif bool(cli.current_buffer.selection_state
                      ) and not key_bindings_manager.enable_vi_mode:
                # Emacs cut/copy keys.
                append((
                    TB,
                    '[Ctrl-W] Cut [Meta-W] Copy [Ctrl-Y] Paste [Ctrl-G] Cancel'
                ))
            else:
                append((TB, '  '))

                if settings.paste_mode:
                    append((TB.On, '[F6] Paste mode (on)   '))
                else:
                    append((TB.Off, '[F6] Paste mode (off)  '))

                if python_buffer.is_multiline:
                    append((TB, ' [Meta+Enter] Execute'))

            return result

        super(PythonToolbar,
              self).__init__(get_tokens,
                             default_char=Char(token=token),
                             filter=~IsDone() & RendererHeightIsKnown())
Example #7
0
def create_layout(lex, exam_lex, toolbar_lex):
    """ creates the layout """
    config = azclishell.configuration.CONFIGURATION
    lexer, exam_lex, toolbar_lex = get_lexers(lex, exam_lex, toolbar_lex)

    input_processors.append(DefaultPrompt(get_prompt_tokens))

    layout_lower = ConditionalContainer(HSplit([
        get_anyhline(config),
        get_descriptions(config, exam_lex, lexer),
        get_examplehline(config),
        get_example(config, exam_lex),
        ConditionalContainer(get_hline(), filter=ShowDefault() | ShowSymbol()),
        ConditionalContainer(Window(
            content=BufferControl(buffer_name='default_values', lexer=lexer)),
                             filter=ShowDefault()),
        ConditionalContainer(get_hline(), filter=ShowDefault() & ShowSymbol()),
        ConditionalContainer(Window(
            content=BufferControl(buffer_name='symbols', lexer=exam_lex)),
                             filter=ShowSymbol()),
        ConditionalContainer(
            Window(content=BufferControl(buffer_name='progress', lexer=lexer)),
            filter=ShowProgress()),
        Window(content=BufferControl(buffer_name='bottom_toolbar',
                                     lexer=toolbar_lex), ),
    ]),
                                        filter=~IsDone()
                                        & RendererHeightIsKnown())

    layout_full = HSplit([
        FloatContainer(
            Window(
                BufferControl(input_processors=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))))
            ]), layout_lower
    ])

    return layout_full
Example #8
0
    def __init__(self):
        token = Token.Toolbar.Status

        version = sys.version_info
        tokens = [
            (token, ' [F2] 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

        super(ShowSidebarButtonInfo, self).__init__(
            TokenListControl(get_tokens, default_char=Char(token=token)),
            filter=~IsDone() & RendererHeightIsKnown(),
            height=LayoutDimension.exact(1),
            width=LayoutDimension.exact(width))
Example #9
0
    def create_prompt_layout(self,
                             message='',
                             lexer=None,
                             is_password=False,
                             reserve_space_for_menu=8,
                             get_prompt_tokens=None,
                             get_bottom_toolbar_tokens=None,
                             display_completions_in_columns=False,
                             extra_input_processors=None,
                             multiline=False,
                             wrap_lines=True):
        """Create a Container instance for a prompt.

        Parameters
        ----------
        message : Text to be used as prompt.
        lexer : ~prompt_toolkit.layout.lexers.Lexer to be used for
            the highlighting.
        is_password : bool or ~prompt_toolkit.filters.CLIFilter.
            When True, display input as '*'.
        reserve_space_for_menu : Space to be reserved for the menu. When >0,
            make sure that a minimal height is allocated in the terminal, in order
            to display the completion menu.
        get_prompt_tokens : An optional callable that returns the tokens to be
            shown in the menu. (To be used instead of a `message`.)
        get_bottom_toolbar_tokens : An optional callable that returns the
            tokens for a toolbar at the bottom.
        display_completions_in_columns : `bool` or
            :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in
            multiple columns.
        multiline : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True, prefer a layout that is more adapted for multiline input.
            Text after newlines is automatically indented, and search/arg input is
            shown below the input, instead of replacing the prompt.
        wrap_lines : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True (the default), automatically wrap long lines instead of
            scrolling horizontally.

        Notes
        -----
        This method was forked from the mainline prompt-toolkit repo.
        Copyright (c) 2014, Jonathan Slenders, All rights reserved.

        WARNING; This method is due for removal once prompt-toolkit >v0.54 
        is released.
        """
        assert isinstance(message, str)
        assert get_bottom_toolbar_tokens is None or callable(
            get_bottom_toolbar_tokens)
        assert get_prompt_tokens is None or callable(get_prompt_tokens)
        assert not (message and get_prompt_tokens)

        display_completions_in_columns = to_cli_filter(
            display_completions_in_columns)
        multiline = to_cli_filter(multiline)

        if get_prompt_tokens is None:
            get_prompt_tokens = lambda _: [(Token.Prompt, message)]

        get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt(
            get_prompt_tokens)

        # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer
        # class is given, turn it into a PygmentsLexer. (Important for
        # backwards-compatibility.)
        try:
            if issubclass(lexer, pygments.lexer.Lexer):
                lexer = PygmentsLexer(lexer)
        except TypeError:  # Happens when lexer is `None` or an instance of something else.
            pass

        # Create highlighters and processors list.
        if ConditionalHighlighter is None:
            highlighters = None
            highlighters_kwargs = {}
        else:
            highlighters = [
                ConditionalHighlighter(
                    # By default, only highlight search when the search
                    # input has the focus. (Note that this doesn't mean
                    # there is no search: the Vi 'n' binding for instance
                    # still allows to jump to the next match in
                    # navigation mode.)
                    SearchHighlighter(preview_search=True),
                    HasFocus(SEARCH_BUFFER)),
                SelectionHighlighter()
            ]
            highlighters_kwargs = {'highlighters': highlighters}

        input_processors = [
            ConditionalProcessor(AppendAutoSuggestion(),
                                 HasFocus(DEFAULT_BUFFER) & ~IsDone()),
            ConditionalProcessor(PasswordProcessor(), is_password)
        ]

        if extra_input_processors:
            input_processors.extend(extra_input_processors)

        # Show the prompt before the input (using the DefaultPrompt processor.
        # This also replaces it with reverse-i-search and 'arg' when required.
        # (Only for single line mode.)
        # (DefaultPrompt should always be at the end of the processors.)
        input_processors.append(
            ConditionalProcessor(DefaultPrompt(get_prompt_tokens), ~multiline))

        # Create bottom toolbar.
        if get_bottom_toolbar_tokens:
            toolbars = [
                ConditionalContainer(
                    Window(TokenListControl(get_bottom_toolbar_tokens,
                                            default_char=Char(
                                                ' ', Token.Toolbar)),
                           height=LayoutDimension.exact(1)),
                    filter=~IsDone() & RendererHeightIsKnown())
            ]
        else:
            toolbars = []

        def get_height(cli):
            # If there is an autocompletion menu to be shown, make sure that our
            # layout has at least a minimal height in order to display it.
            if reserve_space_for_menu and not cli.is_done:
                return LayoutDimension(min=reserve_space_for_menu)
            else:
                return LayoutDimension()

        # Create and return Container instance.
        return HSplit([
            ConditionalContainer(
                Window(TokenListControl(get_prompt_tokens_1),
                       dont_extend_height=True),
                filter=multiline,
            ),
            VSplit([
                # In multiline mode, the prompt is displayed in a left pane.
                ConditionalContainer(
                    Window(
                        TokenListControl(get_prompt_tokens_2),
                        dont_extend_width=True,
                    ),
                    filter=multiline,
                ),
                # The main input, with completion menus floating on top of it.
                FloatContainer(
                    Window(
                        BufferControl(
                            input_processors=input_processors,
                            lexer=lexer,
                            wrap_lines=wrap_lines,
                            # Enable preview_search, we want to have immediate feedback
                            # in reverse-i-search mode.
                            preview_search=True,
                            **highlighters_kwargs),
                        get_height=get_height,
                    ),
                    [
                        Float(xcursor=True,
                              ycursor=True,
                              content=CompletionsMenu(
                                  max_height=16,
                                  scroll_offset=1,
                                  extra_filter=HasFocus(DEFAULT_BUFFER)
                                  & ~display_completions_in_columns)),
                        Float(xcursor=True,
                              ycursor=True,
                              content=MultiColumnCompletionsMenu(
                                  extra_filter=HasFocus(DEFAULT_BUFFER)
                                  & display_completions_in_columns,
                                  show_meta=True))
                    ]),
            ]),
            ValidationToolbar(),
            SystemToolbar(),

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(ArgToolbar(), multiline),
            ConditionalContainer(SearchToolbar(), multiline),
        ] + toolbars)
Example #10
0
    def _create_layout(self,
                       message='',
                       lexer=None,
                       is_password=False,
                       reserve_space_for_menu=8,
                       get_prompt_tokens=None,
                       get_continuation_tokens=None,
                       get_rprompt_tokens=None,
                       get_bottom_toolbar_tokens=None,
                       get_url_tokens=None,
                       display_completions_in_columns=False,
                       extra_input_processors=None,
                       multiline=False,
                       wrap_lines=True):
        """
        Create a :class:`.Container` instance for a prompt.
        :param message: Text to be used as prompt.
        :param lexer: :class:`~prompt_toolkit.layout.lexers.Lexer` to be used for
            the highlighting.
        :param is_password: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True, display input as '*'.
        :param reserve_space_for_menu: Space to be reserved for the menu. When >0,
            make sure that a minimal height is allocated in the terminal, in order
            to display the completion menu.
        :param get_prompt_tokens: An optional callable that returns the tokens to be
            shown in the menu. (To be used instead of a `message`.)
        :param get_continuation_tokens: An optional callable that takes a
            CommandLineInterface and width as input and returns a list of (Token,
            text) tuples to be used for the continuation.
        :param get_bottom_toolbar_tokens: An optional callable that returns the
            tokens for a toolbar at the bottom.
        :param display_completions_in_columns: `bool` or
            :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in
            multiple columns.
        :param multiline: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True, prefer a layout that is more adapted for multiline input.
            Text after newlines is automatically indented, and search/arg input is
            shown below the input, instead of replacing the prompt.
        :param wrap_lines: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True (the default), automatically wrap long lines instead of
            scrolling horizontally.
        """
        assert get_bottom_toolbar_tokens is None or callable(
            get_bottom_toolbar_tokens)
        assert get_prompt_tokens is None or callable(get_prompt_tokens)
        assert get_rprompt_tokens is None or callable(get_rprompt_tokens)
        assert not (message and get_prompt_tokens)

        display_completions_in_columns = to_cli_filter(
            display_completions_in_columns)
        multiline = to_cli_filter(multiline)

        if get_prompt_tokens is None:
            get_prompt_tokens = lambda _: [(Token.Prompt, message)]

        has_before_tokens, get_prompt_tokens_1, get_prompt_tokens_2 = \
            _split_multiline_prompt(get_prompt_tokens)

        # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer
        # class is given, turn it into a PygmentsLexer. (Important for
        # backwards-compatibility.)
        try:
            if pygments_Lexer and issubclass(lexer, pygments_Lexer):
                lexer = PygmentsLexer(lexer, sync_from_start=True)
        except TypeError:  # Happens when lexer is `None` or an instance of something else.
            pass

        # Create processors list.
        input_processors = [
            ConditionalProcessor(
                # By default, only highlight search when the search
                # input has the focus. (Note that this doesn't mean
                # there is no search: the Vi 'n' binding for instance
                # still allows to jump to the next match in
                # navigation mode.)
                HighlightSearchProcessor(preview_search=True),
                HasFocus(SEARCH_BUFFER)),
            HighlightSelectionProcessor(),
            ConditionalProcessor(AppendAutoSuggestion(),
                                 HasFocus(DEFAULT_BUFFER) & ~IsDone()),
            ConditionalProcessor(PasswordProcessor(), is_password),
            DisplayMultipleCursors(DEFAULT_BUFFER),
        ]

        if extra_input_processors:
            input_processors.extend(extra_input_processors)

        # Show the prompt before the input (using the DefaultPrompt processor.
        # This also replaces it with reverse-i-search and 'arg' when required.
        # (Only for single line mode.)
        # (DefaultPrompt should always be at the end of the processors.)
        input_processors.append(
            ConditionalProcessor(DefaultPrompt(get_prompt_tokens_2),
                                 ~multiline))

        # Create bottom toolbar.
        if get_bottom_toolbar_tokens:
            toolbars = [
                ConditionalContainer(VSplit([
                    Window(TokenListControl(get_url_tokens,
                                            default_char=Char(
                                                ' ', Token.Toolbar)),
                           height=LayoutDimension.exact(1)),
                    Window(TokenListControl(get_bottom_toolbar_tokens,
                                            default_char=Char(
                                                ' ', Token.Toolbar),
                                            align_right=True),
                           height=LayoutDimension.exact(1))
                ]),
                                     filter=~IsDone()
                                     & RendererHeightIsKnown())
            ]
        else:
            toolbars = []

        def get_height(cli):
            # If there is an autocompletion menu to be shown, make sure that our
            # layout has at least a minimal height in order to display it.
            if reserve_space_for_menu and not cli.is_done:
                buff = cli.current_buffer

                # Reserve the space, either when there are completions, or when
                # `complete_while_typing` is true and we expect completions very
                # soon.
                if buff.complete_while_typing(
                ) or buff.complete_state is not None:
                    return LayoutDimension(min=reserve_space_for_menu)

            return LayoutDimension()

        # Create and return Container instance.
        return HSplit([
            # The main input, with completion menus floating on top of it.
            FloatContainer(
                HSplit([
                    ConditionalContainer(
                        Window(TokenListControl(get_prompt_tokens_1),
                               dont_extend_height=True),
                        Condition(has_before_tokens)),
                    Window(
                        BufferControl(
                            input_processors=input_processors,
                            lexer=lexer,
                            # Enable preview_search, we want to have immediate feedback
                            # in reverse-i-search mode.
                            preview_search=True),
                        get_height=get_height,
                        left_margins=[
                            # In multiline mode, use the window margin to display
                            # the prompt and continuation tokens.
                            ConditionalMargin(PromptMargin(
                                get_prompt_tokens_2, get_continuation_tokens),
                                              filter=multiline)
                        ],
                        wrap_lines=wrap_lines,
                    ),
                ]),
                [
                    # Completion menus.
                    Float(xcursor=True,
                          ycursor=True,
                          content=CompletionsMenu(
                              max_height=16,
                              scroll_offset=1,
                              extra_filter=HasFocus(DEFAULT_BUFFER)
                              & ~display_completions_in_columns)),
                    Float(xcursor=True,
                          ycursor=True,
                          content=MultiColumnCompletionsMenu(
                              extra_filter=HasFocus(DEFAULT_BUFFER)
                              & display_completions_in_columns,
                              show_meta=True)),

                    # The right prompt.
                    Float(right=0,
                          top=0,
                          hide_when_covering_content=True,
                          content=_RPrompt(get_rprompt_tokens)),
                ]),
            ValidationToolbar(),
            SystemToolbar(),

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(ArgToolbar(), multiline),
            ConditionalContainer(SearchToolbar(), multiline),
        ] + toolbars)
Example #11
0
def create_default_layout(app,
                          message='',
                          lexer=None,
                          is_password=False,
                          reserve_space_for_menu=False,
                          get_prompt_tokens=None,
                          get_bottom_toolbar_tokens=None,
                          display_completions_in_columns=False,
                          extra_input_processors=None,
                          multiline=False):
    """
    Generate default layout.

    Returns a ``Layout`` instance.

    :param message: Text to be used as prompt.
    :param lexer: Lexer to be used for the highlighting.
    :param is_password: `bool` or `CLIFilter`. When True, display input as '*'.
    :param reserve_space_for_menu: When True, make sure that a minimal height
        is allocated in the terminal, in order to display the completion menu.
    :param get_prompt_tokens: An optional callable that returns the tokens to
        be shown in the menu. (To be used instead of a `message`.)
    :param get_bottom_toolbar_tokens: An optional callable that returns the
        tokens for a toolbar at the bottom.
    :param display_completions_in_columns: `bool` or `CLIFilter`. Display the
        completions in multiple columns.
    :param multiline: `bool` or `CLIFilter`. When True, prefer a layout that is
        more adapted for multiline input. Text after newlines is automatically
        indented, and search/arg input is shown below the input, instead of
        replacing the prompt.
    """
    assert isinstance(message, text_type)
    assert (get_bottom_toolbar_tokens is None
            or callable(get_bottom_toolbar_tokens))
    assert get_prompt_tokens is None or callable(get_prompt_tokens)
    assert not (message and get_prompt_tokens)

    display_completions_in_columns = to_cli_filter(
        display_completions_in_columns)
    multiline = to_cli_filter(multiline)

    if get_prompt_tokens is None:
        get_prompt_tokens = lambda _: [(Token.Prompt, message)]

    get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt(
        get_prompt_tokens)

    # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer
    # class is given, turn it into a PygmentsLexer. (Important for
    # backwards-compatibility.)
    try:
        if issubclass(lexer, Lexer):
            lexer = PygmentsLexer(lexer)
    except TypeError:
        # Happens when lexer is `None` or an instance of something else.
        pass

    # Create processors list.
    # (DefaultPrompt should always be at the end.)
    input_processors = [
        ConditionalProcessor(
            # By default, only highlight search when the search
            # input has the focus. (Note that this doesn't mean
            # there is no search: the Vi 'n' binding for instance
            # still allows to jump to the next match in
            # navigation mode.)
            HighlightSearchProcessor(preview_search=Always()),
            HasFocus(SEARCH_BUFFER)),
        HighlightSelectionProcessor(),
        ConditionalProcessor(AppendAutoSuggestion(),
                             HasFocus(DEFAULT_BUFFER) & ~IsDone()),
        ConditionalProcessor(PasswordProcessor(), is_password)
    ]

    if extra_input_processors:
        input_processors.extend(extra_input_processors)

    # Show the prompt before the input (using the DefaultPrompt processor.
    # This also replaces it with reverse-i-search and 'arg' when required.
    # (Only for single line mode.)
    input_processors.append(
        ConditionalProcessor(DefaultPrompt(get_prompt_tokens), ~multiline))

    # Create bottom toolbar.
    if get_bottom_toolbar_tokens:
        toolbars = [
            ConditionalContainer(Window(TokenListControl(
                get_bottom_toolbar_tokens,
                default_char=Char(' ', Token.Toolbar)),
                                        height=LayoutDimension.exact(1)),
                                 filter=~IsDone() & RendererHeightIsKnown())
        ]
    else:
        toolbars = []

    def get_height(cli):
        # If there is an autocompletion menu to be shown, make sure that our
        # layout has at least a minimal height in order to display it.
        if reserve_space_for_menu and not cli.is_done:
            return LayoutDimension(min=8)
        else:
            return LayoutDimension()

    def separator():
        return ConditionalContainer(content=Window(
            height=LayoutDimension.exact(1),
            content=FillControl(u'\u2500', token=Token.Separator)),
                                    filter=HasDocumentation(app) & ~IsDone())

    # Create and return Layout instance.
    return HSplit([
        ConditionalContainer(
            Window(TokenListControl(get_prompt_tokens_1),
                   dont_extend_height=True),
            filter=multiline,
        ),
        VSplit([
            # In multiline mode, the prompt is displayed in a left pane.
            ConditionalContainer(
                Window(
                    TokenListControl(get_prompt_tokens_2),
                    dont_extend_width=True,
                ),
                filter=multiline,
            ),
            # The main input, with completion menus floating on top of it.
            FloatContainer(
                Window(
                    BufferControl(
                        input_processors=input_processors,
                        lexer=lexer,
                        # Enable preview_search, we want to have immediate
                        # feedback in reverse-i-search mode.
                        preview_search=Always(),
                        focus_on_click=True,
                    ),
                    get_height=get_height,
                ),
                [
                    Float(xcursor=True,
                          ycursor=True,
                          content=CompletionsMenu(
                              max_height=16,
                              scroll_offset=1,
                              extra_filter=(HasFocus(DEFAULT_BUFFER)
                                            & ~display_completions_in_columns
                                            ))),  # noqa E501
                    Float(xcursor=True,
                          ycursor=True,
                          content=MultiColumnCompletionsMenu(
                              extra_filter=(HasFocus(DEFAULT_BUFFER)
                                            & display_completions_in_columns),
                              show_meta=Always()))
                ]),
        ]),
        separator(),
        ConditionalContainer(
            content=Window(BufferControl(
                focus_on_click=True,
                buffer_name=u'clidocs',
            ),
                           height=LayoutDimension(max=15)),
            filter=HasDocumentation(app) & ~IsDone(),
        ),
        separator(),
        ValidationToolbar(),
        SystemToolbar(),

        # In multiline mode, we use two toolbars for 'arg' and 'search'.
        ConditionalContainer(ArgToolbar(), multiline),
        ConditionalContainer(SearchToolbar(), multiline),
    ] + toolbars)
Example #12
0
def create_default_layout(message='',
                          lexer=None,
                          is_password=False,
                          reserve_space_for_menu=False,
                          get_prompt_tokens=None,
                          get_bottom_toolbar_tokens=None,
                          extra_input_processors=None):
    """
    Generate default layout.
    Returns a ``Layout`` instance.

    :param message: Text to be used as prompt.
    :param lexer: Pygments lexer to be used for the highlighting.
    :param is_password: When True, display input as '*'.
    :param reserve_space_for_menu: When True, make sure that a minimal height is
        allocated in the terminal, in order to display the completion menu.
    :param get_prompt_tokens: An optional callable that returns the tokens to be
        shown in the menu. (To be used instead of a `message`.)
    :param get_bottom_toolbar_tokens: An optional callable that returns the
        tokens for a toolbar at the bottom.
    """
    assert isinstance(message, text_type)
    assert get_bottom_toolbar_tokens is None or callable(
        get_bottom_toolbar_tokens)
    assert get_prompt_tokens is None or callable(get_prompt_tokens)
    assert not (message and get_prompt_tokens)

    # Create processors list.
    # (DefaultPrompt should always be at the end.)
    input_processors = [
        HighlightSearchProcessor(preview_search=Always()),
        HighlightSelectionProcessor()
    ]

    if is_password:
        input_processors.append(PasswordProcessor())

    if extra_input_processors:
        input_processors.extend(extra_input_processors)

    if message:
        input_processors.append(DefaultPrompt.from_message(message))
    else:
        input_processors.append(DefaultPrompt(get_prompt_tokens))

    # Create bottom toolbar.
    if get_bottom_toolbar_tokens:
        toolbars = [
            Window(TokenListControl(get_bottom_toolbar_tokens,
                                    default_char=Char(' ', Token.Toolbar)),
                   height=LayoutDimension.exact(1),
                   filter=~IsDone() & RendererHeightIsKnown())
        ]
    else:
        toolbars = []

    def get_height(cli):
        # If there is an autocompletion menu to be shown, make sure that our
        # layout has at least a minimal height in order to display it.
        if reserve_space_for_menu and not cli.is_done:
            return LayoutDimension(min=8)
        else:
            return LayoutDimension()

    # Create and return Layout instance.
    return HSplit([
        FloatContainer(
            Window(
                BufferControl(
                    input_processors=input_processors,
                    lexer=lexer,
                    # Enable preview_search, we want to have immediate feedback
                    # in reverse-i-search mode.
                    preview_search=Always()),
                get_height=get_height,
            ),
            [
                Float(xcursor=True,
                      ycursor=True,
                      content=CompletionsMenu(max_height=16,
                                              extra_filter=HasFocus(
                                                  DEFAULT_BUFFER)))
            ]),
        ValidationToolbar(),
        SystemToolbar(),
    ] + toolbars)
Example #13
0
def create_layout(message='',
                  lexer=None,
                  reserve_space_for_menu=8,
                  get_prompt_tokens=None,
                  get_bottom_toolbar_tokens=None,
                  extra_input_processors=None,
                  multiline=False,
                  wrap_lines=True):

    # Create processors list.
    input_processors = [
        ConditionalProcessor(
            # Highlight the reverse-i-search buffer
            HighlightSearchProcessor(preview_search=True),
            HasFocus(SEARCH_BUFFER)),
    ]

    if extra_input_processors:
        input_processors.extend(extra_input_processors)

    lexer = PygmentsLexer(lexer, sync_from_start=True)
    multiline = to_cli_filter(multiline)

    sidebar_token = [(Token.Toolbar.Status.Key, "[ctrl+d]"),
                     (Token.Toolbar.Status, " Exit")]
    sidebar_width = token_list_width(sidebar_token)

    get_prompt_tokens = lambda _: [(Token.Prompt, message)]
    get_sidebar_tokens = lambda _: sidebar_token

    def get_height(cli):
        # If there is an autocompletion menu to be shown, make sure that our
        # layout has at least a minimal height in order to display it.
        if reserve_space_for_menu and not cli.is_done:
            buff = cli.current_buffer

            # Reserve the space, either when there are completions, or when
            # `complete_while_typing` is true and we expect completions very
            # soon.
            if buff.complete_while_typing() or buff.complete_state is not None:
                return LayoutDimension(min=reserve_space_for_menu)

        return LayoutDimension()

    # Create and return Container instance.
    return HSplit([
        VSplit([
            HSplit([
                # The main input, with completion menus floating on top of it.
                FloatContainer(
                    HSplit([
                        Window(
                            BufferControl(
                                input_processors=input_processors,
                                lexer=lexer,
                                # enable preview search for reverse-i-search
                                preview_search=True),
                            get_height=get_height,
                            wrap_lines=wrap_lines,
                            left_margins=[
                                # In multiline mode, use the window margin to display
                                # the prompt and continuation tokens.
                                ConditionalMargin(PromptMargin(
                                    get_prompt_tokens),
                                                  filter=multiline)
                            ],
                        ),
                    ]),
                    [
                        # Completion menu
                        Float(xcursor=True,
                              ycursor=True,
                              content=CompletionsMenu(max_height=16,
                                                      scroll_offset=1,
                                                      extra_filter=HasFocus(
                                                          DEFAULT_BUFFER))),
                    ]),

                # reverse-i-search toolbar (ctrl+r)
                ConditionalContainer(SearchToolbar(), multiline),
            ])
        ]),
    ] + [
        VSplit([
            # Left-Aligned Session Toolbar
            ConditionalContainer(Window(TokenListControl(
                get_bottom_toolbar_tokens),
                                        height=LayoutDimension.exact(1)),
                                 filter=~IsDone() & RendererHeightIsKnown()),

            # Right-Aligned Container
            ConditionalContainer(Window(TokenListControl(get_sidebar_tokens),
                                        height=LayoutDimension.exact(1),
                                        width=LayoutDimension.exact(
                                            sidebar_width)),
                                 filter=~IsDone() & RendererHeightIsKnown())
        ])
    ])