Beispiel #1
0
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,
        ))
Beispiel #2
0
def main():
    app = create_prompt_application('prompt> ')
    while True:
        run_application(app)
Beispiel #3
0
    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)