Skip to content

ExpandPrompt

Kevin Zhuang edited this page Oct 5, 2021 · 6 revisions

This page is deprecated, documentation moved to: https://inquirerpy.readthedocs.io/

A list prompt with 2 sets of UIs, compact and expanded.

The prompt will reveal itself in a compact state but can be expanded using h key. After expansion, the normal list navigation key will be activated.

class ExpandPrompt(BaseListPrompt):
    def __init__(
        self,
        message: Union[str, Callable[[SessionResult], str]],
        choices: Union[Callable[[SessionResult], List[Any]], List[Any]],
        default: Any = "",
        style: InquirerPyStyle = None,
        vi_mode: bool = False,
        qmark: str = "?",
        pointer: str = " ",
        separator: str = ")",
        help_msg: str = "Help, list all choices",
        expand_pointer: str = INQUIRERPY_POINTER_SEQUENCE,
        instruction: str = "",
        transformer: Callable[[Any], Any] = None,
        filter: Callable[[Any], Any] = None,
        height: Union[int, str] = None,
        max_height: Union[int, str] = None,
        multiselect: bool = False,
        marker: str = INQUIRERPY_POINTER_SEQUENCE,
        validate: Union[Callable[[Any], bool], Validator] = None,
        invalid_message: str = "Invalid input",
        keybindings: Dict[str, List[Dict[str, Any]]] = None,
        show_cursor: bool = True,
    ) -> None:

Example

demo

Classic Syntax (PyInquirer)
from InquirerPy import prompt
from InquirerPy.separator import Separator

def question1_choice(_):
    return [
        {"key": "a", "name": "Apple", "value": "Apple"},
        {"key": "c", "name": "Cherry", "value": "Cherry"},
        {"key": "o", "name": "Orange", "value": "Orange"},
        {"key": "p", "name": "Peach", "value": "Peach"},
        {"key": "m", "name": "Melon", "value": "Melon"},
        {"key": "s", "name": "Strawberry", "value": "Strawberry"},
        {"key": "g", "name": "Grapes", "value": "Grapes"},
    ]

def question2_choice(_):
    return [
        {"key": "d", "name": "Delivery", "value": "dl"},
        {"key": "p", "name": "Pick Up", "value": "pk"},
        Separator(line=15 * "*"),
        {"key": "c", "name": "Car Park", "value": "cp"},
        {"key": "t", "name": "Third Party", "value": "tp"},
    ]

questions = [
    {
        "type": "expand",
        "choices": question1_choice,
        "message": "Pick your favourite:",
        "default": "o",
    },
    {
        "type": "expand",
        "choices": question2_choice,
        "message": "Select your preferred method:",
    },
]

result = prompt(questions)
Alternate Syntax
from InquirerPy import inquirer
from InquirerPy.separator import Separator

def question1_choice(_):
    return [
        {"key": "a", "name": "Apple", "value": "Apple"},
        {"key": "c", "name": "Cherry", "value": "Cherry"},
        {"key": "o", "name": "Orange", "value": "Orange"},
        {"key": "p", "name": "Peach", "value": "Peach"},
        {"key": "m", "name": "Melon", "value": "Melon"},
        {"key": "s", "name": "Strawberry", "value": "Strawberry"},
        {"key": "g", "name": "Grapes", "value": "Grapes"},
    ]

def question2_choice(_):
    return [
        {"key": "d", "name": "Delivery", "value": "dl"},
        {"key": "p", "name": "Pick Up", "value": "pk"},
        Separator(line=15 * "*"),
        {"key": "c", "name": "Car Park", "value": "cp"},
        {"key": "t", "name": "Third Party", "value": "tp"},
    ]

fruit = inquirer.expand(
    message="Pick your favourite:", choices=question1_choice, default="o"
).execute()
method = inquirer.expand(
    message="Select your preferred method:", choices=question2_choice
).execute()

Parameters

message: Union[Callable[[SessionResult], str], str]

REQUIRED

The question message to display/ask the user.

When providing as a function, the current prompt session result will be provided as a parameter. If you are using the alternate syntax (i.e. inquirer), put a dummy parameter (_) in your function.

from InquirerPy import inquirer

def get_message(_) -> str:
    message = "Name:"
    # logic ...
    return message

result = inquirer.expand(
    message=get_message,
    choices=[
        {"key": 1, "name": 1, "value": 1},
        {"key": 2, "name": 2, "value": 3},
        {"key": 3, "name": 3, "value": 3},
    ],
).execute()

choices: Union[List[Any], Callable[[SessionResult], List[Any]]]

Note: do not specify the h key, since its already taken and used as the expand key. Also avoid specifying keys such as j or k as they are used for navigation if vi_mode is True.

REQUIRED

A list of choices for user to select.

When providing as a function, the current prompt session result will be provided as a parameter. If you are using the alternate syntax (i.e. inquirer), put a dummy parameter (_) in your function.

choice: Dict[str, Any]

For expand prompt, the choice can only by a dictionary containing the following keys.

  • key: (Union[str, int]) The key to bind to the choice. User can press the key and jump to the this choice.
  • name: (Any) The display name of the choice, user will be able to see this value.
  • value: (Any) The value of the choice, can be different than the name, user will not be able to see this value.

Choice can also be a Separator instance, which can yields visual effect of separating groups of choices. Visit the documentation on Separator for more details.

default: Any

The default value of the prompt. This will be used to determine where the current highlighted choice is. It can be either a value or a callable.

When providing as a function, the current prompt session result will be provided as a parameter. If you are using the alternate syntax (i.e. inquirer), put a dummy parameter (_) in your function.

The default value for expand can be three types of value:

  • shortcut key: (Union[str, int]) default value can be the key of a choice.
  • chocie["value"]: (Any) default value can also be one of the choice["value"].

style: InquirerPy

If you are suing classic syntax (i.e. style), there's no need to provide this value since prompt already sets the style, unless you would like to apply different style for different question.

An InquirerPyStyle instance. Use get_style to retrieve an instance, reference Style documentation for more information.

vi_mode: bool

If you are suing classic syntax (i.e. prompt), there's no need to provide this value since prompt already sets sets this value, unless you would like to apply vi_mode to specific questions.

Enable vim keybindings for the expand prompt. It will change the up navigation from ctrl-p/up to k/up and down navigation from ctrl-n/down to j/down. Checkout Keybindings documentation for more information.

qmark: str

The question mark symbol to display in front of the question. By default, the qmark is ?.

? Question1
? Question2

pointer: str

The pointer symbol which indicates the current selected choice. Reference Style for detailed information on prompt components.

The default symbol for expand is a space, meaning the pointer is not visible. Checkout the demo in Example.

? Question: (aoh) o█
  a) choice1
  o) choice2
  h) Help, list all choices

separator: str

This value can change the UI appearance between the index number and choice. By default, the separator is ).

? Question: (akh) a█
  a) choice1
  k) choice2
  h) Help, list all choices

help_msg: str

The help message to display on expanding for the key h. Default is Help, list all choices.

expand_pointer: str

The symbol to display before expanding the prompt. Default is .

? Question: (ajh) a█
❯ Apple

instruction: str

By default, the instructions are generated by the keys in the choices. Take the following choices as example.

[
    {"key": "a", "name": "Apple", "value": "Apple"},
    {"key": "c", "name": "Cherry", "value": "Cherry"},
    {"key": "o", "name": "Orange", "value": "Orange"},
    {"key": "p", "name": "Peach", "value": "Peach"},
    {"key": "m", "name": "Melon", "value": "Melon"},
    {"key": "s", "name": "Strawberry", "value": "Strawberry"},
    {"key": "g", "name": "Grapes", "value": "Grapes"},
]

The instructions will therefore be (acopmsgh). The h is always generated due to it being the expand key.

Optionally provide some instruction to the user such as navigation keybindings or how many choices they should select. It will override the previous behavior.

transformer: Callable[[Any], Any]

Note: filter function won't affect the answer passed into transformer, filter will manipulate the choice["value"] while the transformer function will manipulate the choice["name"].

A callable to transform the result. This is visual effect only, meaning it doesn't affect the returned result, it only changes the result displayed in the prompt.

The value provided to the transformer is name of a choice (choice["name"]) or a list of name of the choices. This means that the value may be string even if the choices only consists of other types. Reference the following example.

choices = [
    {"key": "d", "name": "Delivery", "value": "dl"},
    {"key": "p", "name": "Pick Up", "value": "pk"},
]

result = inquirer.expand(
    message="Select one:", choices=choices, default="d"
).execute()  # UI -> ? Select one: Delivery
result = inquirer.expand(
    message="Select one:",
    choices=choices,
    default="d",
    transformer=lambda result: result.lower()
).execute()  # UI -> ? Select one: delivery

filter: Callable[[Any], Any]

A callable to filter the result. Different than the transformer, this affects the actual returned result but doesn't affect the visible prompt content.

The value provided to the filter is the value of a choice (choice["value"]) or a list of value of the choices.

choices = [
    {"key": "d", "name": "Delivery", "value": "dl"},
    {"key": "p", "name": "Pick Up", "value": "pk"},
]

result = inquirer.expand(
    message="Select one:", choices=choices, default="d"
).execute()  # result = "dl"
result = inquirer.expand(
    message="Select one:",
    choices=choices,
    default="d",
    filter=lambda result: result.upper()
).execute()  # result = "DL"

height: Union[int, str]

Note: for a better experience, setting the max_height is the preferred way of specifying the height. max_height allow the height of the prompt to be more dynamic, prompt will only take as much space as it needs. When reaching max_height, user will be able to scroll.

Set the height of the expand prompt. This parameter can be used to control how much height the prompt should take. The height parameter will set the prompt height to a fixed value no matter how much space the content requires.

When content is less than the height, height will be extended to the specified height even if the content doesn't require that much space leaving areas blank.

When content is greater than the height, user will be able to scroll through the prompt when navigating up/down.

The value of height can be either a int or a string. An int indicates an exact value in how many lines in the terminal the prompt should take. (e.g. setting height to 1 will cause the prompt to only display 1 choice at a time). A str indicates a percentile in respect to the entire visible terminal.

The following example will only display 2 choices at a time, meaning only the choice Delivery and Pick Up will be visible. The choice Walk will be visible when user scroll down.

result = inquirer.expand(
    message="Select one:",
    choices=[
        {"key": "d", "name": "Delivery", "value": "dl"},
        {"key": "p", "name": "Pick Up", "value": "pk"},
        {"key": "w", "name": "Walk", "value": "wl"},
    ],
    default="p",
    height=2
).execute()

The following example will cause the expand prompt to take 50% of the entire terminal.

result = inquirer.expand(
    message="Select one:",
    choices=[
        {"key": "d", "name": "Delivery", "value": "dl"},
        {"key": "p", "name": "Pick Up", "value": "pk"},
        {"key": "w", "name": "Walk", "value": "wl"},
    ],
    default="p",
    height="50%" # or just "50"
).execute()

max_height: Union[int, str]

The default max_height for all prompt is "60%" if both height and max_height is not provided.

This value controls the maximum height the prompt can grow. When reaching the maximum height, user will be able to scroll.

The value of max_height can be either a int or a string. An int indicates an exact value in how many lines in the terminal the prompt can take. (e.g. setting height to 1 will cause the prompt to only display 1 choice at a time). A str indicates a percentile in respect to the entire visible terminal.

The following example will let the expand prompt to display all of its content unless the visible terminal is less 10 lines in which 9 * 0.5 - 2 is not enough to display all 3 choices, then user will be able to scroll.

result = inquirer.expand(
    message="Select one:",
    choices=[
        {"key": "d", "name": "Delivery", "value": "dl"},
        {"key": "p", "name": "Pick Up", "value": "pk"},
        {"key": "w", "name": "Walk", "value": "wl"},
    ],
    default="p",
    max_height="50%" # or just "50"
).execute()

multiselect: bool

Enable multiple selection of the expand prompt. This enables the keybindings such as tab and shift-tab to select more choices. Visit Keybinding for detailed information on keybindings.

Setting this value to True also change the result from a single value to a list of values.

marker: str

A symbol indicating the selected/marked choices. When a choice is selected using keybindings such as tab or space, this symbol will be displayed between the pointer and choice. Reference Style for more details on prompt components.

The default symbol is an unicode .

? Question: (akh) a█
 ❯a) choice1
 ❯k) choice2
  h) Help, list all choices

validate: Union[Callable[[str], bool], Validator]

Provide the validator for this question. Checkout Validator documentation for full details.

An effective way of using validator against a expand prompt would be checking and enforcing the minimum choices that's required to be selected in a multiselect scenario.

invalid_message: str

Configure the error message to display to the user when input does not meet compliance.

If the validate parameter is a Validator instance, then skip this parameter.

keybindings: Dict[str, List[Dict[str, Any]]]

Provide a dictionary of custom keybindings to apply to this prompt. For more information of keybindings, reference Keybinding section.

show_cursor: bool

By default, InquirerPy will display cursor at the end of the expand prompt. Set to False if you prefer to hide the cursor.

Clone this wiki locally