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