From cbc21827b10996ff34bb634ec07f61fb2a6062e0 Mon Sep 17 00:00:00 2001 From: Leandro Lisboa Penz Date: Sun, 26 Nov 2023 18:34:09 +0000 Subject: [PATCH] Also add searchingmenu widgets --- src/ptvertmenu/__init__.py | 3 ++ src/ptvertmenu/searchingmenu.py | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/ptvertmenu/searchingmenu.py diff --git a/src/ptvertmenu/__init__.py b/src/ptvertmenu/__init__.py index 5963232..108792d 100644 --- a/src/ptvertmenu/__init__.py +++ b/src/ptvertmenu/__init__.py @@ -3,6 +3,7 @@ import importlib.metadata from .filteredmenu import FuzzFilterVertMenu, RegexFilterVertMenu +from .searchingmenu import FuzzSearchVertMenu, RegexSearchVertMenu from .vertmenu import Item, VertMenu @@ -15,5 +16,7 @@ def version() -> str: "VertMenu", "FuzzFilterVertMenu", "RegexFilterVertMenu", + "FuzzSearchVertMenu", + "RegexSearchVertMenu", "Item", ] diff --git a/src/ptvertmenu/searchingmenu.py b/src/ptvertmenu/searchingmenu.py new file mode 100644 index 0000000..91717ee --- /dev/null +++ b/src/ptvertmenu/searchingmenu.py @@ -0,0 +1,73 @@ +"""Menu finder widgets""" + +import re +from typing import Callable, Iterable, Optional + +from prompt_toolkit.buffer import Buffer +from prompt_toolkit.formatted_text import to_plain_text +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.layout.containers import Container, HSplit, VSplit, Window +from prompt_toolkit.layout.controls import BufferControl + +from .vertmenu import Item, VertMenu + +E = KeyPressEvent + + +class SearchingVertMenu: + def __init__( + self, + items: Iterable[Item], + selected_item: Optional[Item] = None, + selected_handler: Optional[Callable[[Optional[Item], int], None]] = None, + accept_handler: Optional[Callable[[Item], None]] = None, + ): + self._all_items = tuple(items) + self._vertmenu = VertMenu( + self._all_items, selected_item, selected_handler, accept_handler + ) + self.buffer = Buffer(multiline=False, on_text_changed=self.apply_search) + self.control = BufferControl( + buffer=self.buffer, key_bindings=self._vertmenu._init_key_bindings() + ) + self.window = HSplit( + [ + VSplit([Window(width=1, char=">", height=1), Window(self.control)]), + self._vertmenu, + ] + ) + + def apply_search(self, buf: Buffer) -> None: + raise NotImplementedError + + def __pt_container__(self) -> Container: + return self.window + + +class RegexSearchVertMenu(SearchingVertMenu): + def apply_search(self, buf: Buffer) -> None: + regex_str = buf.document.text + try: + regex = re.compile(regex_str) + except re.error: + return + item = next( + (item for item in self._all_items if regex.search(to_plain_text(item[0]))) + ) + if item: + self._vertmenu.control.selected_item = item + + +class FuzzSearchVertMenu(SearchingVertMenu): + def apply_search(self, buf: Buffer) -> None: + text = buf.document.text + regex_str = ".*".join(text) + try: + regex = re.compile(regex_str, re.IGNORECASE) + except re.error: + return + item = next( + (item for item in self._all_items if regex.search(to_plain_text(item[0]))) + ) + if item: + self._vertmenu.control.selected_item = item