CLI interface

def _cli():
    '''CLI interface'''
    parser = _argparse.ArgumentParser(
        description='''
            Present the user with a simple CLI menu, and return the option chosen.
            The menu is presented via stderr.
            The output is printed to stdout for piping.
            '''.format(_VERSION),
        epilog='''
            The default for the post prompt is "Enter an option to continue: ".
            If --default-index is specified, the default option value will be printed
                in the post prompt as well.
        '''
    )
    parser.add_argument(
        'option',
        help='The option(s) to present to the user.',
        nargs='*'
    )
    parser.add_argument(
        '--version', '-v',
        help='Print the version and then exit',
        action='store_true'
    )
    parser.add_argument(
        '--pre', '-p',
        help='The pre-prompt/title/introduction to the menu. [%(default)s]',
        default='Options:',
        metavar='TEXT'
    )
    parser.add_argument(
        '--post', '-P',
        help='The prompt presented to the user after the menu items.',
        default=_NO_ARG,
        metavar='TEXT'
    )
    parser.add_argument(
        '--default-index', '-d',
        help='The index of the item to use as the default',
        type=int,
        metavar='INT'
    )
    parser.add_argument(
        '--indexed', '-i',
        help='Print indices with the options, and allow the user to use them to choose.',
        action='store_true'
    )
    parser.add_argument(
        '--insensitive', '-I',
        help=(
            'Perform insensitive matching.  Also drops any items that case-insensitively match'
            + ' prior items.'
        ),
        action='store_true'
    )
    parser.add_argument(
        '--fuzzy', '-f',
        help='search for the individual words in the user input anywhere in the item strings.',
        action='store_true'
    )
    parser.add_argument(
        '--stdout',
        help='Use stdout for interactive output (instead of the default: stderr).',
        action='store_true'
    )
    # parse options
    args = parser.parse_args()
    # argparse nargs is awkward.  Translate to be a proper plural.
    options = args.option
    # set the stream
    stream = _sys.stdout if args.stdout else _sys.stderr
    # if version, print version and exit
    if args.version:
        stream.write('Pimento - v{}\n'.format(_VERSION))
        exit(0)
    # read more options from stdin if there are are any
    # but only if we're on a 'nix system with tty's
    tty = '/dev/tty'
    if not _sys.stdin.isatty() and _path.exists(tty):
        if _sys.version_info.major == 3:
            stream.write('[!] python3 input bug - tab completion not available\n')
            stream.write('[!] python3 input bug - arrow support not available\n')
            stream.write('[!] only known workaround is to not pipe in.\n')
        options += [l.rstrip() for l in _sys.stdin]
        # switch to the main tty
        # this solution (to being interactive after reading from pipe)
        # comes from: https://stackoverflow.com/questions/6312819/pipes-and-prompts-in-python-cli-scripts
        _sys.stdin = open(tty)
    # show the menu
    try:
        result = menu(
            options,
            pre_prompt=args.pre,
            post_prompt=args.post,
            default_index=args.default_index,
            indexed=args.indexed,
            insensitive=args.insensitive,
            fuzzy=args.fuzzy,
            stream=stream
        )
        # print the result (to stdout)
        _sys.stdout.write(result + '\n')
    except KeyboardInterrupt:
        _sys.stderr.write("\nCTRL-C detected. Exiting.\n")
        _sys.stderr.flush()
    except Exception as e:
        _sys.stdout.write("ERROR: {}\n".format(e))
        exit(1)