cape.promptutils: Simple tools for interactive CLI prompts

This module provides tools for auto-completion, colored formatting, and more when prompting users for values interactively.

When the optional third-party textual package is installed and standard input and output are both terminals with a reasonable $TERM, prompts that present a list of options (via vopt) are shown as a clickable menu instead: clicking an option (or pressing Enter on it) selects it, just like typing @N on the readline prompt. Free text, @N answers, and empty input to accept the default still work through a text box in the menu. This clickable backend can be controlled with clickable, and the $CAPE_PROMPT_CLICK environment variable can be set to always or never to override auto-detection.

cape.promptutils.clickable_prompt_ok(clickable: bool | None = None) → bool

Check if clickable option menus are currently available

Clickable prompts require the optional third-party textual package to be installed. Unless forced using clickable or the $CAPE_PROMPT_CLICK environment variable, clickable prompts are only activated if standard input and output are both terminals with a reasonable $TERM.

Call:
>>> ok = clickable_prompt_ok(clickable=None)
Inputs:
clickable: {None} | True | False

If True or False, force clickable prompts on or off; if None, consult $CAPE_PROMPT_CLICK and then auto-detect the terminal

Outputs:
ok: True | False

Whether clickable option menus should be used

cape.promptutils.complete_glob(text: str, state: int) → str | None

Return a tab-completion suggestion based on file names

Call:
>>> suggestion = complete_glob(text, state)
Inputs:
text: str

User input so far

state: int

Return the suggestion of index state, (usually 0)

Outputs:
suggestion: str | None

A file whose name starts with text if possible

cape.promptutils.input_color(prompt: str, color: str = 'black') → str

Modify built-in input() to also set color

Call:
>>> raw = input_color(prompt, color)
Inputs:
prompt: str

Text to display prior to requesting input

color: str

Common name of color to use for prompt

Outputs:
raw: str

User’s input

cape.promptutils.prompt_click(txt: str, vdef: Any | None = None, vopt: list | None = None, prompt: str = '>', oneline: bool = False) → str

Run a clickable option prompt and return the user’s reply

The menu is rendered inline (when the terminal supports it), so that the question and options remain part of the terminal stream along with the user’s answer; on terminals without inline-rendering support, it retries in full-screen mode. The reply has the same format as input_color(): clicking option j of vopt answers "@{j+1}", typing free text answers that text, and pressing Escape (like empty input) answers "". Such replies can be parsed using the same logic as prompt_color() (i.e. @N selects vopt[N-1]).

Call:
>>> vraw = prompt_click(txt, vdef, vopt, prompt, oneline)
Inputs:
txt: str

Text of the question

vdef: {None} | object

Default value (if any)

vopt: {None} | list

List of possible or suggested values

prompt: {">"} | str

Character(s) to use as prompt

oneline: True | {False}

Use compact one-line buttons instead of a list

Outputs:
vraw: str

User’s raw reply

Raises:

KeyboardInterrupt: if the user quits the prompt menu

cape.promptutils.prompt_color(txt: str, vdef: Any | None = None, vopt: list | None = None, color: str = 'green', prompt: str = '>', completer: Callable | None = None, glob: bool = False, show: bool = True, oneline: bool = False, pcolor: str | None = None, atcolor: str | None = None, ocolor: str | None = None, clickable: bool | None = None, erase: bool = True) → Any

Get user input using a colorized prompt

Call:
>>> v = prompt_color(txt, vdef=None)
Inputs:
txt: str

Text of the question on the same line as prompt

vdef: {None} | object

Default value (if any)

vopt: {None} | list

List of possible or suggested values (optional)

color: {"green"} | str

Color name for entire prompt

completer: {None} | callable

Function to return list of suggestions given current text

prompt: {">"} | str

Character(s) to use as prompt

glob: True | {False}

Use glob to suggest file-name-based completions

show: {True} | False

Print the final selection for confirmation

oneline: True | {False}

Option to display values as compact one-line list [y]/n

clickable: {None} | True | False

If True, use a clickable menu for option lists (only when the textual package is installed); if False, always use the colored readline prompt; if None, auto-detect a TUI-capable terminal (see also clickable_prompt_ok())

erase: {True} | False

If True, erase the option list and prompt line (the n+1 lines below the question for n options) from the screen after the user answers, leaving only the question and the final selection; only applies to multi-line option lists on a terminal

Outputs:
v: str | vdef | vopt[j]

User input or default value

cape.promptutils.register_prompt_handler(handler: Callable | None) → Callable | None

Register (or clear) a host handler for interactive prompts

If set, prompt_color() calls handler to obtain the user’s raw reply instead of rendering a prompt itself. The handler signature mirrors prompt_click() and it must return a raw reply with the same format (i.e. "@{j+1}" for option j, typed text, or "" to accept the default); it may raise KeyboardInterrupt to abort. This allows a host application, such as the CAPE TUI, to render prompts in its own interface while its commands run in another thread.

Call:
>>> prev_handler = register_prompt_handler(handler)
Inputs:
handler: callable | {None}

Prompt handler to register, or None to clear

Outputs:
prev_handler: {None} | callable

Previously registered handler (for restoration)

cape.promptutils.textual_terminal_ok() → bool

Check for Textual and an interactive, non-dumb terminal.