Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 107 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,57 @@ interactive selection list in the terminal.

## Options

### `Option`

Provides a an alternative to a simple string value to select from.

- `label`: The string of the option that is displayed in the menu
- `value`: Optional different value to assign to the option to leverage
once selected.
- `description`: Optional text that is rendered alongside the label in the
menu.
- `enabled`: Whether the option is selectable. By default, is `True`.
- `color`: The color the option is printed with to the menu. By default
is colorless. Accepts a string like ANSI code. e.g. to make it bold red:
`color='\x1b[1;31m'`; can also use codes from blessed like
`color=Terminal().green`)

Is leveraged by passing in to `pick()`:

```python
pick(
options=[
Option(
"Option 1",
"option_1_value",
"This is option 1 and is not selectable",
enabled=False,
),
"option 2",
"option 3",
Option(
"Option 4",
"option 4",
"This is option 4 and selectable and green",
enabled=True,
color=blessed.Terminal().green,
),
"option 5",
Option(
"Option 6",
"option 6",
"this is option 6 and colored but unselectable",
enabled=False,
color=blessed.Terminal().pink,
),
"option 5",
],
...
)
```

### `pick`

- `options`: a list of options to choose from
- `title`: (optional) a title above options list
- `indicator`: (optional) custom the selection indicator, defaults to `*`
Expand All @@ -56,10 +107,62 @@ 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)`)
- `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.
- `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; default `ESC` key), if you want to quit
early, you can pass a key codes. If the corresponding key are pressed,
it will quit the menu.
- `up_keys`: (optional; default: up arrow), keys to move the menu
selection up
- `down_keys`: (optional; default: down arrow or tab), keys to move
the menu selection down
- `select_keys`: (optional; default: space key), When in multiselect mode,
keys to add/remove the current selection to/from the list of selected
items
- `enter_keys`: (optional; default: enter key), Key to confirm choices
and close menu
- `disabled_color`: (optional) if you want to change the color that
disabled options are; by default, is grey. Accepts a string like ANSI
code. e.g. to make them bold red: `disabled_color='\x1b[1;31m'`; can
also use codes from blessed like `disabled_color=Terminal().yellow`;
to make it not-colored, `disabled_color=""`)
- `pagination_color`: (optional) if you want to change the color that
the pagination messages (shown when there is multiple pages of content
to scroll through); by default, is uncolored. Accepts a string like
ANSI code. e.g. to make them bold red: `pagination_color='\x1b[1;31m'`;
can also use codes from blessed like `pagination=Terminal().yellow`)

#### Specifying keys

* Refer to list of names from the [blessed docs](https://blessed.readthedocs.io/en/latest/keyboard.html#id1)

If the key you wish to use is a single non-system key (i.e alphanumeric),
then you can use `ord('<key>')`; however, in order to specify system keys,
you must specify them to the `*_keys` parameter like so:

```python
from blessed.keyboard import get_curses_keycodes # type: ignore

# Would allow the user to select current selection with
# BOTH space (default) and the right arrow:
pick(..., select_keys = [get_curses_keycodes()["KEY_RIGHT"], ...)
```

Note that options passed are _additive_ to the defaults. If you wish
to override the defaults entirely, you must also set the constant values
to nothing before calling `pick`:

```python
import pick

# overwrite UP_KEYS, DOWN_KEYS, SELECT_KEYS, ENTER_KEYS, QUIT_KEYS
pick.UP_KEYS = []

# would result in "U" being the only way to move the cursor up
pick(..., up_keys = [ord('U')], ...)
```


## Community Projects

Expand Down
10 changes: 7 additions & 3 deletions example/basic.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from pick import pick
from typing import List
from blessed.keyboard import get_curses_keycodes # type: ignore

KEY_CTRL_C = 3
KEY_ESCAPE = 27
QUIT_KEYS = (KEY_CTRL_C, KEY_ESCAPE, ord("q"))
keystrokes = get_curses_keycodes()

# https://blessed.readthedocs.io/en/latest/keyboard.html
# KEY_EXIT is the escape key
QUIT_KEYS: List[int] = [ord("q"), keystrokes["KEY_EXIT"], keystrokes["KEY_F1"]]

title = "Please choose your favorite programming language: "
options = ["Java", "JavaScript", "Python", "PHP", "C++", "Erlang", "Haskell"]
Expand Down
53 changes: 48 additions & 5 deletions example/multiselect.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
from pick import pick
#!/usr/bin/env python

title = "Choose your favorite programming language(use space to select)"
options = ["Java", "JavaScript", "Python", "PHP", "C++", "Erlang", "Haskell"]
selected = pick(options, title, multiselect=True, min_selection_count=1)
print(selected)
from typing import List
from blessed import Terminal
from blessed.keyboard import get_curses_keycodes # type: ignore
import pick

pick.SELECT_KEYS = []

options: List[pick.OPTION_T] = [
pick.Option(
"Option 1",
"value_field",
"Description field is printed, too (this option is disabled)",
enabled=False,
),
"option 2",
"option 3",
pick.Option("Option 4", "value", "This option is green", color=Terminal().green),
"option 5",
pick.Option(
"Option 6",
"value",
"This is a colored but disabled option",
enabled=False,
color=Terminal().pink,
),
"option 7",
]

prompt = (
"(Up/down/tab to move; space to select/de-select; Enter to continue; "
+ "To filter options, simply begin typing)"
)

# Note that the disabled choices are dark grey by default, but can be
# a custom color via the disabled_color= option:
choice = pick.pick(
options,
prompt,
indicator="=>",
multiselect=True,
min_selection_count=2,
quit_keys=[ord("q")],
select_keys=[get_curses_keycodes()["KEY_RIGHT"]],
disabled_color=Terminal().gray35,
)

print(f"You chose: {choice}")
3 changes: 1 addition & 2 deletions example/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ def main(stdscr):
stdscr.get_wch()

y, x = stdscr.getyx()

title = "Please choose your favorite programming language: "
options = ["Java", "JavaScript", "Python", "PHP", "C++", "Erlang", "Haskell"]
option, index = pick.pick(
options,
title,
indicator="=>",
default_index=2,
screen=stdscr,
position=pick.Position(y=y, x=0) # comment this to demonstrate the issue it solves
)

Expand Down
7 changes: 4 additions & 3 deletions example/scroll.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pick import pick
from blessed.terminal import Terminal

title = "Select:"
options = ["foo.bar%s.baz" % x for x in range(1, 71)]
option, index = pick(options, title)
title = "Select (begin typing to filter options):"
options = [f"foo.bar{x}.baz" * 100 for x in range(1, 71)]
option, index = pick(options, title, pagination_color=Terminal().green)
print(option, index)
Loading