Ejemplo n.º 1
0
 def current_search_state(self):
     """
     Return the current :class:`.SearchState`. (The one for the focused
     :class:`.BufferControl`.)
     """
     ui_control = self.layout.current_control
     if isinstance(ui_control, BufferControl):
         return ui_control.search_state
     else:
         return SearchState()  # Dummy search state.  (Don't return None!)
Ejemplo n.º 2
0
    def __init__(self, buffer=None, input_processors=None, lexer=None,
                 focus_on_click=False, key_bindings=None,
                 ignore_case=False):
        super(SearchBufferControl, self).__init__(
                buffer=buffer, input_processors=input_processors, lexer=lexer,
                focus_on_click=focus_on_click, key_bindings=key_bindings)

        # If this BufferControl is used as a search field for one or more other
        # BufferControls, then represents the search state.
        self.searcher_search_state = SearchState(ignore_case=ignore_case)
Ejemplo n.º 3
0
def search_backward(_: KeyPressEvent):
    control = LAYOUT.current_control
    search_control = control.search_buffer_control
    LAYOUT.search_links = {search_control: control}
    search_state = SearchState(direction=SearchDirection.BACKWARD,
                               ignore_case=False)
    search_control.searcher_search_state = search_state
    LAYOUT.focus(search_control)
    app = get_app()
    app.vi_state.reset()
Ejemplo n.º 4
0
 def search_state(self) -> SearchState:
     """
     Return the `SearchState` for searching this `BufferControl`. This is
     always associated with the search control. If one search bar is used
     for searching multiple `BufferControls`, then they share the same
     `SearchState`.
     """
     search_buffer_control = self.search_buffer_control
     if search_buffer_control:
         return search_buffer_control.searcher_search_state
     else:
         return SearchState()
Ejemplo n.º 5
0
    def __init__(
            self,
            buffer: Optional[Buffer] = None,
            input_processors: Optional[List[Processor]] = None,
            lexer: Optional[Lexer] = None,
            focus_on_click: FilterOrBool = False,
            key_bindings: Optional['KeyBindingsBase'] = None,
            ignore_case: FilterOrBool = False):

        super().__init__(
                buffer=buffer, input_processors=input_processors, lexer=lexer,
                focus_on_click=focus_on_click, key_bindings=key_bindings)

        # If this BufferControl is used as a search field for one or more other
        # BufferControls, then represents the search state.
        self.searcher_search_state = SearchState(ignore_case=ignore_case)
Ejemplo n.º 6
0
    def create_content(self,
                       width: int,
                       height: int,
                       preview_search: bool = False) -> UIContent:
        """
        Create a UIContent.
        """
        buffer = self.buffer

        # Trigger history loading of the buffer. We do this during the
        # rendering of the UI here, because it needs to happen when an
        # `Application` with its event loop is running. During the rendering of
        # the buffer control is the earliest place we can achieve this, where
        # we're sure the right event loop is active, and don't require user
        # interaction (like in a key binding).
        buffer.load_history_if_not_yet_loaded()

        # Get the document to be shown. If we are currently searching (the
        # search buffer has focus, and the preview_search filter is enabled),
        # then use the search document, which has possibly a different
        # text/cursor position.)
        search_control = self.search_buffer_control
        preview_now = preview_search or bool(
            # Only if this feature is enabled.
            self.preview_search() and
            # And something was typed in the associated search field.
            search_control and search_control.buffer.text and
            # And we are searching in this control. (Many controls can point to
            # the same search field, like in Pyvim.)
            get_app().layout.search_target_buffer_control == self)

        if preview_now and search_control is not None:
            ss = self.search_state

            document = buffer.document_for_search(
                SearchState(
                    text=search_control.buffer.text,
                    direction=ss.direction,
                    ignore_case=ss.ignore_case,
                ))
        else:
            document = buffer.document

        get_processed_line = self._create_get_processed_line_func(
            document, width, height)
        self._last_get_processed_line = get_processed_line

        def translate_rowcol(row: int, col: int) -> Point:
            " Return the content column for this coordinate. "
            return Point(x=get_processed_line(row).source_to_display(col),
                         y=row)

        def get_line(i: int) -> StyleAndTextTuples:
            " Return the fragments for a given line number. "
            fragments = get_processed_line(i).fragments

            # Add a space at the end, because that is a possible cursor
            # position. (When inserting after the input.) We should do this on
            # all the lines, not just the line containing the cursor. (Because
            # otherwise, line wrapping/scrolling could change when moving the
            # cursor around.)
            fragments = fragments + [("", " ")]
            return fragments

        content = UIContent(
            get_line=get_line,
            line_count=document.line_count,
            cursor_position=translate_rowcol(document.cursor_position_row,
                                             document.cursor_position_col),
        )

        # If there is an auto completion going on, use that start point for a
        # pop-up menu position. (But only when this buffer has the focus --
        # there is only one place for a menu, determined by the focused buffer.)
        if get_app().layout.current_control == self:
            menu_position = self.menu_position(
            ) if self.menu_position else None
            if menu_position is not None:
                assert isinstance(menu_position, int)
                menu_row, menu_col = buffer.document.translate_index_to_position(
                    menu_position)
                content.menu_position = translate_rowcol(menu_row, menu_col)
            elif buffer.complete_state:
                # Position for completion menu.
                # Note: We use 'min', because the original cursor position could be
                #       behind the input string when the actual completion is for
                #       some reason shorter than the text we had before. (A completion
                #       can change and shorten the input.)
                menu_row, menu_col = buffer.document.translate_index_to_position(
                    min(
                        buffer.cursor_position,
                        buffer.complete_state.original_document.
                        cursor_position,
                    ))
                content.menu_position = translate_rowcol(menu_row, menu_col)
            else:
                content.menu_position = None

        return content