Пример #1
0
Файл: layout.py Проект: pg83/zm
    def __init__(
        self,
        python_input: "PythonInput",
        lexer=PythonLexer,
        extra_body=None,
        extra_toolbars=None,
        extra_buffer_processors=None,
        input_buffer_height: Optional[AnyDimension] = None,
    ) -> 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(),
                        TabsProcessor(),
                        # 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),
            )

        sidebar = python_sidebar(python_input)
        self.exit_confirmation = create_exit_confirmation(python_input)

        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=self.exit_confirmation,
                            ),
                            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)
                        & ~is_done,
                    ),
                    # 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([
                        sidebar,
                        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)
            ])
        ])

        self.layout = Layout(root_container)
        self.sidebar = sidebar
from prompt_toolkit import Application, HTML
from prompt_toolkit.layout.containers import Window
from prompt_toolkit.layout.controls import FormattedTextControl
from prompt_toolkit.layout.layout import Layout
from prompt_toolkit.key_binding import KeyBindings


# naformátovaná zpráva
message = HTML("<ansired>Hello</ansired> <ansiblue>world!</ansiblue>")

# ovládací prvek s naformátovaným textem
text = FormattedTextControl(text=message)

# okno obsahující jediný ovládací prvek
window = Window(content=text)

# správce rozvržení
layout = Layout(window)

# napojení na klávesové zkratky
key_bindings = KeyBindings()


@key_bindings.add('escape')
def on_escape_press(event):
    """Callback funkce volaná při stisku klávesy Esc."""
    print("\n\n[escape]\n\n")
    event.app.exit()

        "spider",
        "turkey",
        "turtle",
    ],
    ignore_case=True,
)


# The layout
buff = Buffer(completer=animal_completer, complete_while_typing=True)

body = FloatContainer(
    content=HSplit(
        [
            Window(
                FormattedTextControl('Press "q" to quit.'), height=1, style="reverse"
            ),
            Window(BufferControl(buffer=buff)),
        ]
    ),
    floats=[
        Float(
            xcursor=True,
            ycursor=True,
            content=CompletionsMenu(max_height=16, scroll_offset=1),
        )
    ],
)


# Key bindings
Пример #4
0
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """
    def get_tokens(cli):
        result = []
        append = result.append
        Signature = Token.Toolbar.Signature

        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.CurrentName, 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(TokenListControl(get_tokens),
                       height=LayoutDimension.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.)
        ~(HasCompletions() &
          (show_completions_menu(python_input)
           | show_multi_column_completions_menu(python_input)))
        # Signature needs to be shown.
        & ShowSignature(python_input) &
        # Not done yet.
        ~IsDone())
Пример #5
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())
Пример #6
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)
Пример #7
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,
        )
Пример #8
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))
            ])
Пример #9
0
SPACE = QLabel(" ")

preview = FormattedTextControl()
preview_frame = PreviewFrame(
    preview,
    title="Preview",
    style="fg:#AAAAAA bold",
)
root_container = MenuContainer(
    body=HSplit([
        VSplit([
            HSplit([
                open_file_frame,
                search_toolbar,
            ]),
            Window(preview),
        ], ),
        VSplit(
            [
                QLabel("<F1=Help>"),
                SPACE,
                QLabel("<F5=Run>"),
                SPACE,
                QLabel("<CTRL+R=Run>"),
            ],
            style="bg:#00AAAA fg:white bold",
            height=1,
        ),
    ]),
    menu_items=[
        MenuItem(
Пример #10
0
    def play(self, vlc_params: str = DEFAULT_VLC_PARAMS) -> None:
        if not self.musics:
            self.warn('Empty playlist')
            return

        try:
            if platform.system() == 'Windows':
                vlc_path = r'C:\Program Files\VideoLAN\VLC'
                logger.debug(f"Adding DLL folder {vlc_path}")
                os.add_dll_directory(vlc_path)  # type: ignore
            import vlc  # type: ignore
            instance = vlc.Instance(vlc_params)
            devices = instance.audio_output_enumerate_devices()
            if not devices:
                logger.warning('maybe no audio output detected...')

            if not instance:
                logger.critical('Unable to start VLC instance')
                return

            player = instance.media_list_player_new()
            if not player:
                logger.critical('Unable to create VLC player')
                return

            media_list = instance.media_list_new(list(self.links))
            if not media_list:
                logger.critical('Unable to create VLC media list')
                return

            player.set_media_list(media_list)
            bindings = KeyBindings()

            def print_help() -> None:
                print_formatted_text(
                    HTML(
                        '<violet>Bindings: q = quit | p = play | s = pause/continue | right = next song | left = previous song | l = playlist</violet>'
                    ))

            @bindings.add('p')
            def _play_binding(event: Any) -> None:  # pylint: disable=unused-argument
                def play() -> None:
                    """Play song"""
                    player.play()

                _ = run_in_terminal(play)

            @bindings.add('q')
            def _quit_binding(event: Any) -> None:
                player.pause()
                event.app.exit()

            @bindings.add('s')
            def _pause_binding(event: Any) -> None:  # pylint: disable=unused-argument
                player.pause()

            @bindings.add('l')
            def _playlist_binding(event: Any) -> None:  # pylint: disable=unused-argument
                def playlist() -> None:
                    """List songs"""
                    media_player = player.get_media_player()
                    media = media_player.get_media()
                    media.parse()
                    current_artist = media.get_meta(vlc.Meta.Artist)
                    current_album = media.get_meta(vlc.Meta.Album)
                    current_title = media.get_meta(vlc.Meta.Title)
                    self.print(output='table',
                               current_artist=current_artist,
                               current_album=current_album,
                               current_title=current_title)

                _ = run_in_terminal(playlist)

            @bindings.add('right')
            def _next_binding(event: Any) -> None:  # pylint: disable=unused-argument
                player.next()

            @bindings.add('left')
            def _previous_binding(event: Any) -> None:  # pylint: disable=unused-argument
                player.previous()

            @bindings.add('h')
            def _help(event: Any) -> None:  # pylint: disable=unused-argument
                def _print_help() -> None:
                    print_help()

                _ = run_in_terminal(_print_help)
                get_app().invalidate()

            def bottom_toolbar() -> Any:
                media_player = player.get_media_player()
                media = media_player.get_media()
                media.parse()
                media_time = formatted_seconds_to_human(
                    round(media_player.get_time() / 1000))
                media_length = formatted_seconds_to_human(
                    round(media_player.get_length() / 1000))
                artist = media.get_meta(vlc.Meta.Artist)
                album = media.get_meta(vlc.Meta.Album)
                title = media.get_meta(vlc.Meta.Title)
                current = f'({media_time} / {media_length}) {artist} - {album} - {title}'
                get_app().invalidate()
                return HTML(f'Current song: {current}')

            print_help()
            player.play()

            root_container = HSplit([
                Window(FormattedTextControl(lambda: bottom_toolbar,
                                            style='class:bottom-toolbar.text'),
                       style='class:bottom-toolbar')
            ])
            layout = Layout(root_container)
            app: Any = Application(layout=layout, key_bindings=bindings)
            app.run()
        except Exception as e:  # pylint:disable=broad-except
            logger.exception(e)
Пример #11
0
class JobWidgetBase(abc.ABC):
    """User-interaction and information display for :class:`~.jobs.JobBase` instance"""

    _no_runtime_widget = Window(
        dont_extend_height=True,
        style='class:info',
    )

    def __init__(self, job, app):
        self._job = job
        self._app = app
        self.setup()
        self.job.signal.register('info', lambda _: self.invalidate())
        self.job.signal.register('warning', lambda _: self.invalidate())
        main_widget = HSplit(
            children=[
                # Status information or user interaction
                ConditionalContainer(
                    filter=Condition(lambda: not self.job.is_finished),
                    content=self.runtime_widget or self._no_runtime_widget,
                ),
                # Result
                ConditionalContainer(
                    filter=Condition(lambda: self.job.output),
                    content=self.output_widget,
                ),
                # Additional info that isn't part of the job's main result
                # (e.g. CreateTorrentJobWidget can show the files in the
                # torrent, but the output is the torrent file path.)
                ConditionalContainer(
                    filter=Condition(lambda: not self.job.is_finished and bool(self.job.info)),
                    content=self.info_widget,
                ),
                # Warnings
                ConditionalContainer(
                    filter=Condition(lambda: bool(self.job.warnings)),
                    content=self.warnings_widget,
                ),
                # Errors
                ConditionalContainer(
                    filter=Condition(lambda: bool(self.job.errors)),
                    content=self.errors_widget,
                ),
            ],
        )
        label = widgets.HLabel(
            group='jobs',
            text=self.job.label,
            style='class:label',
            content=main_widget,
        )
        self._container = ConditionalContainer(
            filter=Condition(lambda: self.job.errors or not self.job.hidden),
            content=label,
        )

    @property
    def job(self):
        """Underlying :class:`~.JobBase` instance"""
        return self._job

    @abc.abstractmethod
    def setup(self):
        """
        Called on object creation

        Create widgets and register :attr:`job` callbacks.
        """

    @property
    @abc.abstractmethod
    def runtime_widget(self):
        """
        Interactive or status that is displayed while this job is running

        :return: :class:`~.prompt_toolkit.layout.containers.Window` object or
            `None`
        """

    @property
    def output_widget(self):
        """
        Job :attr:`~.JobBase.output`

        :return: :class:`~.prompt_toolkit.layout.containers.Window` object
        """
        return Window(
            style='class:output',
            # FIXME: If output is empty, prompt-toolkit ignores the
            #        "dont_extend_height" argument. Using a space (0x20) as a
            #        placeholder seems to prevent this issue.
            content=FormattedTextControl(lambda: '\n'.join(self.job.output) or ' '),
            dont_extend_height=True,
            wrap_lines=True,
        )

    @property
    def info_widget(self):
        """
        :attr:`~.JobBase.info` that is only displayed while this job is running

        :return: :class:`~.prompt_toolkit.layout.containers.Window` object
        """
        return Window(
            style='class:info',
            content=FormattedTextControl(lambda: str(self.job.info)),
            dont_extend_height=True,
            wrap_lines=True,
        )

    @property
    def warnings_widget(self):
        """
        Any :attr:`~.JobBase.warnings`

        :return: :class:`~.prompt_toolkit.layout.containers.Window` object
        """
        return Window(
            style='class:warning',
            content=FormattedTextControl(lambda: '\n'.join(str(e) for e in self.job.warnings)),
            dont_extend_height=True,
            wrap_lines=True,
        )

    @property
    def errors_widget(self):
        """
        Any :attr:`~.JobBase.errors`

        :return: :class:`~.prompt_toolkit.layout.containers.Window` object
        """
        return Window(
            style='class:error',
            content=FormattedTextControl(lambda: '\n'.join(str(e) for e in self.job.errors)),
            dont_extend_height=True,
            wrap_lines=True,
        )

    @property
    def is_interactive(self):
        """Whether this job needs user interaction"""
        if self.runtime_widget:
            for c in walk(to_container(self.runtime_widget), skip_hidden=True):
                if isinstance(c, Window) and c.content.is_focusable():
                    return True
        return False

    def invalidate(self):
        """Schedule redrawing of the TUI"""
        self._app.invalidate()

    def __pt_container__(self):
        return self._container
Пример #12
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)
Пример #13
0
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)),
    ])
Пример #14
0
Файл: layout.py Проект: pg83/zm
def python_sidebar(python_input: "PythonInput") -> Window:
    """
    Create the `Layout` for the sidebar with the configurable options.
    """
    def get_text_fragments() -> StyleAndTextTuples:
        tokens: StyleAndTextTuples = []

        def append_category(category: "OptionCategory") -> None:
            tokens.extend([
                ("class:sidebar", "  "),
                ("class:sidebar.title", "   %-36s" % category.title),
                ("class:sidebar", "\n"),
            ])

        def append(index: int, label: str, status: str) -> None:
            selected = index == python_input.selected_option_index

            @if_mousedown
            def select_item(mouse_event: MouseEvent) -> None:
                python_input.selected_option_index = index

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

            sel = ",selected" if selected else ""

            tokens.append(("class:sidebar" + sel, " >" if selected else "  "))
            tokens.append(
                ("class:sidebar.label" + sel, "%-24s" % label, select_item))
            tokens.append(("class:sidebar.status" + sel, " ", select_item))
            tokens.append(
                ("class:sidebar.status" + sel, "%s" % status, goto_next))

            if selected:
                tokens.append(("[SetCursorPosition]", ""))

            tokens.append(("class:sidebar.status" + sel,
                           " " * (13 - len(status)), goto_next))
            tokens.append(("class:sidebar", "<" if selected else ""))
            tokens.append(("class:sidebar", "\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(FormattedTextControl):
        def move_cursor_down(self):
            python_input.selected_option_index += 1

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

    return Window(
        Control(get_text_fragments),
        style="class:sidebar",
        width=Dimension.exact(43),
        height=Dimension(min=3),
        scroll_offsets=ScrollOffsets(top=1, bottom=1),
    )
Пример #15
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
    )
dignissim placerat. In vel dictum ex, vulputate accumsan mi. Donec ut quam
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut
tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus. """ * 100).split())

# 1. The layout
left_text = HTML("<reverse>transparent=False</reverse>\n")
right_text = HTML("<reverse>transparent=True</reverse>")
quit_text = "Press 'q' to quit."

body = FloatContainer(
    content=Window(FormattedTextControl(LIPSUM), wrap_lines=True),
    floats=[

        # Important note: Wrapping the floating objects in a 'Frame' is
        #                 only required for drawing the border around the
        #                 floating text. We do it here to make the layout more
        #                 obvious.

        # Left float.
        Float(Frame(Window(FormattedTextControl(left_text), width=20,
                           height=4)),
              transparent=False,
              left=0),

        # Right float.
        Float(Frame(
Пример #17
0
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus."""

# Create text buffers. Cursorcolumn/cursorline are mostly combined with an
# (editable) text buffers, where the user can move the cursor.

buff = Buffer()
buff.text = LIPSUM

# 1. The layout
body = HSplit([
    Window(FormattedTextControl('Press "q" to quit.'),
           height=1,
           style='reverse'),
    Window(BufferControl(buffer=buff), cursorcolumn=True, cursorline=True),
])

# 2. Key bindings
kb = KeyBindings()


@kb.add('q')
def _(event):
    " Quit application. "
    event.app.exit()


# 3. The `Application`
Пример #18
0
ctrls = myControls()
myButtons = list()

threadsDir = "threads" + os.sep
dirs = os.listdir(threadsDir)
for d in dirs:
    myButtons.append(myButton(d, myControls=ctrls, name=d))

body = VSplit([
    HSplit(myButtons),

    # A vertical line in the middle. We explicitly specify the width, to make
    # sure that the layout engine will not try to divide the whole width by
    # three for all these windows.
    Window(width=1, char='|', style='class:line'),

    #Window(content)
    HSplit(
        list([
            Window(ctrls.content),
            Window(height=1, char='=', style='class:line'), ctrls.sender
        ]))
])

# 2. Key bindings
kb = KeyBindings()

# Key bindings.
kb = KeyBindings()
kb.add('tab')(focus_next)
Пример #19
0
def get_cell(cell):
    def _():
        return HTML(controller.get_cell_html(cell))

    return _


cell_input_dialog = Dialog(
    TextArea(accept_handler=commit_changes, multiline=False))
controller = PysheetApplication(cell_input_dialog)

grid_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([
        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),
Пример #20
0
from prompt_toolkit import ANSI
from prompt_toolkit.buffer import Buffer
from prompt_toolkit.widgets import Frame
from prompt_toolkit.layout.containers import Window
from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl
from prompt_toolkit.lexers import PygmentsLexer
from pygments.lexers.python import PythonLexer  # type: ignore
from rich.syntax import Syntax
from rich.markdown import Markdown
from rich.console import Console

# TODO: take language into account
lexer: PygmentsLexer = PygmentsLexer(PythonLexer)

EMPTY_PREFIX: Window = Window(width=10)

console = Console()


def get_output_text_and_height(outputs: List[Dict[str, Any]]):
    text_list = []
    height = 0
    for output in outputs:
        if output["output_type"] == "stream":
            text = "".join(output["text"])
            height += text.count("\n") or 1
            if output["name"] == "stderr":
                with console.capture() as capture:
                    console.print(text, style="white on red", end="")
                text = capture.get()
Пример #21
0
def question(message, **kwargs):
    default = kwargs.pop('default', True)

    status = {'answer': None}

    qmark = kwargs.pop('qmark', '?')

    def get_prompt_tokens():
        tokens = []

        tokens.append(('class:question-mark', qmark))
        tokens.append(('class:question', ' %s ' % message))
        if isinstance(status['answer'], bool):
            tokens.append(
                ('class:answer', ' Yes' if status['answer'] else ' No'))
        else:
            if default:
                instruction = ' (Y/n)'
            else:
                instruction = ' (y/N)'
            tokens.append(('class:instruction', instruction))
        return tokens

    # key bindings
    kb = KeyBindings()

    @kb.add(Keys.ControlQ, eager=True)
    @kb.add(Keys.ControlC, eager=True)
    def _(event):
        event.app.exit(exception=KeyboardInterrupt())

    @kb.add('n')
    @kb.add('N')
    def key_n(event):  # pylint:disable=unused-variable
        status['answer'] = False
        event.app.exit(result=False)

    @kb.add('y')
    @kb.add('Y')
    def key_y(event):  # pylint:disable=unused-variable
        status['answer'] = True
        event.app.exit(result=True)

    @kb.add(Keys.Enter, eager=True)
    def set_answer(event):  # pylint:disable=unused-variable
        status['answer'] = default
        event.app.exit(result=default)

    # assemble layout
    layout = Layout(
        HSplit([
            Window(height=D.exact(1),
                   content=FormattedTextControl(get_prompt_tokens)),
        ]))

    return Application(
        layout=layout,
        key_bindings=kb,
        mouse_support=False,
        style=default_style,
    )
Пример #22
0
def run():
    line_cursor_pos = 0
    current_line = 0
    cursor_lock = Lock()
    during_accept = False

    # The layout.
    output_field = TextArea(style="class:output-field")
    input_field = TextArea(
        height=1,
        prompt=" # ",
        style="class:input-field",
        multiline=False,
        wrap_lines=False,
    )

    roll = ['\\', '-', '/', '|']
    current_roll = -1

    def get_statusbar_text():
        nonlocal during_accept, current_roll
        if during_accept:
            if current_roll == 3:
                current_roll = -1
            current_roll = current_roll + 1
            return ' {} Searching...'.format(roll[current_roll])
        else:
            return ' = Nice Translator'

    def get_statusbar_class():
        nonlocal during_accept
        if during_accept:
            return "class:searching-status"
        else:
            return "class:status"

    container = HSplit([
        input_field,
        Window(height=1, char="-", style="class:line"),
        output_field,
        Window(FormattedTextControl(get_statusbar_text),
               height=1,
               style=get_statusbar_class),
    ])

    def addline(old, newline):
        return old + '   {}\n'.format(newline)

    def accept(buff):
        with cursor_lock:
            nonlocal during_accept
            during_accept = True
            nonlocal line_cursor_pos
            nonlocal current_line
            line_cursor_pos = 0
            current_line = 0

            new_text = ''
            if input_field.text.strip() != '':
                try:
                    translate_result = translate.translate(input_field.text)
                    output = ''
                    for rs in translate_result:
                        output = addline(output, rs)
                    text = output
                    text_lines = text.splitlines(keepends=True)
                    for i, l in enumerate(text_lines):
                        if (l.startswith(' > ')):
                            text_lines[i] = '   ' + text_lines[i][3:]
                            break
                    text = ''.join(text_lines)
                    new_text = ' > ' + text[3:]
                except Exception as e:
                    new_text = 'Some error occured.\n{}'.format(e)

            # Add text to output buffer.
            output_field.buffer.document = Document(
                text=new_text, cursor_position=line_cursor_pos)
            during_accept = False

    def threading_accept(buff):
        l = [buff]
        t = Thread(target=accept, args=l)
        t.start()

    input_field.accept_handler = threading_accept

    # The key bindings.
    kb = KeyBindings()

    # show where the cursor is
    # @kb.add("tab")
    # def _(event):
    #     event.app.layout.focus_next()

    @kb.add('escape', 'q')
    def _(event):
        " Pressing Ctrl-Q or Ctrl-C will exit the user interface. "
        event.app.exit()

    # cursor move next line
    @kb.add('escape', 'n')
    def _(event):
        with cursor_lock:
            nonlocal line_cursor_pos
            nonlocal current_line
            new_text = ''
            lines = output_field.text.splitlines(keepends=True)
            if len(lines) == 0 or current_line is len(lines) - 1:
                return
            for i, l in enumerate(lines):
                if i == current_line:
                    lines[i] = '   ' + lines[i][3:]
                    lines[i + 1] = ' > ' + lines[i + 1][3:]
                new_text = new_text + lines[i]
            line_cursor_pos = line_cursor_pos + len(lines[current_line])
            current_line = current_line + 1
            output_field.buffer.document = Document(
                text=new_text, cursor_position=line_cursor_pos)

    # cursor move previous line
    @kb.add('escape', 'm')
    def _(event):
        with cursor_lock:
            nonlocal line_cursor_pos
            nonlocal current_line
            new_text = ''
            lines = output_field.text.splitlines(keepends=True)
            if current_line is 0:
                return
            for i, l in enumerate(lines):
                if i == current_line:
                    lines[i] = '   ' + lines[i][3:]
                    lines[i - 1] = ' > ' + lines[i - 1][3:]
                    break
            for l in lines:
                new_text = new_text + l
            line_cursor_pos = line_cursor_pos - len(lines[current_line - 1])
            current_line = current_line - 1
            output_field.buffer.document = Document(
                text=new_text, cursor_position=line_cursor_pos)

    # Style.
    style = Style([("output-field", ""), ("input-field", ""),
                   ("line", "#ffffff"), ("status", "bg:grey #fff"),
                   ("searching-status", "bg:purple #fff")])

    # Run application.
    application = Application(layout=Layout(container),
                              key_bindings=kb,
                              style=style,
                              full_screen=True,
                              refresh_interval=0.3)

    application.run()
Пример #23
0
def create_layout(python_input,
                  key_bindings_manager,
                  lexer=PythonLexer,
                  extra_body=None,
                  extra_toolbars=None,
                  extra_buffer_processors=None,
                  input_buffer_height=None):
    D = LayoutDimension
    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)

    def create_python_input_window():
        def menu_position(cli):
            """
            When there is no autocompletion menu to be shown, and we have a signature,
            set the pop-up position at `bracket_start`.
            """
            b = cli.buffers[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_name=DEFAULT_BUFFER,
                lexer=lexer,
                input_processors=[
                    ConditionalProcessor(
                        processor=HighlightSearchProcessor(
                            preview_search=True),
                        filter=HasFocus(SEARCH_BUFFER),
                    ),
                    HighlightSelectionProcessor(),
                    DisplayMultipleCursors(DEFAULT_BUFFER),
                    # Show matching parentheses, but only while editing.
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(
                            chars='[](){}'),
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()
                        & Condition(lambda cli: python_input.
                                    highlight_matching_parenthesis)),
                    ConditionalProcessor(processor=AppendAutoSuggestion(),
                                         filter=~IsDone())
                ] + 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.
            get_height=(lambda cli:
                        (None if cli.is_done or python_input.
                         show_exit_confirmation else input_buffer_height)),
            wrap_lines=Condition(lambda cli: python_input.wrap_lines),
        )

    return HSplit([
        VSplit([
            HSplit([
                FloatContainer(
                    content=HSplit([create_python_input_window()] +
                                   extra_body),
                    floats=[
                        Float(xcursor=True,
                              ycursor=True,
                              content=CompletionsMenu(
                                  scroll_offset=Integer.from_callable(
                                      lambda: python_input.
                                      completion_menu_scroll_offset),
                                  max_height=12,
                                  extra_filter=show_completions_menu(
                                      python_input))),
                        Float(
                            xcursor=True,
                            ycursor=True,
                            content=MultiColumnCompletionsMenu(
                                extra_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(),
                SearchToolbar(),
                SystemToolbar(),
                ValidationToolbar(),
                CompletionsToolbar(
                    extra_filter=show_completions_toolbar(python_input)),

                # Docstring region.
                ConditionalContainer(content=Window(
                    height=D.exact(1),
                    content=FillControl('\u2500', token=Token.Separator)),
                                     filter=HasSignature(python_input)
                                     & ShowDocstring(python_input)
                                     & ~IsDone()),
                ConditionalContainer(
                    content=Window(
                        BufferControl(
                            buffer_name='docstring',
                            lexer=SimpleLexer(default_token=Token.Docstring),
                            #lexer=PythonLexer,
                        ),
                        height=D(max=12)),
                    filter=HasSignature(python_input)
                    & ShowDocstring(python_input) & ~IsDone(),
                ),
            ]),
            HSplit([
                python_sidebar(python_input),
                python_sidebar_navigation(python_input),
            ])
        ]),
    ] + extra_toolbars + [
        VSplit([
            status_bar(key_bindings_manager, python_input),
            show_sidebar_button_info(python_input),
        ])
    ])
Пример #24
0
                Label(text=text),
            ]),
            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)
Пример #25
0
def start_app(args):
    """Text-based GUI application"""
    cmd = Commands()
    completer = WordCompleter(cmd.commands(),
                              meta_dict=cmd.meta_dict(),
                              ignore_case=True)
    history = InMemoryHistory()

    # Individual windows
    input_field = TextArea(height=1,
                           prompt='ctserial> ',
                           style='class:input-field',
                           completer=completer,
                           history=history)

    output_field = TextArea(scrollbar=True,
                            style='class:output-field',
                            text='')

    statusbar = Window(content=FormattedTextControl(get_statusbar_text),
                       height=1,
                       style='class:statusbar')

    # Organization of windows
    body = FloatContainer(HSplit([
        input_field,
        Window(height=1, char='-', style='class:line'), output_field, statusbar
    ]),
                          floats=[
                              Float(xcursor=True,
                                    ycursor=True,
                                    content=CompletionsMenu(max_height=16,
                                                            scroll_offset=1))
                          ])

    # Adding menus
    root_container = MenuContainer(
        body=body,
        menu_items=[],
        # menu_items=[
        #     MenuItem('Project ', children=[
        #         MenuItem('New'),
        #         MenuItem('Open'),
        #         MenuItem('Save'),
        #         MenuItem('Save as...'),
        #         MenuItem('-', disabled=True),
        #         MenuItem('Exit'),  ]),
        #     MenuItem('View ', children=[
        #         MenuItem('Split'),  ]),
        #     MenuItem('Info ', children=[
        #         MenuItem('Help'),
        #         MenuItem('About'),  ]),  ],
        floats=[
            Float(xcursor=True,
                  ycursor=True,
                  content=CompletionsMenu(max_height=16, scroll_offset=1)),
        ])

    # The key bindings.
    kb = KeyBindings()

    @kb.add('space')
    def _(event):
        input_text = input_field.text
        cursor = len(input_text)
        input_updated = input_text[:cursor] + ' ' + input_text[cursor + 1:]
        cursor += 1
        input_field.buffer.document = Document(text=input_updated,
                                               cursor_position=cursor)
        input_field.buffer.completer = WordCompleter([], ignore_case=True)

    @kb.add('enter', filter=has_focus(input_field))
    def _(event):
        # Process commands on prompt after hitting enter key
        # tx_bytes = parse_command(input_field.text, event=event)
        input_field.buffer.completer = WordCompleter(cmd.commands(),
                                                     meta_dict=cmd.meta_dict(),
                                                     ignore_case=True)
        if len(input_field.text) == 0:
            return
        output_text = cmd.execute(input_field.text, output_field.text, event)
        input_field.buffer.reset(append_to_history=True)

        # For commands that do not send data to serial device
        if output_text == None:
            input_field.text = ''
            return
        # For invalid commands forcing users to correct them
        elif output_text == False:
            return
        # For invalid commands forcing users to correct them
        else:
            output_field.buffer.document = Document(
                text=output_text, cursor_position=len(output_text))
            input_field.text = ''

    @kb.add('c-c')
    def _(event):
        """Pressing Control-C will copy highlighted text to clipboard"""
        data = output_field.buffer.copy_selection()
        get_app().clipboard.set_data(data)

    @kb.add('c-p')
    def _(event):
        """Pressing Control-P will paste text from clipboard"""
        input_field.buffer.paste_clipboard_data(get_app().clipboard.get_data())

    @kb.add('c-q')
    def _(event):
        " Pressing Ctrl-Q will exit the user interface. "
        cmd.do_exit(input_field.text, output_field.text, event)

    @kb.add('c-d')
    def _(event):
        """Press Ctrl-D to start the python debugger"""
        import pdb
        pdb.set_trace()

    style = Style([
        # ('output-field', 'bg:#000000 #ffffff'),
        # ('input-field', 'bg:#000000 #ffffff'),
        ('line', '#004400'),
        ('statusbar', 'bg:#AAAAAA')
    ])

    # Run application.
    application = MyApplication(layout=Layout(root_container,
                                              focused_element=input_field),
                                key_bindings=kb,
                                style=style,
                                mouse_support=True,
                                full_screen=True)
    application.run()
Пример #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(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)
Пример #27
0
    Window,
    WindowAlign,
)
from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl
from prompt_toolkit.layout.layout import Layout

# 3. Create the buffers
#    ------------------

left_buffer = Buffer()
right_buffer = Buffer()

# 1. First we create the layout
#    --------------------------

left_window = Window(BufferControl(buffer=left_buffer))
right_window = Window(BufferControl(buffer=right_buffer))

body = VSplit([
    left_window,

    # A vertical line in the middle. We explicitly specify the width, to make
    # sure that the layout engine will not try to divide the whole width by
    # three for all these windows.
    Window(width=1, char='|', style='class:line'),

    # Display the Result buffer on the right.
    right_window,
])

# As a demonstration. Let's add a title bar to the top, displaying "Hello world".
Пример #28
0
def question(message, **kwargs):
    # TODO need ENTER confirmation
    default = kwargs.pop('default', True)

    # TODO style defaults on detail level
    style = kwargs.pop(
        'style',
        style_from_dict({
            Token.QuestionMark:
            '#5F819D',
            #Token.Selected: '#FF9D00',  # AWS orange
            Token.Instruction:
            '',  # default
            Token.Answer:
            '#FF9D00 bold',  # AWS orange
            Token.Question:
            'bold',
        }))
    status = {'answer': None}

    def get_prompt_tokens(cli):
        tokens = []
        T = Token

        tokens.append((Token.QuestionMark, '?'))
        tokens.append((Token.Question, ' %s ' % message))
        if isinstance(status['answer'], bool):
            tokens.append(
                (Token.Answer, ' Yes' if status['answer'] else ' No'))
        else:
            if default:
                instruction = ' (Y/n)'
            else:
                instruction = ' (y/N)'
            tokens.append((Token.Instruction, instruction))
        return tokens

    # assemble layout
    # TODO this does not work without the HSplit??
    layout = HSplit([
        Window(
            height=D.exact(1),
            content=TokenListControl(get_prompt_tokens, align_center=False),
        )
    ])

    # 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()

    @manager.registry.add_binding('n')
    @manager.registry.add_binding('N')
    def key_n(event):
        status['answer'] = False
        event.cli.set_return_value(False)

    @manager.registry.add_binding('y')
    @manager.registry.add_binding('Y')
    def key_y(event):
        status['answer'] = True
        event.cli.set_return_value(True)

    @manager.registry.add_binding(Keys.Enter, eager=True)
    def set_answer(event):
        status['answer'] = default
        event.cli.set_return_value(default)

    return Application(
        layout=layout,
        key_bindings_registry=manager.registry,
        mouse_support=False,
        style=style,
        erase_when_done=False,
    )
Пример #29
0
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut
tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus."""

# 1. The layout

left_text = '\nLeft aligned text. - (Press "q" to quit)\n\n' + LIPSUM
center_text = "Centered text.\n\n" + LIPSUM
right_text = "Right aligned text.\n\n" + LIPSUM

body = HSplit([
    Window(FormattedTextControl(left_text), align=WindowAlign.LEFT),
    Window(height=1, char="-"),
    Window(FormattedTextControl(center_text), align=WindowAlign.CENTER),
    Window(height=1, char="-"),
    Window(FormattedTextControl(right_text), align=WindowAlign.RIGHT),
])

# 2. Key bindings
kb = KeyBindings()


@kb.add("q")
def _(event):
    " Quit application. "
    event.app.exit()
Пример #30
0
Файл: layout.py Проект: pg83/zm
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),
    )