""" Search related key bindings. """ from __future__ import annotations from prompt_toolkit import search from prompt_toolkit.application.current import get_app from prompt_toolkit.filters import Condition, control_is_searchable, is_searching from prompt_toolkit.key_binding.key_processor import KeyPressEvent from ..key_bindings import key_binding __all__ = [ "abort_search", "accept_search", "start_reverse_incremental_search", "start_forward_incremental_search", "reverse_incremental_search", "forward_incremental_search", "accept_search_and_accept_input", ] E = KeyPressEvent @key_binding(filter=is_searching) def abort_search(event: E) -> None: """ Abort an incremental search and restore the original line. (Usually bound to ControlG/ControlC.) """ search.stop_search() @key_binding(filter=is_searching) def accept_search(event: E) -> None: """ When enter pressed in isearch, quit isearch mode. (Multiline isearch would be too complicated.) (Usually bound to Enter.) """ search.accept_search() @key_binding(filter=control_is_searchable) def start_reverse_incremental_search(event: E) -> None: """ Enter reverse incremental search. (Usually ControlR.) """ search.start_search(direction=search.SearchDirection.BACKWARD) @key_binding(filter=control_is_searchable) def start_forward_incremental_search(event: E) -> None: """ Enter forward incremental search. (Usually ControlS.) """ search.start_search(direction=search.SearchDirection.FORWARD) @key_binding(filter=is_searching) def reverse_incremental_search(event: E) -> None: """ Apply reverse incremental search, but keep search buffer focused. """ search.do_incremental_search(search.SearchDirection.BACKWARD, count=event.arg) @key_binding(filter=is_searching) def forward_incremental_search(event: E) -> None: """ Apply forward incremental search, but keep search buffer focused. """ search.do_incremental_search(search.SearchDirection.FORWARD, count=event.arg) @Condition def _previous_buffer_is_returnable() -> bool: """ True if the previously focused buffer has a return handler. """ prev_control = get_app().layout.search_target_buffer_control return bool(prev_control and prev_control.buffer.is_returnable) @key_binding(filter=is_searching & _previous_buffer_is_returnable) def accept_search_and_accept_input(event: E) -> None: """ Accept the search operation first, then accept the input. """ search.accept_search() event.current_buffer.validate_and_handle()