Skip to content

Add select prompt example #1331

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
94 changes: 94 additions & 0 deletions examples/prompts/select.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python
"""
An example of select prompt.
"""

from prompt_toolkit.application import Application
from prompt_toolkit.filters import IsDone
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.layout.containers import ConditionalContainer, HSplit, Window
from prompt_toolkit.layout.controls import FormattedTextControl
from prompt_toolkit.layout.dimension import Dimension
from prompt_toolkit.layout.layout import Layout


class SelectControl(FormattedTextControl):
def __init__(self, options):
self.options = options
self.selected_index = 0
super().__init__(key_bindings=self._create_key_bindings())

@property
def selected_option(self):
return self.options[self.selected_index]

def _create_key_bindings(self):
kb = KeyBindings()
count = len(self.options)

@kb.add('down', eager=True)
def move_cursor_down(event):
self.selected_index = (self.selected_index + 1) % count

@kb.add('up', eager=True)
def move_cursor_up(event):
self.selected_index = (self.selected_index - 1) % count

@kb.add('enter', eager=True)
def set_selected(event):
value = self.selected_option
event.app.exit(result=value)

@kb.add('c-q', eager=True)
@kb.add('c-c', eager=True)
def _(event):
raise KeyboardInterrupt()

return kb

def select_option_text(self, mark):
text = []
for idx, op in enumerate(self.options):
if idx == self.selected_index:
line = f'{mark} {op}\n'
else:
line = f' {op}\n'
text.append(('', line)) # style, string
return text


def select_prompt(message, options, mark='>'):
control = SelectControl(options)

def get_formatted_text():
return control.select_option_text(mark)

layout = Layout(HSplit([
Window(
height=Dimension.exact(1),
content=FormattedTextControl(
lambda: message + '\n',
show_cursor=False
),
),
Window(
height=Dimension.exact(len(control.options)),
content=FormattedTextControl(get_formatted_text)
),
ConditionalContainer(
Window(control),
filter=~IsDone()
)
]))

app = Application(
layout=layout,
key_bindings=control.key_bindings,
full_screen=False
)
return app.run()


if __name__ == '__main__':
result = select_prompt('select a option:', ['foo', 'bar'], mark='>')
print(f'You selected {result}')