def complete(command_line,
             current_token,
             position,
             shell: arg(choices=('bash', 'fish'))):
    position = int(position)
    tokens = shlex.split(command_line[:position])
    all_argv, run_argv, command_argv = run.partition_argv(tokens[1:])
    run_args = run.parse_args(run_argv)
    module = run_args.get('commands_module')
    module = module or DEFAULT_COMMANDS_MODULE
    module = normalize_path(module)
    try:
        collection = Collection.load_from_module(module)
    except Exception:
        collection = {}
    found_command = find_command(collection, tokens) or run
    if current_token:
        if current_token.startswith('-'):
            if current_token not in found_command.option_map:
                print_command_options(found_command, current_token)
        else:
            print_commands(collection, shell)
            path = os.path.expanduser(current_token)
            path = os.path.expandvars(path)
            paths = glob.glob('%s*' % path)
            if paths:
                for entry in paths:
                    if os.path.isdir(entry):
                        print('%s/' % entry)
                    else:
                        print(entry)
    else:
        option = found_command.option_map.get(tokens[-1])
        if option and option.takes_value:
            if option.choices:
                for choice in option.choices:
                    print(choice)
            else:
                for entry in os.listdir():
                    if os.path.isdir(entry):
                        print('%s/' % entry)
                    else:
                        print(entry)
        else:
            print_command_options(found_command)
            print_commands(collection, shell)