diff --git a/README.md b/README.md index 4475d21..0612fed 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,10 @@ interactive selection list in the terminal. multiple items by hitting SPACE - `min_selection_count`: (optional) for multi select feature to dictate a minimum of selected items before continuing -- `screen`: (optional), if you are using `pick` within an existing curses application set this to your existing `screen` object. It is assumed this has initialised in the standard way (e.g. via `curses.wrapper()`, or `curses.noecho(); curses.cbreak(); screen.kepad(True)`) +- `screen`: (optional), if you are using `pick` within an existing curses application set this to your existing `screen` object. It is assumed this has initialised in the standard way (e.g. via `curses.wrapper()`, or `curses.noecho(); curses.cbreak(); screen.kepad(True)`) - `position`: (optional), if you are using `pick` within an existing curses application use this to set the first position to write to. e.g., `position=pick.Position(y=1, x=1)` +- `quit_keys`: (optional), if you want to quit early, you can pass a key codes. + If the corresponding key are pressed, it will quit the menu. ## Community Projects diff --git a/example/basic.py b/example/basic.py index e1db466..fad055d 100644 --- a/example/basic.py +++ b/example/basic.py @@ -1,6 +1,12 @@ from pick import pick +KEY_CTRL_C = 3 +KEY_ESCAPE = 27 +QUIT_KEYS = (KEY_CTRL_C, KEY_ESCAPE, ord("q")) + title = "Please choose your favorite programming language: " options = ["Java", "JavaScript", "Python", "PHP", "C++", "Erlang", "Haskell"] -option, index = pick(options, title, indicator="=>", default_index=2) +option, index = pick( + options, title, indicator="=>", default_index=2, quit_keys=QUIT_KEYS +) print(f"You chose {option} at index {index}") diff --git a/src/pick/__init__.py b/src/pick/__init__.py index 0b67f07..294c03a 100644 --- a/src/pick/__init__.py +++ b/src/pick/__init__.py @@ -2,7 +2,7 @@ import textwrap from collections import namedtuple from dataclasses import dataclass, field -from typing import Any, Generic, List, Optional, Sequence, Tuple, TypeVar, Union +from typing import Any, Container, Generic, Iterable, List, Optional, Sequence, Tuple, TypeVar, Union __all__ = ["Picker", "pick", "Option"] @@ -40,6 +40,7 @@ class Picker(Generic[OPTION_T]): screen: Optional["curses._CursesWindow"] = None position: Position = Position(0, 0) clear_screen: bool = True + quit_keys: Optional[Union[Container[int], Iterable[int]]] = None def __post_init__(self) -> None: if len(self.options) == 0: @@ -166,7 +167,12 @@ def run_loop( while True: self.draw(screen) c = screen.getch() - if c in KEYS_UP: + if self.quit_keys is not None and c in self.quit_keys: + if self.multiselect: + return [] + else: + return None, -1 + elif c in KEYS_UP: self.move_up() elif c in KEYS_DOWN: self.move_down() @@ -215,7 +221,8 @@ def pick( min_selection_count: int = 0, screen: Optional["curses._CursesWindow"] = None, position: Position = Position(0, 0), - clear_screen = True, + clear_screen: bool = True, + quit_keys: Optional[Union[Container[int], Iterable[int]]] = None, ): picker: Picker = Picker( options, @@ -227,5 +234,6 @@ def pick( screen, position, clear_screen, + quit_keys, ) return picker.start()