Beispiel #1
0
def python_sidebar_navigation(python_input):
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """
    def get_text_fragments():
        tokens = []

        # Show navigation info.
        tokens.extend([
            ('class:sidebar', '    '),
            ('class:sidebar.key', '[Arrows]'),
            ('class:sidebar', ' '),
            ('class:sidebar.description', 'Navigate'),
            ('class:sidebar', ' '),
            ('class:sidebar.key', '[Enter]'),
            ('class:sidebar', ' '),
            ('class:sidebar.description', 'Hide menu'),
        ])

        return tokens

    return Window(FormattedTextControl(get_text_fragments),
                  style='class:sidebar',
                  width=Dimension.exact(43),
                  height=Dimension.exact(1))
Beispiel #2
0
def setup_logging_containers(repl):
    j = KosmosShellConfig.j

    panel_line_count = j.core.myenv.config.get("LOGGER_PANEL_NRLINES", 12)
    parent_container = get_ptpython_parent_container(repl)
    parent_container.children.extend(
        [
            ConditionalContainer(
                content=Window(height=Dimension.exact(1), char="\u2500", style="class:separator"),
                filter=HasLogs(repl) & ~is_done,
            ),
            ConditionalContainer(
                content=Window(
                    BufferControl(
                        buffer=LogPane.Buffer,
                        input_processors=[FormatANSIText(), HighlightIncrementalSearchProcessor()],
                        focusable=False,
                        preview_search=True,
                    ),
                    wrap_lines=True,
                    height=Dimension.exact(panel_line_count),
                ),
                filter=HasLogs(repl) & ~is_done,
            ),
        ]
    )
Beispiel #3
0
def show_sidebar_button_info(my_app: "sqlApp") -> Container:
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    @if_mousedown
    def toggle_sidebar(mouse_event: MouseEvent) -> None:
        " Click handler for the menu. "
        my_app.show_sidebar = not my_app.show_sidebar

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

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

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style="class:status-toolbar",
            height=Dimension.exact(1),
            width=Dimension.exact(width),
        ),
        filter=~is_done
        & Condition(lambda: not my_app.show_exit_confirmation)
        & renderer_height_is_known)
    def preferred_dimensions(self, width):
        dimensions = [[]] * self.columns
        for row in self.children:
            assert isinstance(row, _Row)
            j = 0
            for cell in row.children:
                assert isinstance(cell, _Cell)

                if cell.merge != 1:
                    dimensions[j].append(cell.preferred_width(width))

                j += cell.merge

        for i, c in enumerate(dimensions):
            yield D.exact(1)

            try:
                w = self.column_widths[i]
            except IndexError:
                w = self.column_width
            if w is None:  # fitted
                yield max_layout_dimensions(c)
            else:  # fixed or weighted
                yield to_dimension(w)
        yield D.exact(1)
Beispiel #5
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(mouse_event):
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    version = sys.version_info
    tokens = [
        ('class:status-toolbar.key', '[F2]', toggle_sidebar),
        ('class:status-toolbar', ' Menu', toggle_sidebar),
        ('class:status-toolbar', ' - '),
        ('class:status-toolbar.python-version', '%s %i.%i.%i' % (platform.python_implementation(),
                                               version[0], version[1], version[2])),
        ('class:status-toolbar', ' '),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments():
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style='class:status-toolbar',
            height=Dimension.exact(1),
            width=Dimension.exact(width)),
        filter=~is_done & renderer_height_is_known &
            Condition(lambda: python_input.show_status_bar and
                                  not python_input.show_exit_confirmation))
Beispiel #6
0
def python_sidebar_navigation(python_input):
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """
    def get_text_fragments():
        tokens = []

        # Show navigation info.
        tokens.extend([
            ('class:sidebar', '    '),
            ('class:sidebar.key', '[Arrows]'),
            ('class:sidebar', ' '),
            ('class:sidebar.description', 'Navigate'),
            ('class:sidebar', ' '),
            ('class:sidebar.key', '[Enter]'),
            ('class:sidebar', ' '),
            ('class:sidebar.description', 'Hide menu'),
        ])

        return tokens

    return Window(
        FormattedTextControl(get_text_fragments),
        style='class:sidebar',
        width=Dimension.exact(43),
        height=Dimension.exact(1))
Beispiel #7
0
def show_sidebar_button_info(python_input):
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    @if_mousedown
    def toggle_sidebar(mouse_event):
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    version = sys.version_info
    tokens = [
        ('class:status-toolbar.key', '[F2]', toggle_sidebar),
        ('class:status-toolbar', ' Menu', toggle_sidebar),
        ('class:status-toolbar', ' - '),
        ('class:status-toolbar.python-version',
         '%s %i.%i.%i' % (platform.python_implementation(), version[0],
                          version[1], version[2])),
        ('class:status-toolbar', ' '),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments():
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_text_fragments),
                       style='class:status-toolbar',
                       height=Dimension.exact(1),
                       width=Dimension.exact(width)),
        filter=~is_done & renderer_height_is_known
        & Condition(lambda: python_input.show_status_bar and not python_input.
                    show_exit_confirmation))
Beispiel #8
0
 def get_width(self, progress_bar: "ProgressBar") -> AnyDimension:
     width = 5
     for counter in progress_bar.counters:
         if counter.items_completed >= 1000:
             width = 6
             break
     return Dimension.exact(width)
Beispiel #9
0
def sql_sidebar_navigation():
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """

    def get_text_fragments():
        # Show navigation info.
        return [
            ("class:sidebar.navigation", "   "),
            ("class:sidebar.navigation.key", "[Up/Dn]"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.description", "Navigate"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.key", "[L/R]"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.description", "Expand/Collapse"),
            ("class:sidebar.navigation", "\n   "),
            ("class:sidebar.navigation.key", "[Enter]"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.description", "Connect/Preview"),
        ]

    return Window(
        FormattedTextControl(get_text_fragments),
        style = "class:sidebar.navigation",
        width=Dimension.exact( 45 ),
        height=Dimension(max = 2),
    )
    def __init__(self, prev, next, table, borders,
                 window_too_small=None, align=HorizontalAlign.JUSTIFY,
                 padding=D.exact(0), padding_char=None, padding_style='',
                 width=None, height=None, z_index=None,
                 modal=False, key_bindings=None, style=''):
        assert prev or next
        self.prev = prev
        self.next = next
        self.table = table
        self.borders = borders

        children = [_HorizontalBorder(borders=borders)] * self.columns

        super().__init__(
            children=children,
            window_too_small=window_too_small,
            align=align,
            padding=padding,
            padding_char=padding_char,
            padding_style=padding_style,
            width=width,
            height=height or 1,
            z_index=z_index,
            modal=modal,
            key_bindings=key_bindings,
            style=style)
    def __init__(self, row, table, borders,
                 window_too_small=None, align=HorizontalAlign.JUSTIFY,
                 padding=D.exact(0), padding_char=None, padding_style='',
                 width=None, height=None, z_index=None,
                 modal=False, key_bindings=None, style=''):
        self.table = table
        self.borders = borders

        # ensure the row is iterable (has cells)
        if not isinstance(row, list):
            row = [row]
        children = []
        for c in row:
            m = 1
            if isinstance(c, Merge):
                c, m = c
            elif isinstance(c, dict):
                c, m = Merge(**c)
            children.append(_Cell(cell=c, table=table, row=self, merge=m))

        super().__init__(
            children=children,
            window_too_small=window_too_small,
            align=align,
            padding=padding,
            padding_char=padding_char,
            padding_style=padding_style,
            width=width,
            height=height,
            z_index=z_index,
            modal=modal,
            key_bindings=key_bindings,
            style=style)
Beispiel #12
0
def progress_dialog(
    title: AnyFormattedText = "",
    text: AnyFormattedText = "",
    run_callback: Callable[[Callable[[int], None], Callable[[str], None]], None] = (
        lambda *a: None
    ),
    style: Optional[BaseStyle] = None,
) -> Application[None]:
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    loop = get_event_loop()
    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,
        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10 ** 10),
    )

    dialog = Dialog(
        body=HSplit(
            [
                Box(Label(text=text)),
                Box(text_area, padding=D.exact(1)),
                progressbar,
            ]
        ),
        title=title,
        with_background=True,
    )
    app = _create_app(dialog, style)

    def set_percentage(value: int) -> None:
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text: str) -> None:
        loop.call_soon_threadsafe(text_area.buffer.insert_text, text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start() -> None:
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    def pre_run() -> None:
        run_in_executor_with_context(start)

    app.pre_run_callables.append(pre_run)

    return app
Beispiel #13
0
def show_sidebar_button_info(python_input: "PythonInput") -> Container:
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """

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

    version = sys.version_info
    tokens: StyleAndTextTuples = [
        ("class:status-toolbar.key", "[F2]", toggle_sidebar),
        ("class:status-toolbar", " Menu", toggle_sidebar),
        ("class:status-toolbar", " - "),
        (
            "class:status-toolbar.python-version",
            "%s %i.%i.%i"
            % (platform.python_implementation(), version[0], version[1], version[2]),
        ),
        ("class:status-toolbar", " "),
    ]
    width = fragment_list_width(tokens)

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

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style="class:status-toolbar",
            height=Dimension.exact(1),
            width=Dimension.exact(width),
        ),
        filter=~is_done
        & renderer_height_is_known
        & Condition(
            lambda: python_input.show_status_bar
            and not python_input.show_exit_confirmation
        ),
    )
def select_prompt(message, options, mark='>'):
    control = SelectControl(options)

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

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

    app = Application(layout=layout,
                      key_bindings=control.key_bindings,
                      full_screen=False)
    return app.run()
Beispiel #15
0
Datei: layout.py Projekt: pg83/zm
def python_sidebar_navigation(python_input):
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """
    def get_text_fragments():
        # Show navigation info.
        return [
            ("class:sidebar", "    "),
            ("class:sidebar.key", "[Arrows]"),
            ("class:sidebar", " "),
            ("class:sidebar.description", "Navigate"),
            ("class:sidebar", " "),
            ("class:sidebar.key", "[Enter]"),
            ("class:sidebar", " "),
            ("class:sidebar.description", "Hide menu"),
        ]

    return Window(
        FormattedTextControl(get_text_fragments),
        style="class:sidebar",
        width=Dimension.exact(43),
        height=Dimension.exact(1),
    )
def progress_dialog(title='',
                    text='',
                    run_callback=None,
                    style=None,
                    async_=False):
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    assert callable(run_callback)

    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,

        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10**10))

    dialog = Dialog(body=HSplit([
        Box(Label(text=text)),
        Box(text_area, padding=D.exact(1)),
        progressbar,
    ]),
                    title=title,
                    with_background=True)
    app = _create_app(dialog, style)

    def set_percentage(value):
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text):
        text_area.buffer.insert_text(text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start():
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    run_in_executor(start)

    if async_:
        return app.run_async()
    else:
        return app.run()
def progress_dialog(
        title: AnyFormattedText = '',
        text: AnyFormattedText = '',
        run_callback: Callable[[Callable[[int], None], Callable[[str], None]], None] = (lambda *a: None),
        style: Optional[BaseStyle] = None) -> Application[None]:
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    loop = get_event_loop()
    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,

        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10**10))

    dialog = Dialog(
        body=HSplit([
            Box(Label(text=text)),
            Box(text_area, padding=D.exact(1)),
            progressbar,
        ]),
        title=title,
        with_background=True)
    app = _create_app(dialog, style)

    def set_percentage(value: int) -> None:
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text: str) -> None:
        loop.call_soon_threadsafe(text_area.buffer.insert_text, text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start() -> None:
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    def pre_run() -> None:
        run_in_executor_with_context(start)
    app.pre_run_callables.append(pre_run)

    return app
def progress_dialog(title='', text='', run_callback=None, style=None, async_=False):
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    assert callable(run_callback)

    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,

        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10**10))

    dialog = Dialog(
        body=HSplit([
            Box(Label(text=text)),
            Box(text_area, padding=D.exact(1)),
            progressbar,
        ]),
        title=title,
        with_background=True)
    app = _create_app(dialog, style)

    def set_percentage(value):
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text):
        text_area.buffer.insert_text(text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start():
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    run_in_executor(start)

    if async_:
        return app.run_async()
    else:
        return app.run()
Beispiel #19
0
def setup_docstring_containers(repl):
    parent_container = get_ptpython_parent_container(repl)
    # the same as ptpython containers, but without signature checking
    parent_container.children.extend(
        [
            ConditionalContainer(
                content=Window(height=Dimension.exact(1), char="\u2500", style="class:separator"),
                filter=HasDocString(repl) & ShowDocstring(repl) & ~is_done,
            ),
            ConditionalContainer(
                content=Window(
                    BufferControl(buffer=repl.docstring_buffer, lexer=PygmentsLexer(PythonLexer)),
                    height=Dimension(max=12),
                ),
                filter=HasDocString(repl) & ShowDocstring(repl) & ~is_done,
            ),
        ]
    )
Beispiel #20
0
def expanding_object_notification(my_app: "sqlApp"):
    """
    Create the `Layout` for the 'Expanding object' notification.
    """
    def get_text_fragments():
        # Show navigation info.
        return [("fg:red", "Expanding object ...")]

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style="class:sidebar",
            width=Dimension.exact(45),
            height=Dimension(max=1),
        ),
        filter=~is_done
        & ShowSidebar(my_app)
        & Condition(lambda: my_app.show_expanding_object))
Beispiel #21
0
def setup_logging_containers(repl):
    parent_container = get_ptpython_parent_container(repl)
    parent_container.children.extend(
        [
            ConditionalContainer(
                content=Window(height=Dimension.exact(1), char="\u2500", style="class:separator"),
                filter=HasLogs(repl) & ~is_done,
            ),
            ConditionalContainer(
                content=Window(
                    BufferControl(
                        buffer=LogPane.Buffer,
                        input_processors=[FormatANSIText(), HighlightIncrementalSearchProcessor()],
                        focusable=False,
                        preview_search=True,
                    ),
                    height=Dimension(max=12),
                ),
                filter=HasLogs(repl) & ~is_done,
            ),
        ]
    )
Beispiel #22
0
    def __init__(
        self,
        text='',
        width=None,
        height=None,
        max_length=None,
        allowed_chars=None,
        widget=None,
        style=None,
    ):

        self.max_length = max_length

        self.buffer = FixedLengthBuffer(
            document=Document(text, 0),
            multiline=False,
            max_length=max_length,
            widget=widget,
            allowed_chars=allowed_chars,
            accept_handler=None,
        )

        self.control = BufferControl(
            buffer=self.buffer,
            focusable=True,
            focus_on_click=True,
        )

        height = D.exact(1)

        self.window = Window(
            height=height,
            width=width,
            content=self.control,
            style=style,
            wrap_lines=False,
        )
    def __init__(self,
                 text: str = '',
                 multiline: FilterOrBool = True,
                 password: FilterOrBool = False,
                 lexer: Optional[Lexer] = None,
                 auto_suggest: Optional[AutoSuggest] = None,
                 completer: Optional[Completer] = None,
                 complete_while_typing: FilterOrBool = True,
                 accept_handler: Optional[BufferAcceptHandler] = None,
                 history: Optional[History] = None,
                 focusable: FilterOrBool = True,
                 focus_on_click: FilterOrBool = False,
                 wrap_lines: FilterOrBool = True,
                 read_only: FilterOrBool = False,
                 width: AnyDimension = None,
                 height: AnyDimension = None,
                 dont_extend_height: FilterOrBool = False,
                 dont_extend_width: FilterOrBool = False,
                 line_numbers: bool = False,
                 get_line_prefix: Optional[GetLinePrefixCallable] = None,
                 scrollbar: bool = False,
                 style: str = '',
                 search_field: Optional[SearchToolbar] = None,
                 preview_search: FilterOrBool = True,
                 prompt: AnyFormattedText = '',
                 input_processors: Optional[List[Processor]] = None) -> None:

        if search_field is None:
            search_control = None
        elif isinstance(search_field, SearchToolbar):
            search_control = search_field.control

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history)

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(
                    AppendAutoSuggestion(),
                    has_focus(self.buffer) & ~is_done),
                ConditionalProcessor(
                    processor=PasswordProcessor(),
                    filter=to_filter(password)
                ),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix)
Beispiel #24
0
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """
    def get_text_fragments():
        result = []
        append = result.append
        Signature = 'class:signature-toolbar'

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

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

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

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

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

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

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

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

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            height=Dimension.exact(1)),
        filter=
            # Show only when there is a signature
            HasSignature(python_input) &
            # And there are no completions to be shown. (would cover signature pop-up.)
            ~(has_completions & (show_completions_menu(python_input) |
                                   show_multi_column_completions_menu(python_input)))
            # Signature needs to be shown.
            & ShowSignature(python_input) &
            # Not done yet.
            ~is_done)
Beispiel #25
0
    def __init__(self,
                 text: str = '',
                 multiline: FilterOrBool = True,
                 password: FilterOrBool = False,
                 lexer: Optional[Lexer] = None,
                 auto_suggest: Optional[AutoSuggest] = None,
                 completer: Optional[Completer] = None,
                 complete_while_typing: FilterOrBool = True,
                 accept_handler: Optional[BufferAcceptHandler] = None,
                 history: Optional[History] = None,
                 focusable: FilterOrBool = True,
                 focus_on_click: FilterOrBool = False,
                 wrap_lines: FilterOrBool = True,
                 read_only: FilterOrBool = False,
                 width: AnyDimension = None,
                 height: AnyDimension = None,
                 dont_extend_height: FilterOrBool = False,
                 dont_extend_width: FilterOrBool = False,
                 line_numbers: bool = False,
                 get_line_prefix: Optional[GetLinePrefixCallable] = None,
                 scrollbar: bool = False,
                 style: str = '',
                 search_field: Optional[SearchToolbar] = None,
                 preview_search: FilterOrBool = True,
                 prompt: AnyFormattedText = '',
                 input_processors: Optional[List[Processor]] = None) -> None:

        if search_field is None:
            search_control = None
        elif isinstance(search_field, SearchToolbar):
            search_control = search_field.control

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history)

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(AppendAutoSuggestion(),
                                     has_focus(self.buffer) & ~is_done),
                ConditionalProcessor(processor=PasswordProcessor(),
                                     filter=to_filter(password)),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix)
Beispiel #26
0
def progress_log_dialog(
    title: AnyFormattedText = "",
    text: AnyFormattedText = "",
    wait_text: str = "Wait",
    quit_text: str = "Quit",
    status_text: AnyFormattedText = "",
    run_callback: Callable[[
        Callable[[int], None], Callable[[str], None], Callable[
            [str], None], Callable[[dict], None], Callable[[], bool]
    ], None] = (lambda *a: None),
    style: Optional[BaseStyle] = None,
) -> Application[None]:
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    loop = get_event_loop()

    def wait_handler() -> None:
        pass

    def quit_handler() -> None:
        app = get_app()
        if not app.exited:
            app.exited = True
            app.exit(result=app.result)

    wait_button = Button(text=wait_text, handler=wait_handler)
    quit_button = Button(text=quit_text, handler=quit_handler)

    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,
        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10**10),
        width=D(preferred=10**10))
    status = Label(text=status_text)

    dialog = Dialog(
        title=title,
        body=HSplit([
            Box(Label(text=text)),
            Box(text_area, padding=D.exact(1)),
            Box(status, padding=D.exact(1)),
            progressbar,
        ]),
        buttons=[wait_button, quit_button],
        with_background=True,
    )
    app = _create_app(dialog, style)
    app.result = None
    app.exited = False

    def set_percentage(value: int) -> None:
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text: str) -> None:
        loop.call_soon_threadsafe(text_area.buffer.insert_text, text)
        app.invalidate()

    def change_status(text: str) -> None:
        status.formatted_text_control.text = text
        app.invalidate()

    def set_result(new_result: dict) -> None:
        app.result = new_result

    def get_exited() -> bool:
        return app.exited

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start() -> None:
        result = None
        try:
            result = run_callback(set_percentage, log_text, change_status,
                                  set_result, get_exited)
        finally:
            if not app.exited:
                app.exited = True
                app.exit(result=result)

    def pre_run() -> None:
        run_in_executor_with_context(start)

    app.pre_run_callables.append(pre_run)

    return app
Beispiel #27
0
 def preferred_height(self, width, max_available_height):
     return D.exact(BigClock.HEIGHT)
Beispiel #28
0
 def preferred_width(self, max_available_width):
     # Enough to display all the digits.
     return Dimension.exact(6 * len('%s' % self._get_index()) - 1)
    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)
Beispiel #30
0
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """
    def get_text_fragments() -> StyleAndTextTuples:
        result: StyleAndTextTuples = []
        append = result.append
        Signature = "class:signature-toolbar"

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

            append((Signature, " "))
            try:
                append((Signature, sig.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", "("))

            got_positional_only = False
            got_keyword_only = False

            for i, p in enumerate(sig.parameters):
                # Detect transition between positional-only and not positional-only.
                if p.kind == ParameterKind.POSITIONAL_ONLY:
                    got_positional_only = True
                if got_positional_only and p.kind != ParameterKind.POSITIONAL_ONLY:
                    got_positional_only = False
                    append((Signature, "/"))
                    append((Signature + ",operator", ", "))

                if not got_keyword_only and p.kind == ParameterKind.KEYWORD_ONLY:
                    got_keyword_only = True
                    append((Signature, "*"))
                    append((Signature + ",operator", ", "))

                sig_index = getattr(sig, "index", 0)

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

                if p.default:
                    # NOTE: For the jedi-based completion, the default is
                    #       currently still part of the name.
                    append((Signature, f"={p.default}"))

                append((Signature + ",operator", ", "))

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

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

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_text_fragments),
                       height=Dimension.exact(1)),
        filter=
        # Show only when there is a signature
        HasSignature(python_input) &
        # Signature needs to be shown.
        ShowSignature(python_input) &
        # And no sidebar is visible.
        ~ShowSidebar(python_input) &
        # Not done yet.
        ~is_done,
    )
Beispiel #31
0
    def __init__(self, text='', multiline=True, password=False,
                 lexer=None, auto_suggest=None, completer=None,
                 complete_while_typing=True, accept_handler=None, history=None,
                 focusable=True, focus_on_click=False, wrap_lines=True,
                 read_only=False, width=None, height=None,
                 dont_extend_height=False, dont_extend_width=False,
                 line_numbers=False, get_line_prefix=None, scrollbar=False,
                 style='', search_field=None, preview_search=True, prompt='',
                 input_processors=None):
       # assert isinstance(text, six.text_type)

        if search_field is None:
            search_control = None

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history)

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(
                    AppendAutoSuggestion(),
                    has_focus(self.buffer) & is_done), #
                ConditionalProcessor(
                    processor=PasswordProcessor(),
                    filter=to_filter(password)
                ),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix)
Beispiel #32
0
def sql_sidebar(my_app: "sqlApp") -> Window:
    """
    Create the `Layout` for the sidebar with the configurable objects.
    """
    @if_mousedown
    def expand_item(obj: "myDBObject") -> None:
        obj.expand()

    def tokenize_obj(obj: "myDBObject") -> StyleAndTextTuples:
        " Recursively build the token list "
        tokens: StyleAndTextTuples = []
        selected = obj is my_app.selected_object
        expanded = obj.children is not None
        connected = obj.otype == "Connection" and obj.conn.connected()
        active = my_app.active_conn is not None and my_app.active_conn is obj.conn and obj.level == 0

        act = ",active" if active else ""
        sel = ",selected" if selected else ""
        if len(obj.name) > 24 - 2 * obj.level:
            name_trim = obj.name[:24 - 2 * obj.level - 3] + "..."
        else:
            name_trim = ("%-" + str(24 - 2 * obj.level) + "s") % obj.name

        tokens.append(
            ("class:sidebar.label" + sel + act, " >" if connected else "  "))
        tokens.append(
            ("class:sidebar.label" + sel, " " * 2 * obj.level, expand_item))
        tokens.append(
            ("class:sidebar.label" + sel + act, name_trim, expand_item))
        tokens.append(("class:sidebar.status" + sel + act, " ", expand_item))
        tokens.append(("class:sidebar.status" + sel + act, "%+12s" % obj.otype,
                       expand_item))

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

        if expanded:
            tokens.append(("class:sidebar.status" + sel + act, "\/"))
        else:
            tokens.append(("class:sidebar.status" + sel + act,
                           " <" if selected else "  "))

        # Expand past the edge of the visible buffer to get an even panel
        tokens.append(("class:sidebar.status" + sel + act, " " * 10))
        return tokens

    def _buffer_pos_changed(buff):
        """ When the cursor changes in the sidebar buffer, make sure the appropriate
            database object is market as selected
        """
        # Only when this buffer has the focus.
        try:
            line_no = buff.document.cursor_position_row

            if line_no < 0:  # When the cursor is above the inserted region.
                raise IndexError

            idx = 0
            obj = my_app.obj_list[0]
            while idx < line_no:
                if not obj.next_object:
                    raise IndexError
                idx += 1
                obj = obj.next_object

            my_app.selected_object = obj

        except IndexError:
            pass

    search_buffer = Buffer(name="sidebarsearchbuffer")
    search_field = SearchToolbar(search_buffer=search_buffer, ignore_case=True)
    sidebar_buffer = Buffer(name="sidebarbuffer",
                            read_only=True,
                            on_cursor_position_changed=_buffer_pos_changed)

    class myLexer(Lexer):
        def __init__(self, token_list=None, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.token_list = token_list

        def lex_document(
                self,
                document: Document) -> Callable[[int], StyleAndTextTuples]:
            def get_line(lineno: int) -> StyleAndTextTuples:
                # TODO: raise out-of-range exception
                return self.token_list[lineno]

            return get_line

        def reset_tokens(self, tokens: [StyleAndTextTuples]):
            self.token_list = tokens

    sidebar_lexer = myLexer()

    class myControl(BufferControl):
        def move_cursor_down(self):
            my_app.select_next()

        # Need to figure out what do do here
        # AFAICT thse are only called for the mouse handler
        # when events are otherwise not handled
        def move_cursor_up(self):
            my_app.select_previous()

        def mouse_handler(self,
                          mouse_event: MouseEvent) -> "NotImplementedOrNone":
            """
                There is an intricate relationship between the cursor position
                in the sidebar document and which object is market as 'selected'
                in the linked list.  Let's not muck that up by allowing the user
                to change the cursor position in the sidebar document with the mouse.
            """
            return NotImplemented

        def create_content(self, width: int,
                           height: Optional[int]) -> UIContent:
            res = []
            res_tokens = []
            count = 0
            obj = my_app.obj_list[0]
            res.append(obj.name)
            res_tokens.append(tokenize_obj(obj))
            found_selected = obj is my_app.selected_object
            idx = 0
            while obj.next_object is not my_app.obj_list[0]:
                res.append(obj.next_object.name)
                res_tokens.append(tokenize_obj(obj.next_object))
                if obj is not my_app.selected_object and not found_selected:
                    count += 1
                    idx += len(obj.name) + 1  # Newline character
                else:
                    found_selected = True
                obj = obj.next_object

            self.buffer.set_document(
                Document(text="\n".join(res), cursor_position=idx), True)
            self.lexer.reset_tokens(res_tokens)
            return super().create_content(width, height)

    sidebar_control = myControl(
        buffer=sidebar_buffer,
        lexer=sidebar_lexer,
        search_buffer_control=search_field.control,
        focusable=True,
    )

    return HSplit([
        search_field,
        Window(sidebar_control,
               right_margins=[ScrollbarMargin(display_arrows=True)],
               style="class:sidebar",
               width=Dimension.exact(45),
               height=Dimension(min=7, preferred=33),
               scroll_offsets=ScrollOffsets(top=1, bottom=1)),
        Window(
            height=Dimension.exact(1),
            char="\u2500",
            style="class:sidebar,separator",
        ),
        expanding_object_notification(my_app),
        sql_sidebar_navigation()
    ])
Beispiel #33
0
 def preferred_width(self, max_available_width):
     # Enough to display all the digits.
     return Dimension.exact(6 * len('%s' % self._get_index()) - 1)
Beispiel #34
0
Datei: layout.py Projekt: 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),
    )
Beispiel #35
0
def python_sidebar(python_input):
    """
    Create the `Layout` for the sidebar with the configurable options.
    """
    def get_text_fragments():
        tokens = []

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

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

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

            @if_mousedown
            def goto_next(mouse_event):
                " 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))
Beispiel #36
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)
Beispiel #37
0
def sql_sidebar(my_app: "sqlApp") -> Window:
    """
    Create the `Layout` for the sidebar with the configurable objects.
    """

    @if_mousedown
    def expand_item(obj: "myDBObject") -> None:
        obj.expand()

    def tokenize_obj(obj: "myDBObject") -> StyleAndTextTuples:
        " Recursively build the token list "
        tokens: StyleAndTextTuples = []
        selected = obj is my_app.selected_object
        expanded = obj.children is not None
        connected = obj.otype == "Connection" and obj.conn.connected()
        active = my_app.active_conn is not None and my_app.active_conn is obj.conn and obj.level == 0

        act = ",active" if active else ""
        sel = ",selected" if selected else ""
        if len(obj.name) > 24 -  2 * obj.level:
            name_trim = obj.name[:24 - 2 * obj.level - 3] + "..."
        else:
            name_trim = ("%-" + str(24 - 2 * obj.level) + "s") % obj.name

        tokens.append(("class:sidebar.label" + sel + act, " >" if connected else "  "))
        tokens.append(
            ("class:sidebar.label" + sel, " " * 2 * obj.level, expand_item)
        )
        tokens.append(
            ("class:sidebar.label" + sel + act,
            name_trim,
            expand_item)
        )
        tokens.append(("class:sidebar.status" + sel + act, " ", expand_item))
        tokens.append(("class:sidebar.status" + sel + act, "%+12s" % obj.otype, expand_item))

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

        if expanded:
            tokens.append(("class:sidebar.status" + sel + act, "\/"))
        else:
            tokens.append(("class:sidebar.status" + sel + act, " <" if selected else "  "))

        # Expand past the edge of the visible buffer to get an even panel
        tokens.append(("class:sidebar.status" + sel + act, " " * 10))
        return tokens

    search_buffer = Buffer(name = "sidebarsearchbuffer")
    search_field = SearchToolbar(
        search_buffer = search_buffer,
        ignore_case = True
    )
    def _buffer_pos_changed(buff):
        """ This callback gets executed after cursor position changes.  Most
            of the time we register a key-press (up / down), we change the
            selected object and as a result of that the cursor changes.  By that
            time we don't need to updat the selected object (cursor changed as
            a result of the selected object being updated).  The one exception
            is when searching the sidebar buffer.  When this happens the cursor
            moves ahead of the selected object.  When that happens, here we
            update the selected object to follow suit.
        """
        if buff.document.cursor_position_row != my_app.selected_object_idx[0]:
            my_app.select(buff.document.cursor_position_row)

    sidebar_buffer = Buffer(
        name = "sidebarbuffer",
        read_only = True,
        on_cursor_position_changed = _buffer_pos_changed
    )

    class myLexer(Lexer):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self._obj_list = []

        def add_objects(self, objects: List):
            self._obj_list = objects

        def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]:
            def get_line(lineno: int) -> StyleAndTextTuples:
                # TODO: raise out-of-range exception
                return tokenize_obj(self._obj_list[lineno])
            return get_line


    sidebar_lexer = myLexer()

    class myControl(BufferControl):

        def move_cursor_down(self):
            my_app.select_next()
        # Need to figure out what do do here
        # AFAICT these are only called for the mouse handler
        # when events are otherwise not handled
        def move_cursor_up(self):
            my_app.select_previous()

        def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone":
            """
                There is an intricate relationship between the cursor position
                in the sidebar document and which object is market as 'selected'
                in the linked list.  Let's not muck that up by allowing the user
                to change the cursor position in the sidebar document with the mouse.
            """
            return NotImplemented

        def create_content(self, width: int, height: Optional[int]) -> UIContent:
            # Only traverse the obj_list if it has been expanded / collapsed
            if not my_app.obj_list_changed:
                self.buffer.cursor_position = my_app.selected_object_idx[1]
                return super().create_content(width, height)

            res = []
            obj = my_app.obj_list[0]
            res.append(obj)
            while obj.next_object is not my_app.obj_list[0]:
                res.append(obj.next_object)
                obj = obj.next_object

            self.lexer.add_objects(res)
            self.buffer.set_document(Document(
                text = "\n".join([a.name for a in res]), cursor_position = my_app.selected_object_idx[1]), True)
            # Reset obj_list_changed flag, now that we have had a chance to
            # regenerate the sidebar document content
            my_app.obj_list_changed = False
            return super().create_content(width, height)



    sidebar_control = myControl(
            buffer = sidebar_buffer,
            lexer = sidebar_lexer,
            search_buffer_control = search_field.control,
            focusable = True,
            )

    return HSplit([
        search_field,
        Window(
            sidebar_control,
            right_margins = [ScrollbarMargin(display_arrows = True)],
            style = "class:sidebar",
            width = Dimension.exact( 45 ),
            height = Dimension(min = 7, preferred = 33),
            scroll_offsets = ScrollOffsets(top = 1, bottom = 1)),
        Window(
            height = Dimension.exact(1),
            char = "\u2500",
            style = "class:sidebar,separator",
            ),
        expanding_object_notification(my_app),
        sql_sidebar_navigation()])
Beispiel #38
0
 def preferred_height(self, width, max_available_height):
     return Dimension.exact(self.HEIGHT)
Beispiel #39
0
    def __init__(self,
                 text='',
                 multiline=True,
                 password=False,
                 lexer=None,
                 completer=None,
                 accept_handler=None,
                 focusable=True,
                 wrap_lines=True,
                 read_only=False,
                 width=None,
                 height=None,
                 dont_extend_height=False,
                 dont_extend_width=False,
                 line_numbers=False,
                 scrollbar=False,
                 style='',
                 input_processor=None,
                 search_field=None,
                 preview_search=True,
                 prompt=''):
        assert isinstance(text, six.text_type)
        assert search_field is None or isinstance(search_field, SearchToolbar)

        if search_field is None:
            search_control = None
        elif isinstance(search_field, SearchToolbar):
            search_control = search_field.control

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=read_only,
            completer=completer,
            complete_while_typing=True,
            accept_handler=lambda buff: accept_handler and accept_handler())

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=lexer,
            input_processor=merge_processors([
                ConditionalProcessor(processor=PasswordProcessor(),
                                     filter=to_filter(password)),
                HighlightSearchProcessor(preview_search=preview_search),
                HighlightSelectionProcessor(),
                DisplayMultipleCursors(),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ]),
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            wrap_lines = False  # Never wrap for single line input.
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(height=height,
                             width=width,
                             dont_extend_height=dont_extend_height,
                             dont_extend_width=dont_extend_width,
                             content=self.control,
                             style=style,
                             wrap_lines=wrap_lines,
                             left_margins=left_margins,
                             right_margins=right_margins)
Beispiel #40
0
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """
    def get_text_fragments():
        result = []
        append = result.append
        Signature = 'class:signature-toolbar'

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

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

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

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

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

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

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

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

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_text_fragments),
                       height=Dimension.exact(1)),
        filter=
        # Show only when there is a signature
        HasSignature(python_input) &
        # And there are no completions to be shown. (would cover signature pop-up.)
        ~(has_completions &
          (show_completions_menu(python_input)
           | show_multi_column_completions_menu(python_input)))
        # Signature needs to be shown.
        & ShowSignature(python_input) &
        # Not done yet.
        ~is_done)
Beispiel #41
0
 def preferred_height(self, width, max_available_height):
     return Dimension.exact(self.HEIGHT)
Beispiel #42
0
def python_sidebar(python_input):
    """
    Create the `Layout` for the sidebar with the configurable options.
    """
    def get_text_fragments():
        tokens = []

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

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

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

            @if_mousedown
            def goto_next(mouse_event):
                " 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))
Beispiel #43
0
 def preferred_width(self, max_available_width):
     return D.exact(BigClock.WIDTH)