search.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. """
  2. Search related key bindings.
  3. """
  4. from __future__ import annotations
  5. from prompt_toolkit import search
  6. from prompt_toolkit.application.current import get_app
  7. from prompt_toolkit.filters import Condition, control_is_searchable, is_searching
  8. from prompt_toolkit.key_binding.key_processor import KeyPressEvent
  9. from ..key_bindings import key_binding
  10. __all__ = [
  11. "abort_search",
  12. "accept_search",
  13. "start_reverse_incremental_search",
  14. "start_forward_incremental_search",
  15. "reverse_incremental_search",
  16. "forward_incremental_search",
  17. "accept_search_and_accept_input",
  18. ]
  19. E = KeyPressEvent
  20. @key_binding(filter=is_searching)
  21. def abort_search(event: E) -> None:
  22. """
  23. Abort an incremental search and restore the original
  24. line.
  25. (Usually bound to ControlG/ControlC.)
  26. """
  27. search.stop_search()
  28. @key_binding(filter=is_searching)
  29. def accept_search(event: E) -> None:
  30. """
  31. When enter pressed in isearch, quit isearch mode. (Multiline
  32. isearch would be too complicated.)
  33. (Usually bound to Enter.)
  34. """
  35. search.accept_search()
  36. @key_binding(filter=control_is_searchable)
  37. def start_reverse_incremental_search(event: E) -> None:
  38. """
  39. Enter reverse incremental search.
  40. (Usually ControlR.)
  41. """
  42. search.start_search(direction=search.SearchDirection.BACKWARD)
  43. @key_binding(filter=control_is_searchable)
  44. def start_forward_incremental_search(event: E) -> None:
  45. """
  46. Enter forward incremental search.
  47. (Usually ControlS.)
  48. """
  49. search.start_search(direction=search.SearchDirection.FORWARD)
  50. @key_binding(filter=is_searching)
  51. def reverse_incremental_search(event: E) -> None:
  52. """
  53. Apply reverse incremental search, but keep search buffer focused.
  54. """
  55. search.do_incremental_search(search.SearchDirection.BACKWARD, count=event.arg)
  56. @key_binding(filter=is_searching)
  57. def forward_incremental_search(event: E) -> None:
  58. """
  59. Apply forward incremental search, but keep search buffer focused.
  60. """
  61. search.do_incremental_search(search.SearchDirection.FORWARD, count=event.arg)
  62. @Condition
  63. def _previous_buffer_is_returnable() -> bool:
  64. """
  65. True if the previously focused buffer has a return handler.
  66. """
  67. prev_control = get_app().layout.search_target_buffer_control
  68. return bool(prev_control and prev_control.buffer.is_returnable)
  69. @key_binding(filter=is_searching & _previous_buffer_is_returnable)
  70. def accept_search_and_accept_input(event: E) -> None:
  71. """
  72. Accept the search operation first, then accept the input.
  73. """
  74. search.accept_search()
  75. event.current_buffer.validate_and_handle()