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