Example #1
0
    def __init__(self, values: Sequence[Tuple[_T, AnyFormattedText]]) -> None:
        assert len(values) > 0

        self.values = values
        # current_values will be used in multiple_selection,
        # current_value will be used otherwise.
        self.current_values: List[_T] = []
        self.current_value: _T = values[0][0]
        self._selected_index = 0

        # Key bindings.
        kb = KeyBindings()

        @kb.add("up")
        def _(event: E) -> None:
            self._selected_index = max(0, self._selected_index - 1)

        @kb.add("down")
        def _(event: E) -> None:
            self._selected_index = min(len(self.values) - 1, self._selected_index + 1)

        @kb.add("pageup")
        def _(event: E) -> None:
            w = event.app.layout.current_window
            self._selected_index = max(
                0, self._selected_index - len(w.render_info.displayed_lines)
            )

        @kb.add("pagedown")
        def _(event: E) -> None:
            w = event.app.layout.current_window
            self._selected_index = min(
                len(self.values) - 1,
                self._selected_index + len(w.render_info.displayed_lines),
            )

        @kb.add("enter")
        @kb.add(" ")
        def _(event: E) -> None:
            self._handle_enter()

        @kb.add(Keys.Any)
        def _(event: E) -> None:
            # We first check values after the selected value, then all values.
            for value in self.values[self._selected_index + 1 :] + self.values:
                if value[1].startswith(event.data):
                    self._selected_index = self.values.index(value)
                    return

        # Control and window.
        self.control = FormattedTextControl(
            self._get_text_fragments, key_bindings=kb, focusable=True
        )

        self.window = Window(
            content=self.control,
            style=self.container_style,
            right_margins=[ScrollbarMargin(display_arrows=True),],
            dont_extend_height=True,
        )
Example #2
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 #3
0
    def create(self):
        from freud.key_bindings import response_kb, header_kb

        right_margins = [ScrollbarMargin(display_arrows=True)]
        left_margins = [NumberedMargin()]

        self.buffer_control = BufferControl(
            lexer=PygmentsLexer(JsonLexer),
            search_buffer_control=search_toolbar.control,
            buffer=response_buffer)

        header_window = Window(
            wrap_lines=True,
            right_margins=right_margins,
            left_margins=left_margins,
            height=HEADER_HEIGHT,
            content=BufferControl(key_bindings=header_kb,
                                  search_buffer_control=search_toolbar.control,
                                  lexer=PygmentsLexer(HeaderLexer),
                                  buffer=header_buffer))

        body_window = Window(left_margins=left_margins,
                             right_margins=right_margins,
                             wrap_lines=True,
                             content=self.buffer_control)

        return HSplit([
            header_window,
            Window(height=1, char='─', style='class:line'),
            body_window,
        ],
                      key_bindings=response_kb)
Example #4
0
    def __init__(
            self, options: Sequence[Tuple[RadioListType,
                                          AnyFormattedText]]) -> None:
        self.options = options
        self.current_option: RadioListType = options[0][0]
        self._selected_index = 0

        # Key bindings.
        kb = KeyBindings()

        kb.add("up")(self._handle_up)
        kb.add("down")(self._handle_down)
        kb.add("enter")(self._handle_enter)
        kb.add("c-d")(self._handle_exit)
        kb.add("c-a")(self._handle_home)
        kb.add("c-e")(self._handle_end)

        # Control and window.
        self.control = FormattedTextControl(self._get_text_fragments,
                                            key_bindings=kb,
                                            focusable=True)

        self.window = Window(
            content=self.control,
            style=self.container_style,
            right_margins=[ScrollbarMargin(display_arrows=True)],
            dont_extend_height=True,
        )
Example #5
0
    def __init__(self, fm: Filemanager, handler: Callable[[str], None]):
        self.fm = fm
        self.values: List[str] = ['../']
        self._styles = [FileList.STYLE_DIR]
        self._selected_index: int = 0
        self._file_handler = handler

        for f in fm.cwd.iterdir():
            if f.is_file():
                self.values.append(f.name)
                self._styles.append(FileList.STYLE_FILE)
            elif f.is_dir():
                self.values.append(f.name + '/')
                self._styles.append(FileList.STYLE_DIR)
            # elif f.is_symlink():
            #    self.values.append(f.name + ' -> ' + os.path.realpath(f))
            #    self._styles.append(FileList.STYLE_SYMLINK)
            else:
                self.values.append(f.name + '|')
                self._styles.append(FileList.STYLE_OTHER)

        self.input_field = FormattedTextControl(
            self._get_text_fragments,
            show_cursor=False,
            key_bindings=self._get_filemanager_kb(fm),
            focusable=True)

        self.window = Window(content=self.input_field,
                             cursorline=True,
                             right_margins=[
                                 ScrollbarMargin(display_arrows=True),
                             ],
                             dont_extend_height=True)
Example #6
0
    def __init__(self, values):
        assert isinstance(values, list)
        assert len(values) > 0
        assert all(isinstance(i, tuple) and len(i) == 2 for i in values)

        self.values = values
        self.current_value = values[0][0]
        self._selected_index = 0

        # Key bindings.
        kb = KeyBindings()

        @kb.add('up')
        def _(event):
            self._selected_index = max(0, self._selected_index - 1)

        @kb.add('down')
        def _(event):
            self._selected_index = min(
                len(self.values) - 1, self._selected_index + 1)

        @kb.add('pageup')
        def _(event):
            w = event.app.layout.current_window
            self._selected_index = max(
                0, self._selected_index - len(w.render_info.displayed_lines))

        @kb.add('pagedown')
        def _(event):
            w = event.app.layout.current_window
            self._selected_index = min(
                len(self.values) - 1,
                self._selected_index + len(w.render_info.displayed_lines))

        @kb.add('enter')
        @kb.add(' ')
        def _(event):
            self.current_value = self.values[self._selected_index][0]

        @kb.add(Keys.Any)
        def _(event):
            # We first check values after the selected value, then all values.
            for value in self.values[self._selected_index + 1:] + self.values:
                if value[1].startswith(event.data):
                    self._selected_index = self.values.index(value)
                    return

        # Control and window.
        self.control = FormattedTextControl(self._get_text_fragments,
                                            key_bindings=kb,
                                            focusable=True)

        self.window = Window(content=self.control,
                             style='class:radio-list',
                             right_margins=[
                                 ScrollbarMargin(display_arrows=True),
                             ],
                             dont_extend_height=True)
Example #7
0
def make_exchange_container(e_key):
    exchange = {}
    exchange['name'] = allowed_exchanges[e_key]['name']
    exchange['title'] = FormattedTextControl()
    exchange['title'].text = HTML('awaiting connection')
    exchange['book_buffer'] = FormattedTextControl()
    exchange['trades_buffer'] = Buffer_()
    exchange['summary'] = FormattedTextControl()
    exchange['summary'].text = get_summary_text()

    exchange['container'] = HSplit([
        Window(BufferControl(Buffer_()), height=0),
        Window(
            height=1,
            content=exchange['title'],
            align=WindowAlign.LEFT,
            left_margins=[ScrollbarMargin()],
        ),
        Window(height=1, char="-", style="class:line"),
        VSplit([
            Window(
                height=5,
                width=45,
                content=exchange['summary'],
                align=WindowAlign.LEFT,
                left_margins=[ScrollbarMargin()],
            ),
            Window(width=1, char=".", style="class:mbline"),
            Window(height=1,
                   content=exchange['book_buffer'],
                   align=WindowAlign.LEFT)
        ]),
        Window(height=1, char="-", style="class:line"),
        Window(
            BufferControl(exchange['trades_buffer'],
                          input_processors=[FormatText()],
                          include_default_input_processors=True),
            # right_margins=[ScrollbarMargin(), ScrollbarMargin()],
        ),
    ])
    return exchange
Example #8
0
    def _gen_layout(self):
        stat_windows = []

        for stat_group in statinfo.groups:
            for stat in stat_group:
                stat_windows.append(make_stat_window(stat))

            stat_windows.append(vpad(1))

        stat_windows.append(
            Window(content=BufferControl(buffer_name='REROLLS_STAT_BUFFER'),
                   **stat_args))
        stat_windows.append(vpad(1))

        @Condition
        def scroll_cond(cli):
            if self.info_window.render_info is None:
                return True

            try:
                l = self.buffers['INFO_BUFFER'].document.line_count
                return self.info_window.render_info.window_height < l
            except:
                return True

        self.info_window = Window(
            content=BufferControl(buffer_name='INFO_BUFFER'),
            dont_extend_width=True,
            wrap_lines=True,
            always_hide_cursor=True,
            right_margins=[
                ConditionalMargin(ScrollbarMargin(display_arrows=True),
                                  scroll_cond)
            ])

        return HSplit([
            hpad(1),
            VSplit([
                vpad(1),
                HSplit(stat_windows),
                vpad(2),  # idk why there's an extra space on the stats
                self.info_window,
                vpad(1)
            ]),
            hpad(1),
            Window(content=BufferControl(buffer_name='MSG_BUFFER'),
                   height=D.exact(3),
                   wrap_lines=True),
            Window(content=BufferControl(buffer_name=DEFAULT_BUFFER),
                   height=D.exact(1),
                   always_hide_cursor=True)
        ])
Example #9
0
 def __init__(self):
     self.selected_line = 0
     self.container = Window(
         content=FormattedTextControl(
             text=self._get_formatted_text,
             focusable=True,
             key_bindings=self._get_key_bindings(),
         ),
         style="class:select-box",
         cursorline=True,
         right_margins=[
             ScrollbarMargin(display_arrows=True),
         ],
         width=20,
         always_hide_cursor=True,
     )
Example #10
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 #11
0
    def __init__(self, buffer, title):
        self._title = title
        self._buffer = buffer

        self.buffer_control = BufferControl(
            buffer=self._buffer,
            lexer=PygmentsLexer(MarkdownLexer),
        )

        self.window = Frame(
            body=Window(
                content=self.buffer_control,
                right_margins=[ScrollbarMargin(display_arrows=True)],
                scroll_offsets=ScrollOffsets(top=2, bottom=2),
            ),
            title=self._title,
        )
Example #12
0
 def setup_layout(self):
     """docstring for setup_layout"""
     if bool(egc.TEXT_EDITOR_ENABLE_LEFT_MARGIN) is True:
         self._left_margin = NumberredMargin(display_tildes=True)
     if bool(egc.TEXT_EDITOR_ENABLE_RIGHT_MARGIN) is True:
         self._right_margin = ScrollbarMargin(display_arrows=True)
     self._buffer_control = BufferControl(buffer_name=self._editor_buffer_name)
     self._editor_aiml_code_window = Window(content=self._buffer_control, left_margins=[self._left_margin,])
     self._vertical_line = FillControl('|', token=Token.Line)
     self._window_separater = Window(width=D.exact(1), content=self._vertical_line)
     self._aiml_list = TokenListControl(get_tokens=self.get_aiml_list)
     self._editor_aiml_list_window = Window(content=self._aiml_list, right_margins=[self._right_margin,])
     self._layout = VSplit([
         self._editor_aiml_code_window,
         self._window_separater,
         self._editor_aiml_list_window,
         ])
Example #13
0
    def __init__(self, buffer):

        self.buffer_control = BufferControl(
            buffer=buffer,
            focusable=True,
            key_bindings=self._get_key_bindings(),
            focus_on_click=True,
        )

        self.window = Window(
            content=self.buffer_control,
            right_margins=[ScrollbarMargin(display_arrows=True)],
        )
        self.window = Frame(body=Box(
            self.window,
            padding_left=2,
            padding_right=2,
            padding_top=0,
            padding_bottom=0,
        ))
Example #14
0
 def __init__(self,
              title: AnyFormattedText = "",
              style: str = "",
              width: AnyDimension = None,
              height: AnyDimension = None,
              key_bindings: Optional[KeyBindings] = None,
              modal: bool = False):
     buffer = Buffer(read_only=True, name='diff')
     self._search = SearchToolbar(vi_mode=True)
     self.control = DiffControl(buffer, self._search.control)
     body = HSplit([
         Window(self.control,
                right_margins=[ScrollbarMargin(display_arrows=True)]),
         self._search
     ])
     super().__init__(body=body,
                      title=title,
                      style=style,
                      width=width,
                      height=height,
                      key_bindings=key_bindings,
                      modal=modal)
Example #15
0
    def __init__(self, values):
        assert isinstance(values, list)
        assert len(values) > 0
        assert all(isinstance(i, tuple) and len(i) == 2 for i in values)

        self.values = values
        self.current_value = values[0][0]
        self._selected_index = 0

        # Key bindings.
        kb = KeyBindings()

        @kb.add('up')
        def _(event):
            self._selected_index = max(0, self._selected_index - 1)

        @kb.add('down')
        def _(event):
            self._selected_index = min(
                len(self.values) - 1, self._selected_index + 1)

        @kb.add('enter')
        @kb.add(' ')
        def _(event):
            self.current_value = self.values[self._selected_index][0]

        # Control and window.
        self.control = FormattedTextControl(self._get_text_fragments,
                                            key_bindings=kb,
                                            focusable=True)

        self.window = Window(content=self.control,
                             style='class:radio-list',
                             right_margins=[
                                 ScrollbarMargin(display_arrows=True),
                             ],
                             dont_extend_height=True)
def create_layout(python_input, history_mapping):
    """
    Create and return a `Container` instance for the history
    application.
    """
    processors = [
        HighlightSearchProcessor(preview_search=True),
        HighlightSelectionProcessor()
    ]

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

    return HSplit([
        #  Top title bar.
        TokenListToolbar(get_tokens=_get_top_toolbar_tokens,
                         align_center=True,
                         default_char=Char(' ', Token.Toolbar.Status)),
        FloatContainer(
            content=VSplit([
                # Left side: history.
                Window(content=BufferControl(buffer_name=HISTORY_BUFFER,
                                             lexer=PygmentsLexer(PythonLexer),
                                             input_processors=processors),
                       wrap_lines=False,
                       left_margins=[HistoryMargin(history_mapping)],
                       scroll_offsets=ScrollOffsets(top=2, bottom=2)),
                # Separator.
                Window(width=D.exact(1),
                       content=FillControl(BORDER.LIGHT_VERTICAL,
                                           token=Token.Separator)),
                # Right side: result.
                Window(
                    content=BufferControl(buffer_name=DEFAULT_BUFFER,
                                          input_processors=processors +
                                          [GrayExistingText(history_mapping)],
                                          lexer=PygmentsLexer(PythonLexer)),
                    wrap_lines=False,
                    left_margins=[ResultMargin(history_mapping)],
                    scroll_offsets=ScrollOffsets(top=2, bottom=2)),
            ]),
            floats=[
                # Help text as a float.
                Float(
                    width=60,
                    top=3,
                    bottom=2,
                    content=ConditionalContainer(
                        # (We use InFocusStack, because it's possible to search
                        # through the help text as well, and at that point the search
                        # buffer has the focus.)
                        content=help_window,
                        filter=InFocusStack(HELP_BUFFER))),
            ]),
        # Bottom toolbars.
        ArgToolbar(),
        SearchToolbar(),
        TokenListToolbar(get_tokens=partial(_get_bottom_toolbar_tokens,
                                            python_input=python_input),
                         default_char=Char(' ', Token.Toolbar.Status)),
    ])
Example #17
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)
Example #18
0
    def __init__(self):
        self.command_parser = BrewPiCommandParser(self)

        self.buffers = {
            DEFAULT_BUFFER:
            Buffer(completer=command_completer,
                   enable_history_search=True,
                   history=InMemoryHistory(),
                   accept_action=AcceptAction(self.command_parser.parse)),
            'MESSAGES':
            Buffer(),
            'RESULT':
            Buffer(),
            'STATE':
            Buffer(),
        }

        self.registry = load_key_bindings()
        self.registry.add_binding(Keys.ControlC,
                                  eager=True)(self._on_request_shutdown)
        self.registry.add_binding(Keys.ControlQ,
                                  eager=True)(self._on_request_shutdown)

        self.layout = HSplit([
            # One window that holds the BufferControl with the default buffer on the
            # left.
            VSplit([
                HSplit([
                    Window(content=TokenListControl(get_tokens=lambda cli: [(
                        Token.Title, 'Command Result')]),
                           height=D.exact(1)),
                    Window(content=BufferControl(buffer_name='RESULT'),
                           wrap_lines=True,
                           left_margins=[ScrollbarMargin()]),
                ]),
                Window(width=D.exact(1),
                       content=FillControl('|', token=Token.Line)),
                HSplit([
                    Window(content=TokenListControl(get_tokens=lambda cli: [(
                        Token.Title, 'Raw Protocol Messages')]),
                           height=D.exact(1)),
                    Window(
                        content=BufferControl(buffer_name='MESSAGES',
                                              lexer=PygmentsLexer(JsonLexer)),
                        wrap_lines=True,
                        left_margins=[NumberredMargin()],
                        right_margins=[ScrollbarMargin()])
                ])
            ]),
            VSplit([
                Window(content=TokenListControl(
                    get_tokens=self.get_prompt_tokens),
                       height=D.exact(1),
                       dont_extend_width=True),
                Window(content=BufferControl(buffer_name=DEFAULT_BUFFER),
                       height=D.exact(1),
                       dont_extend_height=True),
            ]),
            Window(content=BufferControl(buffer_name='STATE'),
                   height=D.exact(1),
                   dont_extend_height=True)
        ])

        super().__init__(
            layout=self.layout,
            buffers=self.buffers,
            key_bindings_registry=self.registry,
            mouse_support=True,
            style=style_from_pygments(
                get_style_by_name('emacs'),
                style_dict={
                    Token.Toolbar:
                    '#ffffff bg:#333333',
                    Token.Title:
                    '#ffffff bg:#000088',
                    # User input.
                    Token:
                    '#ff0066',

                    # Prompt.
                    Token.Name:
                    '#884444 italic',
                    Token.At:
                    '#00aa00',
                    Token.Colon:
                    '#00aa00',
                    Token.Pound:
                    '#00aa00',
                    Token.Host:
                    '#000088 bg:#aaaaff',
                    Token.Path:
                    '#884444 underline',
                    # Make a selection reverse/underlined.
                    # (Use Control-Space to select.)
                    Token.SelectedText:
                    'reverse underline',
                }),
            use_alternate_screen=True)

        # BrewPi Stuff
        self.controller_manager = BrewPiControllerManager()
        self.msg_decoder = RawMessageDecoder()

        self.controller = None
Example #19
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)
Example #20
0
    def __init__(self, debugger):
        self._filename = None
        self.sources = {}
        self.debugger = debugger
        self.debugger.events.on_stop += self.on_stop
        self.current_address_margin = CurrentAddressMargin()
        kb = KeyBindings()
        self.locals_processor = DisplayVariablesProcessor()

        self.source_buffer = Buffer(multiline=True)
        self.bar_buffer = Buffer(multiline=True)
        self.register_buffer = Buffer(multiline=True)
        self.logs_buffer = Buffer(multiline=True)

        @kb.add(Keys.F10, eager=True)
        def quit_(event):
            event.app.exit()

        @kb.add(Keys.F8)
        def clear_breakpoint_(event):
            if self.has_source():
                filename, row = self.get_current_location()
                self.debugger.clear_breakpoint(filename, row)

        @kb.add(Keys.F7)
        def set_breakpoint_(event):
            if self.has_source():
                filename, row = self.get_current_location()
                self.debugger.set_breakpoint(filename, row)

        @kb.add(Keys.F6)
        def step_(event):
            self.debugger.step()

        @kb.add(Keys.F5)
        def run_(event):
            self.debugger.run()

        @kb.add(Keys.F4)
        def stop_(event):
            self.debugger.stop()

        @kb.add(Keys.PageUp)
        def scroll_up_(event):
            self.source_buffer.cursor_up(count=15)

        @kb.add(Keys.PageDown)
        def scroll_down_(event):
            self.source_buffer.cursor_down(count=15)

        src_lexer = PygmentsLexer(CLexer)

        source_code_window = Window(
            content=BufferControl(
                buffer=self.source_buffer,
                lexer=src_lexer,
                input_processors=[self.locals_processor],
            ),
            left_margins=[self.current_address_margin,
                          NumberedMargin()],
            right_margins=[ScrollbarMargin(display_arrows=True)],
            cursorline=True,
        )

        register_window = Window(
            content=BufferControl(buffer=self.register_buffer), width=20)

        title_text = "Welcome to the ppci debugger version {} running in prompt_toolkit {}".format(
            ppci_version, ptk_version)

        help_text = ("F4=stop F5=run F6=step F7=set breakpoint" +
                     " F8=clear breakpoint F10=exit")

        # Application layout:
        body = HSplit([
            Window(content=FormattedTextControl(text=title_text), height=1),
            VSplit([
                HSplit([
                    Frame(
                        body=source_code_window,
                        title="source-code",
                    ),
                    Window(
                        content=BufferControl(buffer=self.logs_buffer),
                        height=2,
                    ),
                ]),
                Frame(body=register_window, title="registers"),
            ]),
            Window(
                content=FormattedTextControl(self.get_status_tokens),
                height=1,
            ),
            Window(content=FormattedTextControl(help_text), height=1),
        ])
        layout = Layout(body)

        style = style_from_pygments_cls(get_style_by_name("vim"))

        log_handler = MyHandler(self.logs_buffer)
        fmt = logging.Formatter(fmt=logformat)
        log_handler.setFormatter(fmt)
        log_handler.setLevel(logging.DEBUG)
        logging.getLogger().setLevel(logging.DEBUG)
        logging.getLogger().addHandler(log_handler)

        self._event_loop = get_event_loop()

        self.application = Application(layout=layout,
                                       style=style,
                                       key_bindings=kb,
                                       full_screen=True)
Example #21
0

WINDOW_VISIBILITY = {
    'history': True,
    'diff': False,
}


@Condition
def diff_visible() -> bool:
    global WINDOW_VISIBILITY
    return WINDOW_VISIBILITY['diff']


MARGINS = [
    ScrollbarMargin(display_arrows=True),
    ConditionalMargin(MyMargin(), filter=diff_visible)
]
DIFF_CONTAINER = ConditionalContainer(DiffView(key_bindings=KD),
                                      filter=diff_visible)

HISTORY_CONTAINER = HistoryContainer(KB, ARGUMENTS, right_margins=MARGINS)


def get_container():
    width = screen_width()
    if width >= 160:
        return VSplit([HISTORY_CONTAINER, DIFF_CONTAINER])
    return HSplit([HISTORY_CONTAINER, DIFF_CONTAINER])

Example #22
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()])
Example #23
0
    def __init__(self, config, out_queue, state=TaskState()):
        self.config = config
        tui_config = config['tui']
        self.tui_config = tui_config
        self.out_queue = out_queue

        def commandHandler(buffer):
            #check incoming command
            cmdString = buffer.text
            #executeCommand(cmdString)
            pass

        def commandPrompt(line_number, wrap_count):
            return "command> "

        ########################################################################

        kb = KeyBindings()

        @kb.add('c-d')
        def exit_(event):
            """
            Pressing Esc will exit the user interface.

            Setting a return value means: quit the event loop that drives the user
            interface and return this value from the `CommandLineInterface.run()` call.
            """
            event.app.exit()

        @kb.add('tab')
        def tab_(event):
            focus_next(event)

        @kb.add('s-tab')
        def stab_(event):
            focus_previous(event)

        @kb.add('s-right')
        def next_tab(event):
            state.next_tab()
            event.app.invalidate()

        @kb.add('s-left')
        def next_tab(event):
            state.prev_tab()
            event.app.invalidate()

        orders_kb = KeyBindings()

        @orders_kb.add('f5')
        def _(event):
            #command = ('refresh', something...)
            #self.out_queue.put_nowait(command)
            pass

        ########################################################################

        outputArea = TextArea(
            text="",
            multiline=True,
            wrap_lines=False,
            #lexer=lexer.OutputAreaLexer(),
            #scrollbar=enableScrollbar,
            style='class:output-field',
            read_only=True)

        content_container = Frame(outputArea, title="Output")

        log_container = Frame(
            Window(
                BufferControl(
                    buffer=Buffer(name='logger_buffer', read_only=True),
                    input_processors=[FormatTextHTML()],
                ),
                right_margins=[ScrollbarMargin(display_arrows=True)
                               ],  # low-level scrollbar
            ),
            title='Log',
            height=8,
        )

        command_container = TextArea(text="",
                                     multiline=False,
                                     accept_handler=commandHandler,
                                     get_line_prefix=commandPrompt)

        commandWindowFrame = Frame(
            command_container,
            title=
            "TuiTerminal (Ctrl-D to exit, Tab to switch focus and refresh UI, 'help' for help)",
            height=4)

        root_container = HSplit(
            [content_container, log_container, commandWindowFrame])

        layout = Layout(root_container, focused_element=command_container)

        style = Style.from_dict({
            'output-field': 'bg:#101010',
            'frame.border': 'SteelBlue',
            'frame.label': 'PowderBlue',
        })

        application = Application(
            layout=layout,
            key_bindings=kb,
            style=style,
            full_screen=tui_config.getboolean('full_screen'),
            mouse_support=tui_config.getboolean('mouse_support'),
            #after_render=after_render,
        )

        self.application = application
Example #24
0
    def __init__(self) -> None:

        self._selected_index = 0

        # Key bindings.
        kb = KeyBindings()

        @kb.add("up")
        def _up(event: E) -> None:
            self._selected_index = max(0, self._selected_index - 1)

        @kb.add("down")
        def _down(event: E) -> None:
            self._selected_index = min(
                len(self.values) - 1, self._selected_index + 1)

        @kb.add("pageup")
        def _pageup(event: E) -> None:
            w = event.app.layout.current_window
            if w.render_info:
                self._selected_index = max(
                    0,
                    self._selected_index - len(w.render_info.displayed_lines))

        @kb.add("pagedown")
        def _pagedown(event: E) -> None:
            w = event.app.layout.current_window
            if w.render_info:
                self._selected_index = min(
                    len(self.values) - 1,
                    self._selected_index + len(w.render_info.displayed_lines),
                )

        @kb.add("enter")
        @kb.add(" ")
        def _click(event: E) -> None:
            self._handle_enter()

        @kb.add(Keys.Any)
        def _find(event: E) -> None:
            # We first check values after the selected value, then all values.
            values = list(self.values)
            for value in values[self._selected_index + 1:] + values:
                text = fragment_list_to_text(to_formatted_text(
                    value[1])).lower()

                if text.startswith(event.data.lower()):
                    self._selected_index = self.values.index(value)
                    return

        # Control and window.
        self.control = FormattedTextControl(self._get_text_fragments,
                                            key_bindings=kb,
                                            focusable=True)

        self.window = Window(
            content=self.control,
            style=self.container_style,
            right_margins=[
                ConditionalMargin(
                    margin=ScrollbarMargin(display_arrows=True),
                    filter=Condition(lambda: self.show_scrollbar),
                ),
            ],
            dont_extend_height=True,
        )
Example #25
0
# Create text buffers. The margins will update if you scroll up or down.

buff = Buffer()
buff.text = LIPSUM

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

        # Add margins.
        left_margins=[NumberedMargin(), ScrollbarMargin()],
        right_margins=[ScrollbarMargin(), ScrollbarMargin()],
    ),
])

# 2. Key bindings
kb = KeyBindings()


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

Example #26
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()
    ])
Example #27
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)
Example #28
0
    def __init__(self, values: Sequence[Tuple[_T, AnyFormattedText]], current_values: Optional[_T] = undefined,
                 current_value: Optional[_T] = undefined) -> None:
        self.values = values
        # current_values will be used in multiple_selection,
        # current_value will be used otherwise.
        self.current_values: List[_T] = []
        self.current_value: _T = undefined
        self._selected_index = 0

        if current_values != undefined:
            indexes = [i for i, (v, _) in enumerate(values) if v in current_values]
            if indexes:
                self._selected_index = indexes[0]
                self.current_values = [values[i][0] for i in indexes]

        if current_value != undefined:
            self._selected_index = [i for i, (v, _) in enumerate(values) if v == current_value][0]
            self.current_value = values[self._selected_index][0]

        # Key bindings.
        kb = KeyBindings()

        @kb.add("up")
        def _up(event: E) -> None:
            if self._selected_index == 0:
                focus_previous(event)
                return

            self._selected_index = max(0, self._selected_index - 1)

        @kb.add("down")
        def _down(event: E) -> None:
            if self._selected_index == len(self.values) - 1:
                focus_next(event)
                return

            self._selected_index = min(len(self.values) - 1, self._selected_index + 1)

        @kb.add("pageup")
        def _pageup(event: E) -> None:
            w = event.app.layout.current_window
            if w.render_info:
                self._selected_index = max(
                    0, self._selected_index - len(w.render_info.displayed_lines)
                )

        @kb.add("pagedown")
        def _pagedown(event: E) -> None:
            w = event.app.layout.current_window
            if w.render_info:
                self._selected_index = min(
                    len(self.values) - 1,
                    self._selected_index + len(w.render_info.displayed_lines),
                )

        @kb.add("enter")
        @kb.add(" ")
        def _click(event: E) -> None:
            self._handle_enter()

            if not self.multiple_selection:
                get_app().exit(result=self.current_value)

        @kb.add(Keys.Any)
        def _find(event: E) -> None:
            # We first check values after the selected value, then all values.
            values = list(self.values)
            for value in values[self._selected_index + 1 :] + values:
                text = fragment_list_to_text(to_formatted_text(value[1])).lower()

                if text.startswith(event.data.lower()):
                    self._selected_index = self.values.index(value)
                    return

        # Control and window.
        self.control = FormattedTextControl(
            self._get_text_fragments, key_bindings=kb, focusable=True
        )

        self.window = Window(
            content=self.control,
            style=self.container_style,
            right_margins=[
                ConditionalMargin(
                    margin=ScrollbarMargin(display_arrows=True),
                    filter=Condition(lambda: self.show_scrollbar),
                ),
            ],
            dont_extend_height=True,
        )
Example #29
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, max_line_count=1000, initial_text="", align=WindowAlign.LEFT):
        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

        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.max_line_count = max_line_count

        self.buffer = CustomBuffer(
            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:
            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,
            align=align)

        self.log_lines: Deque[str] = deque()
        self.log(initial_text)
Example #30
0
    def __init__(self):
        pdb.Pdb.__init__(self)

        # Cache for the grammar.
        self._grammar_cache = None  # (current_pdb_commands, grammar) tuple.

        self.completer = None
        self.validator = None
        self.lexer = None

        self._source_code_window = Window(BufferControl(
            buffer_name='source_code',
            lexer=PygmentsLexer(PythonLexer),
            input_processors=[
                HighlightSearchProcessor(preview_search=True),
                HighlightSelectionProcessor(),
            ],
        ),
                                          left_margins=[
                                              SourceCodeMargin(self),
                                              NumberredMargin(),
                                          ],
                                          right_margins=[ScrollbarMargin()],
                                          scroll_offsets=ScrollOffsets(
                                              top=2, bottom=2),
                                          height=LayoutDimension(preferred=10))

        # Callstack window.
        callstack = CallStack(weakref.ref(self))
        self.callstack_focussed = False  # When True, show cursor there, and allow navigation through it.
        self.callstack_selected_frame = 0  # Top frame.

        show_pdb_content_filter = ~IsDone() & Condition(
            lambda cli: not self.python_input.show_exit_confirmation)

        self.python_input = PythonInput(
            get_locals=lambda: self.curframe.f_locals,
            get_globals=lambda: self.curframe.f_globals,
            _completer=DynamicCompleter(lambda: self.completer),
            _validator=DynamicValidator(lambda: self.validator),
            _accept_action=self._create_accept_action(),
            _extra_buffers={'source_code': Buffer(read_only=True)},
            _input_buffer_height=LayoutDimension(min=2, max=4),
            _lexer=PdbLexer(),
            _extra_buffer_processors=[
                ConditionalProcessor(processor=CompletionHint(),
                                     filter=~IsDone())
            ],
            _extra_layout_body=ConditionalContainer(
                HSplit([
                    VSplit([
                        HSplit([
                            SourceTitlebar(weakref.ref(self)),
                            FloatContainer(
                                content=self._source_code_window,
                                floats=[
                                    Float(right=0,
                                          bottom=0,
                                          content=BreakPointInfoToolbar(
                                              weakref.ref(self)))
                                ]),
                        ]),
                        HSplit([
                            Window(width=LayoutDimension.exact(1),
                                   height=LayoutDimension.exact(1),
                                   content=FillControl(
                                       '\u252c', token=Token.Toolbar.Title)),
                            Window(width=LayoutDimension.exact(1),
                                   content=FillControl('\u2502',
                                                       token=Token.Separator)),
                        ]),
                        HSplit([
                            StackTitlebar(weakref.ref(self)),
                            Window(callstack,
                                   scroll_offsets=ScrollOffsets(top=2,
                                                                bottom=2),
                                   right_margins=[ScrollbarMargin()],
                                   height=LayoutDimension(preferred=10)),
                        ]),
                    ]),
                ]),
                filter=show_pdb_content_filter),
            _extra_toolbars=[
                ConditionalContainer(PdbShortcutsToolbar(weakref.ref(self)),
                                     show_pdb_content_filter)
            ],
            history_filename=os.path.expanduser('~/.ptpdb_history'),
        )

        # Override prompt style.
        self.python_input.all_prompt_styles['pdb'] = PdbPromptStyle(
            self._get_current_pdb_commands())
        self.python_input.prompt_style = 'pdb'

        # Override exit message.
        self.python_input.exit_message = 'Do you want to quit BDB? This raises BdbQuit.'

        # Set UI styles.
        self.python_input.ui_styles = {
            'ptpdb': get_ui_style(),
        }
        self.python_input.use_ui_colorscheme('ptpdb')

        # Set autocompletion style. (Multi-column works nicer.)
        self.python_input.completion_visualisation = CompletionVisualisation.MULTI_COLUMN

        # Load additional key bindings.
        load_custom_pdb_key_bindings(self,
                                     self.python_input.key_bindings_registry)

        self.cli = CommandLineInterface(
            eventloop=create_eventloop(),
            application=self.python_input.create_application())