Example #1
0
    def __init__(self, editor, manager, window_arrangement):
        self.editor = editor  # Back reference to editor.
        self.manager = manager
        self.window_arrangement = window_arrangement

        # Mapping from (`window_arrangement.Window`, `EditorBuffer`) to a frame
        # (Layout instance).
        # We keep this as a cache in order to easily reuse the same frames when
        # the layout is updated. (We don't want to create new frames on every
        # update call, because that way, we would loose some state, like the
        # vertical scroll offset.)
        self._frames = {}

        self._fc = FloatContainer(
            content=VSplit([
                Window(BufferControl())  # Dummy window
            ]),
            floats=[
                Float(xcursor=True, ycursor=True,
                      content=CompletionsMenu(max_height=12,
                                              scroll_offset=2,
                                              extra_filter=~HasFocus(COMMAND_BUFFER))),
                Float(content=BufferListOverlay(editor), bottom=1, left=0),
                Float(bottom=1, left=0, right=0, height=1,
                      content=CompletionsToolbar(
                          extra_filter=HasFocus(COMMAND_BUFFER) &
                                       ~bufferlist_overlay_visible_filter &
                                       Condition(lambda cli: editor.show_wildmenu))),
                Float(bottom=1, left=0, right=0, height=1,
                      content=ValidationToolbar()),
                Float(bottom=1, left=0, right=0, height=1,
                      content=MessageToolbarBar(editor)),
                Float(content=WelcomeMessageWindow(editor),
                      height=WELCOME_MESSAGE_HEIGHT,
                      width=WELCOME_MESSAGE_WIDTH),
            ]
        )

        self.layout = FloatContainer(
            content=HSplit([
                TabsToolbar(editor),
                self._fc,
                CommandLine(),
                ReportMessageToolbar(editor),
                SystemToolbar(),
                SearchToolbar(vi_mode=True),
            ]),
            floats=[
                Float(right=0, height=1, bottom=0, width=5,
                      content=SimpleArgToolbar()),
            ]
        )
Example #2
0
    def get_root_container(self):
        solution_containers = [
            HSplit([
                self._get_grid_container(grid),
                Button(
                    "Select",
                    functools.partial(self.multi_screen.app.exit,
                                      result=grid)),
            ]) for grid in self.solution_grids
        ]

        challenge_grid_container = Box(
            self._get_grid_container(self.challenge_grid))

        return FloatContainer(
            Box(
                Frame(
                    HSplit(
                        [
                            challenge_grid_container,
                            VSplit(
                                solution_containers,
                                padding=2,
                            ),
                        ],
                        padding=1,
                    ), ), ),
            floats=[],
        )
Example #3
0
def make_app(path_to_checklist, new_session):
    session = ChecklistSession(path_to_checklist, new_session)
    checklist = session.load()

    def status_bar_text():
        items = checklist.items()
        return "{name} : {checked}/{total} done | 'q': quit | 'z': undo | '?' help | <up>/<down> moves | <space> toggles".format(
            name=checklist.name,
            checked=len([i for i in items if i.checked]),
            total=len(items))

    checklist_window = Window(ChecklistControl(checklist, session),
                              left_margins=[NumberedMargin()],
                              right_margins=[
                                  ScrollbarMargin(display_arrows=True),
                              ])
    status_bar_window = Window(content=FormattedTextControl(status_bar_text),
                               height=1,
                               style='reverse')

    root_container = FloatContainer(
        content=HSplit([
            checklist_window,
            status_bar_window,
        ]),
        floats=[],
    )

    if session.duplicates:
        root_container.floats.append(
            Float(content=DuplicatesWarningDialog(session.duplicates)))

    return Application(layout=Layout(root_container),
                       full_screen=True,
                       key_bindings=build_key_bindings())
Example #4
0
    def __init__(self):
        self.no_action_dialog = NoActionDialog(
            ok_btn_cb=self.kb_run_action_or_dismiss)
        self.key_bindings = self._init_keybindings()

        tasks = [
            Task('task1, summary',
                 "Longer description",
                 "lightblue",
                 action=OpenOrStart('https://github.com/')),
            Task('task2, summary', "Longer description", "orange"),
            Task('task3, summary', "Longer description", "lightgreen"),
            Task('task4, summary', "Longer description", "darkred"),
            Task('task5, summary', "Longer description", "gray"),
            Task('task6, summary', "Longer description", "darkmagenta"),
        ]
        self.tasklist = TaskList(
            tasks, default_action=lambda t: self.no_action_dialog.show())

        layout = Layout(
            FloatContainer(content=self.tasklist,
                           floats=[Float(self.no_action_dialog)]))

        style = Style([])

        super().__init__(layout,
                         style,
                         key_bindings=self.key_bindings,
                         full_screen=True)
Example #5
0
 def __init__(self, buffer, **kwargs):
     self.buffer = buffer
     self.before_input_text = kwargs.get("before_input_text", "➜ ")
     self.title = kwargs.get("title", "COMMAND SHELL")
     self._buffer = buffer
     self._buffer_control = BufferControl(
         buffer=self.buffer,
         input_processors=[BeforeInput(text=self.before_input_text)],
         focus_on_click=True,
     )
     self.window = Frame(
         title=self.title,
         key_bindings=self.kbindings(),
         body=FloatContainer(
             content=Window(self._buffer_control),
             key_bindings=None,
             floats=[
                 Float(
                     xcursor=True,
                     ycursor=True,
                     content=CompletionsMenu(max_height=5, scroll_offset=1),
                 )
             ],
         ),
         height=3,
     )
Example #6
0
    def get_root_container(self) -> FloatContainer:
        validator = CoordinateValidator(self.maze_grid)

        maze_grid_container = Label(text=self.maze_grid.format_grid, )

        coordinates_input_container = Window(
            BufferControl(
                buffer=Buffer(
                    validator=validator,
                    validate_while_typing=False,
                    multiline=False,
                    accept_handler=self._accept_handler,
                ),
                input_processors=[
                    BeforeInput("Enter coordinates (x, y): "),
                ],
            ), )

        validation_toolbar = ConditionalContainer(
            ValidationToolbar(),
            filter=~is_done,
        )

        return FloatContainer(
            HSplit([
                maze_grid_container,
                HorizontalLine(),
                coordinates_input_container,
                validation_toolbar,
            ]),
            floats=[],
        )
Example #7
0
    def create(self):
        self.display_layout = display_container.create()
        completions = Float(xcursor=True,
                            ycursor=True,
                            content=CompletionsMenu(max_height=16,
                                                    scroll_offset=1))
        self.float_container = FloatContainer(content=self.display_layout,
                                              floats=[completions])

        return Layout(HSplit([self.float_container]),
                      focused_element=self.display_layout)
def create_default_layout(message='', lexer=None, is_password=False,
                          reserve_space_for_menu=False, get_bottom_toolbar_tokens=None):
    """
    Generate default layout.
    """
    assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens)

    # Create processors list.
    input_processors = [HighlightSearchProcessor(), HighlightSelectionProcessor()]
    if is_password:
        input_processors.extend([PasswordProcessor(), DefaultPrompt(message)])
    else:
        input_processors.append(DefaultPrompt(message))

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

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

    # Create and return Layout instance.
    return HSplit([
        FloatContainer(
            Window(
                BufferControl(
                    input_processors=input_processors,
                    lexer=lexer,
                    # Enable preview_search, we want to have immediate feedback
                    # in reverse-i-search mode.
                    preview_search=Always()),
                get_height=get_height,
            ),
            [
                Float(xcursor=True,
                      ycursor=True,
                      content=CompletionsMenu(max_height=16,
                                              extra_filter=HasFocus(DEFAULT_BUFFER)))
            ]
        ),
        ValidationToolbar(),
        SystemToolbar(),
    ] + toolbars)
Example #9
0
def create_default_layout(message='', lexer=None, is_password=False,
                          reserve_space_for_menu=False, get_bottom_toolbar_tokens=None):
    """
    Generate default layout.
    """
    assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens)

    # Create processors list.
    if is_password:
        input_processors = [PasswordProcessor(), DefaultPrompt(message)]
    else:
        input_processors = [DefaultPrompt(message)]

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

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

    # Create and return Layout instance.
    return HSplit([
        FloatContainer(
            Window(
                BufferControl(
                    input_processors=input_processors,
                    lexer=lexer),
                get_height=get_height,
            ),
            [
                Float(xcursor=True,
                      ycursor=True,
                      content=CompletionsMenu(max_height=16,
                                              extra_filter=HasFocus('default')))
            ]
        ),
        ValidationToolbar(),
        SystemToolbar(),
    ] + toolbars)
Example #10
0
    def _get_layout(self):
        menu_layout = self._current_menu.get_layout()
        if self._current_menu.is_framed:
            menu_layout = Frame(menu_layout, title=self.header_string)

        if self._float_message_layout:
            menu_layout = FloatContainer(
                content=menu_layout,
                floats=[
                    Float(
                        content=self._float_message_layout
                    )
                ]
            )

        return menu_layout
Example #11
0
def select_menu(items, display_format=None, max_height=10):
    """ Presents a list of options and allows the user to select one.

    This presents a static list of options and prompts the user to select one.
    This is similar to a completion menu but is different in that it does not
    allow a user to type and the returned value is always a member of the list.

    :type items: list
    :param list: The list of items to be selected from. If this list contains
    elements that are not strings the display_format option must be specified.

    :type display_format: Callable[[Any], str]
    :param display_format: A callable that takes a single element from the
    items list as input and returns a string used to represent the item in the
    menu.

    :type max_height: int
    :param max_height: The max number of items to show in the list at a time.

    :returns: The selected element from the items list.
    """
    app_bindings = KeyBindings()

    @app_bindings.add('c-c')
    def exit_app(event):
        event.app.exit(exception=KeyboardInterrupt, style='class:aborting')

    min_height = min(max_height, len(items))
    menu_window = Window(
        SelectionMenuControl(items, display_format=display_format),
        always_hide_cursor=False,
        height=Dimension(min=min_height, max=min_height),
        scroll_offsets=ScrollOffsets(),
        right_margins=[ScrollbarMargin()],
    )

    # Using a FloatContainer was the only way I was able to succesfully
    # limit the height and width of the window.
    content = FloatContainer(
        Window(height=Dimension(min=min_height, max=min_height)),
        [Float(menu_window, top=0, left=0)])
    app = Application(
        layout=Layout(content),
        key_bindings=app_bindings,
        erase_when_done=True,
    )
    return app.run()
Example #12
0
def main():
    # Create a big layout of many text areas, then wrap them in a `ScrollablePane`.
    root_container = VSplit([
        Label("<left column>"),
        HSplit([
            Label("ScrollContainer Demo"),
            Frame(
                ScrollablePane(
                    HSplit([
                        Frame(
                            TextArea(
                                text=f"label-{i}",
                                completer=animal_completer,
                            )) for i in range(20)
                    ])), ),
        ]),
    ])

    root_container = FloatContainer(
        root_container,
        floats=[
            Float(
                xcursor=True,
                ycursor=True,
                content=CompletionsMenu(max_height=16, scroll_offset=1),
            ),
        ],
    )

    layout = Layout(container=root_container)

    # Key bindings.
    kb = KeyBindings()

    @kb.add("c-c")
    def exit(event) -> None:
        get_app().exit()

    kb.add("tab")(focus_next)
    kb.add("s-tab")(focus_previous)

    # Create and run application.
    application = Application(layout=layout,
                              key_bindings=kb,
                              full_screen=True,
                              mouse_support=True)
    application.run()
Example #13
0
 def get_layout(self) -> Layout:
     root_container = HSplit([
         self._get_main_title_layout(),
         self._get_columns_layout(),
         self._get_main_content_layout(),
         Window(width=2, height=1, char="."),
         self.__bottom.get_input_instructions_view()
     ])
     root_container = FloatContainer(
         root_container,
         floats=[
             Float(
                 xcursor=True,
                 ycursor=True,
                 content=CompletionsMenu(max_height=16, scroll_offset=1),
             ),
         ],
     )
     return Layout(container=root_container)
Example #14
0
 def create_app(self, focus):
     ctx = self.ctx
     ctx.cmd_buffer.on_text_changed += self.process_key
     ctx.input_buffer.on_text_changed += self.process_key
     ctx.cmd_buffer.cursor_position = len(ctx.cmd_buffer.text)
     if focus:
         focused_element = {
             "COMMAND": ctx.cmd_buffer,
             "c": ctx.cmd_buffer,
             "INPUT": ctx.input_buffer,
             "i": ctx.input_buffer,
             "OUTPUT": ctx.output_buffer,
             "o": ctx.output_buffer,
         }[focus]
     else:
         focused_element = ctx.cmd_buffer if ctx.input_buffer.text else ctx.input_buffer
     layout = Layout(
         FloatContainer(
             HSplit(
                 [
                     self.create_boxes(),
                     self.create_status_bar(),
                     self.create_cmd_bar(),
                 ]
             ),
             floats=[
                 Float(self.create_help()),
             ],
         ),
         focused_element=focused_element,
     )
     return Application(
         key_bindings=kb,
         editing_mode=EditingMode.VI,
         clipboard=PyperclipClipboard(),
         color_depth=ColorDepth.from_env() or ColorDepth.DEPTH_24_BIT,
         full_screen=True,
         mouse_support=True,
         include_default_pygments_style=False,
         style=application_style,
         layout=layout,
     )
Example #15
0
    def create(self):

        sort_by = SortOrder.sort_by
        order = SortOrder.order

        self.body = titled_body.create(sort_by=sort_by, order=order)

        self.container = HSplit([self.body])

        completions = Float(xcursor=True,
                            ycursor=True,
                            content=CompletionsMenu(max_height=16,
                                                    scroll_offset=1))

        self.float_container = FloatContainer(content=self.container,
                                              floats=[completions])

        self.floats = self.float_container.floats

        return self.float_container
Example #16
0
    def get_root_container(self) -> FloatContainer:
        tree_lines = self.tree.format_tree(hide_values=True).splitlines()
        self.node_inputs = [
            TextArea(wrap_lines=False,
                     style="class:tree-node",
                     width=NODE_INPUT_WIDTH) for _ in self.tree.descendants
        ]
        tree_labels = [
            Label(line, dont_extend_width=True) for line in tree_lines
        ]

        tree_input_container = Frame(
            HSplit([
                VSplit([label, button])
                for label, button in zip(tree_labels, self.node_inputs)
            ]),
            title="Tree",
        )

        buttons = [
            Button("Done", handler=self.handle_input_confirm),
        ]

        button_container = Box(VSplit(buttons, padding=4), padding_top=1)

        tree_panel_container = Box(
            HSplit([
                tree_input_container,
                button_container,
            ]))

        table_container = Label(self.closure_table.format_table())

        root_container = FloatContainer(
            VSplit([tree_panel_container, table_container]),
            floats=[],
        )

        return root_container
Example #17
0
def create_layout(buffers,
                  settings,
                  key_bindings_manager,
                  python_prompt_control=None,
                  lexer=PythonLexer,
                  extra_sidebars=None,
                  extra_buffer_processors=None):
    D = LayoutDimension
    show_all_buffers = Condition(lambda cli: settings.show_all_buffers)
    extra_sidebars = extra_sidebars or []
    extra_buffer_processors = extra_buffer_processors or []

    def create_buffer_window(buffer_name):
        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[buffer_name]

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

        return Window(
            BufferControl(
                buffer_name=buffer_name,
                lexer=lexer,
                show_line_numbers=ShowLineNumbersFilter(settings, buffer_name),
                input_processors=[BracketsMismatchProcessor()] +
                extra_buffer_processors,
                menu_position=menu_position,
            ),
            # As long as we're editing, prefer a minimal height of 8.
            get_height=(lambda cli: (None if cli.is_done else D(min=6))),

            # When done, show only if this was focussed.
            filter=(~IsDone() & show_all_buffers)
            | PythonBufferFocussed(buffer_name, settings))

    def create_buffer_window_separator(buffer_name):
        return Window(width=D.exact(1),
                      content=FillControl('\u2502', token=Token.Separator),
                      filter=~IsDone() & show_all_buffers)

    buffer_windows = []
    for b in sorted(buffers):
        if b.startswith('python-'):
            buffer_windows.append(create_buffer_window_separator(b))
            buffer_windows.append(create_buffer_window(b))

    return HSplit([
        VSplit([
            HSplit([
                TabsToolbar(settings),
                FloatContainer(content=HSplit([
                    VSplit([
                        Window(
                            python_prompt_control,
                            dont_extend_width=True,
                        ),
                        VSplit(buffer_windows),
                    ]),
                ]),
                               floats=[
                                   Float(xcursor=True,
                                         ycursor=True,
                                         content=CompletionsMenu(
                                             max_height=12,
                                             extra_filter=ShowCompletionsMenu(
                                                 settings))),
                                   Float(xcursor=True,
                                         ycursor=True,
                                         content=SignatureToolbar(settings))
                               ]),
                ArgToolbar(),
                SearchToolbar(),
                SystemToolbar(),
                ValidationToolbar(),
                CompletionsToolbar(
                    extra_filter=ShowCompletionsToolbar(settings)),

                # Docstring region.
                Window(height=D.exact(1),
                       content=FillControl('\u2500', token=Token.Separator),
                       filter=HasSignature(settings) & ShowDocstring(settings)
                       & ~IsDone()),
                Window(
                    BufferControl(
                        buffer_name='docstring',
                        default_token=Token.Docstring,
                        #lexer=PythonLexer,
                    ),
                    filter=HasSignature(settings) & ShowDocstring(settings)
                    & ~IsDone(),
                    height=D(max=12),
                ),
            ]),
        ] + extra_sidebars + [
            PythonSidebar(settings, key_bindings_manager),
        ]),
        VSplit([
            PythonToolbar(key_bindings_manager, settings),
            ShowSidebarButtonInfo(),
        ])
    ])
Example #18
0
 def __enter__(self) -> Application:
     """Build a Layout and instantiate an Application around it."""
     main = VSplit(
         (
             # Command History on most of the left panel, Prompt at the bottom.
             HSplit(
                 (
                     self.terminal,
                     ConditionalContainer(
                         Window(  # Command Prompt.
                             BufferControl(self.command_buffer, self.procs),
                             dont_extend_height=True,
                             wrap_lines=True,
                         ),
                         Condition(lambda: not self.busy()),
                     ),
                     ConditionalContainer(
                         Window(  # "Busy" Prompt, blocks Commands.
                             FormattedTextControl("..."),
                             height=1,
                             ignore_content_width=True,
                         ),
                         Condition(self.busy),
                     ),
                     ConditionalContainer(
                         Window(  # Completion Bar.
                             FormattedTextControl(lambda: self.handler.completion),
                             height=1,
                             ignore_content_width=True,
                             style=self.style_meth,
                         ),
                         Condition(lambda: bool(self.handler.completion)),
                     ),
                 )
             ),
             ConditionalContainer(  # Vertical Line.
                 HSplit(
                     (
                         VerticalLine(),
                         Window(
                             FormattedTextControl(
                                 lambda: "├" if self.state is Mode.SCOPES else "│"
                             ),
                             width=1,
                             height=1,
                         ),
                         VerticalLine(),
                     )
                 ),
                 Condition(lambda: self.state is not Mode.OFF),
             ),
             ConditionalContainer(  # Scopes Panel. Visualizes nearby Space.
                 HSplit(
                     (
                         # Top-down visualization on the upper panel.
                         Window(
                             self.scope_topdown,
                             ignore_content_height=True,
                             ignore_content_width=True,
                         ),
                         HorizontalLine(),
                         # Visualization from behind on the lower panel.
                         Window(
                             self.scope_horizon,
                             ignore_content_height=True,
                             ignore_content_width=True,
                         ),
                     )
                 ),
                 Condition(lambda: self.state is Mode.SCOPES),
             ),
             ConditionalContainer(  # Scans Panel. Lists nearby Objects.
                 Window(self.scans, ignore_content_width=True),
                 Condition(lambda: self.state is Mode.SCANS),
             ),
             ConditionalContainer(  # Orders Panel. Shows future actions.
                 Window(self.orders, ignore_content_width=True),
                 Condition(lambda: self.state is Mode.ORDERS),
             ),
         )
     )
     root = Layout(
         HSplit(
             (
                 Window(self.header_bar, height=1, style=self.style_meth),
                 FloatContainer(main, self.floating_elems),
             )
         )
     )
     root.focus(self.command_buffer)
     self._app = Application(root, STYLE, full_screen=True, key_bindings=self.kb)
     return self._app
Example #19
0
def main():
    manager = KeyBindingManager(enable_system_bindings=Always())

    D = LayoutDimension
    layout = HSplit([
        VSplit([
            Window(width=D(min=15, max=30, preferred=30),
                   content=FillControl('a', token=Token.A)),
            Window(width=D.exact(1),
                   content=FillControl('|', token=Token.Line)),
            Window(content=TokenListControl.static([(Token.HelloWorld,
                                                     lipsum)])),
            Window(width=D.exact(1),
                   content=FillControl('|', token=Token.Line)),
            Window(content=BufferControl(
                lexer=PygmentsLexer(PythonLexer),
                margin=NumberredMargin(),
                input_processors=[
                    DefaultPrompt.from_message('python> '),
                    AfterInput.static(' <python', token=Token.AfterInput),
                ]), ),
            Window(width=D.exact(1),
                   content=FillControl('|', token=Token.Line)),
            HSplit([
                Window(width=D(max=40),
                       height=D.exact(4),
                       content=FillControl('b', token=Token.B)),
                Window(width=D(max=40),
                       content=FillControl('f', token=Token.F)),
                Window(width=D.exact(30),
                       height=D.exact(2),
                       content=FillControl('c', token=Token.C)),
            ]),
            #CompletionsMenu(),
        ]),
        Window(height=D.exact(1), content=FillControl('-', token=Token.Line)),
        Window(height=D.exact(3), content=FillControl('d', token=Token.D)),
        SystemToolbar(),
        ArgToolbar(),
        CompletionsToolbar(),
        SearchToolbar(),
    ])

    layout = FloatContainer(content=layout,
                            floats=[
                                Float(xcursor=True,
                                      ycursor=True,
                                      content=VSplit([
                                          Window(width=D.exact(5),
                                                 content=FillControl(
                                                     'f', token=Token.F)),
                                          CompletionsMenu(),
                                      ])),
                            ])

    eventloop = create_eventloop()
    application = Application(layout=layout,
                              style=TestStyle,
                              key_bindings_registry=manager.registry,
                              buffer=Buffer(is_multiline=Always(),
                                            completer=TestCompleter()))

    cli = CommandLineInterface(application=application, eventloop=eventloop)

    cli.run()
    eventloop.close()
        max_height=16,
        scroll_offset=1))

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

root_container = FloatContainer(
    content=HSplit([
        output_field,
        Window(height=1, char="-", style="class:line"),
        input_field,
        search_field
    ]),
    floats=[
        completions_menu
    ],
    key_bindings=KeyBindings())

layout = Layout(root_container, focused_element=input_field)


def input_parser(buff):
    global update_announcements_enabled
    global update_leaderboard_enabled
    global block_backtick
    loop = asyncio.get_event_loop()
Example #21
0
    def create_layout(self):
        # Create functions that will dynamically split the prompt. (If we have
        # a multiline prompt.)
        has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \
            _split_multiline_prompt(self.formatted_message)

        default_buffer = ModalBuffer(
            name=DEFAULT_BUFFER,
            complete_while_typing=Condition(
                lambda: self.complete_while_typing),
            completer=DynamicCompleter(lambda: self.completer),
            history=self.history,
            get_tempfile_suffix=lambda: self.tempfile_suffix)

        search_buffer = Buffer(name=SEARCH_BUFFER)

        search_toolbar = SearchToolbar(search_buffer)

        input_processor = merge_processors([
            ConditionalProcessor(HighlightSearchProcessor(preview_search=True),
                                 has_focus(search_buffer)),
            HighlightSelectionProcessor(),
            HighlightMatchingBracketProcessor(),
            DisplayMultipleCursors()
        ])

        default_buffer_control = BufferControl(
            buffer=default_buffer,
            search_buffer_control=search_toolbar.control,
            input_processor=input_processor,
            lexer=DynamicLexer(lambda: self.lexer),
            preview_search=True)

        def get_default_buffer_control_height():
            # If there is an autocompletion menu to be shown, make sure that our
            # layout has at least a minimal height in order to display it.
            space = self.reserve_space_for_menu

            if space and not get_app().is_done:
                buff = default_buffer
                if buff.complete_while_typing(
                ) or buff.complete_state is not None:
                    return Dimension(min=space)
            return Dimension()

        def get_continuation(width):
            prompt_continuation = self.prompt_continuation

            if callable(prompt_continuation):
                prompt_continuation = prompt_continuation(width)

            return to_formatted_text(prompt_continuation,
                                     style='class:prompt-continuation')

        default_buffer_window = Window(
            default_buffer_control,
            height=get_default_buffer_control_height,
            left_margins=[PromptMargin(get_prompt_text_2, get_continuation)],
            wrap_lines=True)

        def get_arg_text():
            arg = self.app.key_processor.arg
            if arg == '-':
                arg = '-1'

            return [('class:arg-toolbar', 'Repeat: '),
                    ('class:arg-toolbar.text', arg)]

        # Build the layout.
        layout = HSplit([
            # The main input, with completion menus floating on top of it.
            FloatContainer(
                HSplit([
                    ConditionalContainer(
                        Window(FormattedTextControl(get_prompt_text_1),
                               dont_extend_height=True),
                        Condition(has_before_fragments)),
                    default_buffer_window,
                ]),
                [
                    # Completion menus.
                    Float(xcursor=True,
                          ycursor=True,
                          content=MultiColumnCompletionsMenu(
                              show_meta=True,
                              extra_filter=has_focus(default_buffer)))
                ]),
            ConditionalContainer(
                Window(FormattedTextControl(get_arg_text), height=1), has_arg),
            search_toolbar
        ])

        return Layout(layout, default_buffer_window)
Example #22
0
    def _create_app(self):
        # Create UI Application.
        title_toolbar = ConditionalContainer(
            Window(
                FormattedTextControl(lambda: self.title),
                height=1,
                style="class:progressbar,title",
            ),
            filter=Condition(lambda: self.title is not None),
        )

        bottom_toolbar = ConditionalContainer(
            Window(
                FormattedTextControl(
                    lambda: self.bottom_toolbar, style="class:bottom-toolbar.text"
                ),
                style="class:bottom-toolbar",
                height=1,
            ),
            filter=~is_done
                   & renderer_height_is_known
                   & Condition(lambda: self.bottom_toolbar is not None),
        )

        def width_for_formatter(formatter: Formatter) -> AnyDimension:
            # Needs to be passed as callable (partial) to the 'width'
            # parameter, because we want to call it on every resize.
            return formatter.get_width(progress_bar=self)

        progress_controls = [
            Window(
                content=_ProgressControl(self, f),
                width=functools.partial(width_for_formatter, f),
            )
            for f in self.formatters
        ]

        body = self.create_content(progress_controls)

        self.root = FloatContainer(
            content=HSplit(
                    [
                        title_toolbar,
                        body,
                        bottom_toolbar,
                    ]
                ),
            floats=[]
        )

        if self.key_bindings is None:
            self.create_key_bindings()

        self.app: Application[None] = Application(
            min_redraw_interval=0.05,
            layout=Layout(self.root),
            style=self.style,
            key_bindings=self.key_bindings,
            refresh_interval=0.3,
            color_depth=self.color_depth,
            output=self.output,
            input=self.input,
            full_screen=True,
        )

        return self.app
Example #23
0
    def __init__(self, username: str, password: str):
        super().__init__(username, password, handle_data=DataFormat.ANSI)

        self.commands = []

        self.output_buffer = Buffer_()
        self.cursor_pos = 0

        self.chat_buffer = Buffer_()

        self.output = BufferControl(self.output_buffer,
                                    input_processors=[FormatText()],
                                    include_default_input_processors=True)

        self.chat = BufferControl(self.chat_buffer,
                                  input_processors=[FormatText()],
                                  include_default_input_processors=True)

        self.hide_ip = "--hide-ip" in sys.argv

        self.suggest = AutoSuggestFromLogs([
            CommandSuggest(),
        ])

        self.input = TextArea(height=1,
                              prompt=" >> ",
                              multiline=False,
                              wrap_lines=False,
                              accept_handler=self.accept,
                              auto_suggest=self.suggest,
                              dont_extend_width=True)

        self.host_ip = FormattedTextControl(ANSI(""))

        self.chat_float = Float(Frame(Window(self.chat, wrap_lines=True)),
                                right=1,
                                top=0,
                                width=40,
                                height=12,
                                hide_when_covering_content=True)

        self.text = ""
        self.chat_text = ""

        def set_frame_size(fn):
            def inner(*args):
                size = self.app.output.get_size()
                self.chat_float.width = size.columns // 3
                self.chat_float.height = size.rows // 2
                return fn(*args)

            return inner

        self.out_window = Window(self.output, wrap_lines=True)

        kb = KeyBindings()

        @kb.add('c-c')
        @kb.add('c-q')
        def _(_):
            self.app.exit()
            self._loop = False
            self.run_again = False

        @kb.add('c-i', filter=has_focus(self.input))
        def __(_):
            fut = self.suggest.get_suggestion_future(self.input.buffer,
                                                     self.input.document)
            text = self.input.text

            def set_input(fut_2):
                res = fut_2.result()
                if res is not None:
                    self.input.text = text + res.text
                    self.input.document = Document(self.input.text,
                                                   cursor_position=len(
                                                       self.input.text))

            fut.add_done_callback(set_input)

        @kb.add(Keys.ScrollUp)
        def sup(_):
            self.output_buffer.cursor_up(1)
            self.out_window._scroll_up()  # pylint: disable=protected-access

        @kb.add(Keys.ScrollDown)
        def sdown(_):
            self.output_buffer.cursor_down(1)
            self.out_window._scroll_down()  # pylint: disable=protected-access

        self.app = Application(
            layout=Layout(
                container=HSplit([
                    Frame(
                        FloatContainer(self.out_window,
                                       floats=[self.chat_float])),
                    Frame(
                        VSplit([
                            self.input,
                            Window(self.host_ip,
                                   align=WindowAlign.RIGHT,
                                   dont_extend_width=True)
                        ]))
                ]),
                focused_element=self.input,
            ),
            full_screen=True,
            mouse_support=True,
            enable_page_navigation_bindings=True,
            key_bindings=merge_key_bindings([kb]),
            paste_mode=True,
        )

        self.app._on_resize = set_frame_size(self.app._on_resize)  # pylint: disable=protected-access

        self.run_again = True
        self.loop = get_event_loop()
        self._loop = False

        self.own_pass = ""
        self.own_ip = ""
        self.current_ip = ""
    def __configure_layout(self):
        # Configure completers used by the application.
        commands_completer = NestedCommandsFuzzyWordCompleter(
            self.commands, completers=self.completers)

        # Configure PythonRuntimeCompleter
        python_runtime_completer = PythonRuntimeCompleter(self)

        # --------- This is the CLI input container ---------
        # Comfigure the input container and handler.
        self.input_container = TextArea(prompt='{}> '.format(self.app_name),
                                        style='class:input-field',
                                        multiline=False,
                                        wrap_lines=True,
                                        completer=commands_completer,
                                        history=InMemoryHistory())
        self.input_container.accept_handler = lambda command: self.__root_command_handler(
            self.input_container.text)

        # Configure the python buffer to write interactive pytho code.
        self.python_code_buffer = Buffer(completer=python_runtime_completer)

        # --------- This is the Python code container ---------
        self.python_code_container = Window(
            width=130,  # Is there any way to use precentage?
            content=BufferControl(buffer=self.python_code_buffer,
                                  lexer=PythonLexer(self.python_code_buffer)),
            get_line_prefix=self.__get_line_prefix,
            wrap_lines=True)

        # Configure the output buffer to 'print' out results.
        self.output_buffer = Buffer()

        # --------- This is the Output container ---------
        self.output_container = Window(
            content=BufferControl(buffer=self.output_buffer), wrap_lines=True)

        self.session = Session()
        self.session.add_tab(Tab("Console", self.output_container))
        self.session.add_tab(
            Tab("Python Interpreter Environment", self.python_code_container))

        self.tabs_container = TabbedBuffersContainer(self.session)
        self.tabs_container.set_selected_tab(0)

        # Configure the application layout.
        root_container = HSplit([
            VSplit([
                # Window for python code.
                self.tabs_container,
            ]),
            # Seperation line.
            Window(height=1, char='-', style='class:line'),
            # Command line prompt.
            self.input_container,
        ])

        self.floating_container = FloatContainer(
            content=root_container,
            floats=[
                Float(xcursor=True,
                      ycursor=True,
                      content=CompletionsMenu(max_height=16, scroll_offset=1))
            ])

        self.body_layout = Layout(self.floating_container)
Example #25
0
def create_default_layout(app,
                          message='',
                          lexer=None,
                          is_password=False,
                          reserve_space_for_menu=False,
                          get_prompt_tokens=None,
                          get_bottom_toolbar_tokens=None,
                          display_completions_in_columns=False,
                          extra_input_processors=None,
                          multiline=False):
    """
    Generate default layout.

    Returns a ``Layout`` instance.

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

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

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

    get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt(
        get_prompt_tokens)

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

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

    if extra_input_processors:
        input_processors.extend(extra_input_processors)

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

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

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

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

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

        # In multiline mode, we use two toolbars for 'arg' and 'search'.
        ConditionalContainer(ArgToolbar(), multiline),
        ConditionalContainer(SearchToolbar(), multiline),
    ] + toolbars)
Example #26
0
    def create_prompt_layout(self,
                             message='',
                             lexer=None,
                             is_password=False,
                             reserve_space_for_menu=8,
                             get_prompt_tokens=None,
                             get_bottom_toolbar_tokens=None,
                             display_completions_in_columns=False,
                             extra_input_processors=None,
                             multiline=False,
                             wrap_lines=True):
        """Create a Container instance for a prompt.

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

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

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

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

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

        get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt(
            get_prompt_tokens)

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

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

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

        if extra_input_processors:
            input_processors.extend(extra_input_processors)

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

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

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

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

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(ArgToolbar(), multiline),
            ConditionalContainer(SearchToolbar(), multiline),
        ] + toolbars)
Example #27
0
def create_layout(settings, key_bindings_manager,
                  python_prompt_control=None, lexer=PythonLexer, extra_sidebars=None,
                  extra_buffer_processors=None):
    D = LayoutDimension
    extra_sidebars = extra_sidebars or []
    extra_buffer_processors = extra_buffer_processors or []

    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']

            if b.complete_state is None and settings.signatures:
                row, col = settings.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,
                show_line_numbers=ShowLineNumbersFilter(settings, 'default'),
                input_processors=[
                                  # Show matching parentheses, but only while editing.
                                  ConditionalProcessor(
                                      processor=HighlightMatchingBracketProcessor(chars='[](){}'),
                                      filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
                                  HighlightSearchProcessor(preview_search=Always()),
                                  HighlightSelectionProcessor()] + extra_buffer_processors,
                menu_position=menu_position,

                # Make sure that we always see the result of an reverse-i-search:
                preview_search=Always(),
            ),
            # As long as we're editing, prefer a minimal height of 6.
            get_height=(lambda cli: (None if cli.is_done else D(min=6))),
        )

    return HSplit([
        VSplit([
            HSplit([
                FloatContainer(
                    content=HSplit([
                        VSplit([
                            Window(
                                python_prompt_control,
                                dont_extend_width=True,
                            ),
                            create_python_input_window(),
                        ]),
                    ]),
                    floats=[
                        Float(xcursor=True,
                              ycursor=True,
                              content=CompletionsMenu(
                                  max_height=12,
                                  extra_filter=ShowCompletionsMenu(settings))),
                        Float(xcursor=True,
                              ycursor=True,
                              content=SignatureToolbar(settings))
                    ]),
                ArgToolbar(),
                SearchToolbar(),
                SystemToolbar(),
                ValidationToolbar(),
                CompletionsToolbar(extra_filter=ShowCompletionsToolbar(settings)),

                # Docstring region.
                Window(height=D.exact(1),
                       content=FillControl('\u2500', token=Token.Separator),
                       filter=HasSignature(settings) & ShowDocstring(settings) & ~IsDone()),
                Window(
                    BufferControl(
                        buffer_name='docstring',
                        default_token=Token.Docstring,
                        #lexer=PythonLexer,
                    ),
                    filter=HasSignature(settings) & ShowDocstring(settings) & ~IsDone(),
                    height=D(max=12),
                ),
            ]),
            ] + extra_sidebars + [
            PythonSidebar(settings, key_bindings_manager),
        ]),
        VSplit([
            PythonToolbar(key_bindings_manager, settings),
            ShowSidebarButtonInfo(),
        ])
    ])
Example #28
0
    def _create_layout(self,
                       message='',
                       lexer=None,
                       is_password=False,
                       reserve_space_for_menu=8,
                       get_prompt_tokens=None,
                       get_continuation_tokens=None,
                       get_rprompt_tokens=None,
                       get_bottom_toolbar_tokens=None,
                       get_url_tokens=None,
                       display_completions_in_columns=False,
                       extra_input_processors=None,
                       multiline=False,
                       wrap_lines=True):
        """
        Create a :class:`.Container` instance for a prompt.
        :param message: Text to be used as prompt.
        :param lexer: :class:`~prompt_toolkit.layout.lexers.Lexer` to be used for
            the highlighting.
        :param is_password: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True, display input as '*'.
        :param reserve_space_for_menu: Space to be reserved for the menu. When >0,
            make sure that a minimal height is allocated in the terminal, in order
            to display the completion menu.
        :param get_prompt_tokens: An optional callable that returns the tokens to be
            shown in the menu. (To be used instead of a `message`.)
        :param get_continuation_tokens: An optional callable that takes a
            CommandLineInterface and width as input and returns a list of (Token,
            text) tuples to be used for the continuation.
        :param get_bottom_toolbar_tokens: An optional callable that returns the
            tokens for a toolbar at the bottom.
        :param display_completions_in_columns: `bool` or
            :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in
            multiple columns.
        :param multiline: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True, prefer a layout that is more adapted for multiline input.
            Text after newlines is automatically indented, and search/arg input is
            shown below the input, instead of replacing the prompt.
        :param wrap_lines: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`.
            When True (the default), automatically wrap long lines instead of
            scrolling horizontally.
        """
        assert get_bottom_toolbar_tokens is None or callable(
            get_bottom_toolbar_tokens)
        assert get_prompt_tokens is None or callable(get_prompt_tokens)
        assert get_rprompt_tokens is None or callable(get_rprompt_tokens)
        assert not (message and get_prompt_tokens)

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

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

        has_before_tokens, get_prompt_tokens_1, get_prompt_tokens_2 = \
            _split_multiline_prompt(get_prompt_tokens)

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

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

        if extra_input_processors:
            input_processors.extend(extra_input_processors)

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

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

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

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

            return LayoutDimension()

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

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

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(ArgToolbar(), multiline),
            ConditionalContainer(SearchToolbar(), multiline),
        ] + toolbars)
Example #29
0
    def _create_layout(self):
        """
        Create `Layout` for this prompt.
        """
        dyncond = self._dyncond

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

        default_buffer = self.default_buffer
        search_buffer = self.search_buffer

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

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

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

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

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

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

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

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

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

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

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

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

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

        return Layout(layout, default_buffer_window)
Example #30
0
    def __init__(self):
        # styling
        style = Style.from_dict({
            'completion-menu.completion': 'bg:#008888 #ffffff',
            'completion-menu.completion.current': 'bg:#00aaaa #000000',
            'scrollbar.background': 'bg:#88aaaa',
            'scrollbar.button': 'bg:#222222',
            'input-field': '#004400',
            'buffer': '#ff0066',
        })

        # create input fields
        self.source_field = make_text_area('[Source folder]: ')
        self.target_field = make_text_area('[Target folder]: ')
        self.dry_field = make_text_area('[{:13}]: '.format("Dry? (y/n)"))

        # get completers
        initialize_database()
        con = db_connect()

        self.source_field.completer = FuzzyCompleter(
            WordCompleter(get_source_paths(con), ignore_case=True))
        self.target_field.completer = FuzzyCompleter(
            WordCompleter(get_target_paths(con), ignore_case=True))
        self.dry_field.completer = WordCompleter(
            ['Yes', 'No', 'True', 'False', 'yes', 'no'], ignore_case=True)

        # bottom toolbar
        def bottom_toolbar_call():
            s1 = '<b><style bg="ansired">C-H</style></b>: history mode.'
            s2 = '<b><style bg="ansired">C-C/C-Q</style></b>: exit app.'
            s3 = '<b><style bg="ansired">C-O</style></b>: ordered paths.'
            s4 = '<b><style bg="ansired">C-R</style></b>: reverse paths.'
            return HTML(" ".join([s1, s2, s3, s4]))

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

        # create app body
        self.body = FloatContainer(content=HSplit(children=[
            self.source_field, self.target_field, self.dry_field,
            self.bottom_toolbar
        ],
                                                  height=8),
                                   floats=[
                                       Float(xcursor=True,
                                             ycursor=True,
                                             content=CompletionsMenu(
                                                 max_height=12,
                                                 scroll_offset=1))
                                   ])

        # define internal logic
        def execute_command(buff):
            """Send command to subprocess dealing with dry argument recursively"""
            dry = False if buff.text.lower() in ['n', 'no', 'false'] else True
            dry_flag = 'DRY' if dry else 'NOT DRY'
            dry_string = 'n' if dry else ''
            command = "rsync -avucP{} {} {}".format(dry_string,
                                                    self.source_field.text,
                                                    self.target_field.text)

            def run_script():
                subprocess.call(command, shell=True)

            def print_info():
                print_formatted_text(
                    HTML('<ansired>{} </ansired>'.format(dry_flag)))
                print_formatted_text(
                    HTML('<ansired>{} </ansired>'.format(
                        'You entered: {}'.format(command))))
                print_formatted_text(
                    HTML('<ansired>{} </ansired>'.format('Running...')))

            run_in_terminal(print_info)

            if dry:
                run_in_terminal(run_script)
                return
            else:
                con = db_connect()
                create_rsync_record(con, self.source_field.text,
                                    self.target_field.text)
                run_in_terminal(run_script)

                app = get_app()
                app.exit()
                return

        self.dry_field.buffer.accept_handler = execute_command

        # Key bindings
        self.kb = KeyBindings()

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

        #kb.add('enter')(focus_next)
        self.kb.add('tab')(focus_next)
        self.kb.add('s-tab')(focus_previous)

        # The `Application`
        self.app = Application(
            layout=Layout(self.body),
            #style=style,
            key_bindings=self.kb,
            full_screen=False,
            mouse_support=True)