def select(message, *options): """ Display a confirmation prompt. """ styling = style_from_dict({ Token.Key: 'bold', Token.DefaultKey: 'bold underline', }) def _get_tokens(cli): yield (Token, message + ': ') for i, option in enumerate(options): if i: yield (Token, ', ') if option.default: yield (Token.DefaultKey, option.caption[0].upper()) else: yield (Token.Key, option.caption[0].upper()) yield (Token.Caption, option.caption[1:]) yield (Token, '? ') def _event(option, event): event.cli.buffers[DEFAULT_BUFFER].text = option.output event.cli.set_return_value(option.value) registry = Registry() for option in options: handler = functools.partial(_event, option) for char in option.chars: registry.add_binding(char)(handler) if option.fallback: registry.add_binding(Keys.ControlC)(handler) registry.add_binding(Keys.Escape)(handler) if option.default: registry.add_binding(Keys.Enter)(handler) sys.stdout.flush() return run_application( create_prompt_application( get_prompt_tokens=_get_tokens, style=styling, key_bindings_registry=registry, ))
def main(): app = create_prompt_application('prompt> ') while True: run_application(app)
def __call__(self, questions, **kwargs): if isinstance(questions, Mapping): questions = [questions] answers = {} # specific to prompt_toolkit run_kw = 'patch_stdout return_asyncio_coroutine true_color refresh_interval eventloop'.split( ) run_kw = {k: kwargs.pop(k) for k in run_kw if k in kwargs} run_kw.setdefault('true_color', True) history = InMemoryHistory() for question in questions: kw = {} kw.update(kwargs) kw.update(question) # get question type _type = kw.pop('type', 'input') # get question name name = kw.pop('name') # handle the prompt message = kw.pop('message') if callable(message): message = message(answers) tokens = [ (Token.Prompt.Prefix, kw.pop('prefix', '?')), (Token.Space, ' '), (Token.Prompt.Message, message), (Token.Prompt.Suffix, kw.pop('suffix', '')), (Token.Space, ' '), ] kw['get_prompt_tokens'] = get_prompt_tokens_factory(tokens) # handle defaults if callable(kw.get('default', None)): kw['default'] = kw['default'](answers) # handle choices if callable(kw.get('choices', None)): kw['choices'] = kw['choices'](answers) # get the filter _filter = kw.pop('filter', None) # decide whether or not to ask the question if 'when' in kw: when = kw.pop('when') if callable(when) and not when(answers): continue elif not when: continue # ask the question kw['history'] = history # fix pylint warning if 'pageSize' in kw: kw['page_size'] = kw.pop('pageSize', None) # bind answers to transformer if 'transformer' in kw: kw['transformer'] = bind_answers(kw['transformer'], answers) application = getattr(prompts, _type).question(**kw) answer = run_application(application, **run_kw) # filter the response if _filter: answer = _filter(answer) # save the response to answers temp = answers path = name.split('.') for part in path[:-1]: temp = temp.setdefault(part, {}) temp[path[-1]] = answer return answers
def prompt(questions, answers=None, **kwargs): if isinstance(questions, dict): questions = [questions] answers = answers or {} patch_stdout = kwargs.pop('patch_stdout', False) return_asyncio_coroutine = kwargs.pop('return_asyncio_coroutine', False) true_color = kwargs.pop('true_color', False) refresh_interval = kwargs.pop('refresh_interval', 0) eventloop = kwargs.pop('eventloop', None) kbi_msg = kwargs.pop('keyboard_interrupt_msg', 'Cancelled by user') raise_kbi = kwargs.pop('raise_keyboard_interrupt', False) for question in questions: # import the question if 'type' not in question: raise PromptParameterException('type') if 'name' not in question: raise PromptParameterException('name') if 'message' not in question: raise PromptParameterException('message') try: choices = question.get('choices') if choices is not None and callable(choices): question['choices'] = choices(answers) _kwargs = {} _kwargs.update(kwargs) _kwargs.update(question) type = _kwargs.pop('type') name = _kwargs.pop('name') message = _kwargs.pop('message') when = _kwargs.pop('when', None) filter = _kwargs.pop('filter', None) if when: # at least a little sanity check! if callable(question['when']): try: if not question['when'](answers): continue except Exception as e: raise ValueError( 'Problem in \'when\' check of %s question: %s' % (name, e)) else: raise ValueError('\'when\' needs to be function that ' \ 'accepts a dict argument') if filter: # at least a little sanity check! if not callable(question['filter']): raise ValueError('\'filter\' needs to be function that ' \ 'accepts an argument') if callable(question.get('default')): _kwargs['default'] = question['default'](answers) application = getattr(prompts, type).question(message, **_kwargs) answer = run_application( application, patch_stdout=patch_stdout, return_asyncio_coroutine=return_asyncio_coroutine, true_color=true_color, refresh_interval=refresh_interval, eventloop=eventloop) if answer is not None: if filter: try: answer = question['filter'](answer) except Exception as e: raise ValueError( 'Problem processing \'filter\' of %s question: %s' % (name, e)) answers[name] = answer except AttributeError as e: print(e) raise ValueError('No question type \'%s\'' % type) except KeyboardInterrupt as exc: if raise_kbi: raise exc from None if kbi_msg: print('') print(kbi_msg) print('') return {} return answers
def confirm_without_ctrl_c(message): app = create_confirm_application(message) return run_application(app)