Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added ability to quit early #126

Merged
merged 10 commits into from
Jun 27, 2024
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 7 additions & 1 deletion example/basic.py
Original file line number Diff line number Diff line change
@@ -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}")
14 changes: 11 additions & 3 deletions src/pick/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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,
Expand All @@ -227,5 +234,6 @@ def pick(
screen,
position,
clear_screen,
quit_keys,
)
return picker.start()