f_autocmd_get(typval_T *argvars, typval_T *rettv)
{
    event_T	event_arg = NUM_EVENTS;
    event_T	event;
    AutoPat	*ap;
    AutoCmd	*ac;
    list_T	*event_list;
    dict_T	*event_dict;
    char_u	*event_name = NULL;
    char_u	*pat = NULL;
    char_u	*name = NULL;
    int		group = AUGROUP_ALL;

    if (rettv_list_alloc(rettv) == FAIL)
	return;
    if (check_for_opt_dict_arg(argvars, 0) == FAIL)
	return;

    if (argvars[0].v_type == VAR_DICT)
    {
	// return only the autocmds in the specified group
	if (dict_has_key(argvars[0].vval.v_dict, "group"))
	{
	    name = dict_get_string(argvars[0].vval.v_dict,
						      (char_u *)"group", TRUE);
	    if (name == NULL)
		return;

	    if (*name == NUL)
		group = AUGROUP_DEFAULT;
	    else
	    {
		group = au_find_group(name);
		if (group == AUGROUP_ERROR)
		{
		    semsg(_(e_no_such_group_str), name);
		    vim_free(name);
		    return;
		}
	    }
	    vim_free(name);
	}

	// return only the autocmds for the specified event
	if (dict_has_key(argvars[0].vval.v_dict, "event"))
	{
	    int		i;

	    name = dict_get_string(argvars[0].vval.v_dict,
						      (char_u *)"event", TRUE);
	    if (name == NULL)
		return;

	    if (name[0] == '*' && name[1] == NUL)
		event_arg = NUM_EVENTS;
	    else
	    {
		for (i = 0; event_names[i].name != NULL; i++)
		    if (STRICMP(event_names[i].name, name) == 0)
			break;
		if (event_names[i].name == NULL)
		{
		    semsg(_(e_no_such_event_str), name);
		    vim_free(name);
		    return;
		}
		event_arg = event_names[i].event;
	    }
	    vim_free(name);
	}

	// return only the autocmds for the specified pattern
	if (dict_has_key(argvars[0].vval.v_dict, "pattern"))
	{
	    pat = dict_get_string(argvars[0].vval.v_dict,
						    (char_u *)"pattern", TRUE);
	    if (pat == NULL)
		return;
	}
    }

    event_list = rettv->vval.v_list;

    // iterate through all the autocmd events
    for (event = (event_T)0; (int)event < NUM_EVENTS;
	    event = (event_T)((int)event + 1))
    {
	if (event_arg != NUM_EVENTS && event != event_arg)
	    continue;

	event_name = event_nr2name(event);

	// iterate through all the patterns for this autocmd event
	FOR_ALL_AUTOCMD_PATTERNS(event, ap)
	{
	    char_u	*group_name;

	    if (group != AUGROUP_ALL && group != ap->group)
		continue;

	    if (pat != NULL && STRCMP(pat, ap->pat) != 0)
		continue;

	    group_name = get_augroup_name(NULL, ap->group);

	    // iterate through all the commands for this pattern and add one
	    // item for each cmd.
	    for (ac = ap->cmds; ac != NULL; ac = ac->next)
	    {
		event_dict = dict_alloc();
		if (event_dict == NULL
			|| list_append_dict(event_list, event_dict) == FAIL)
		    return;

		if (dict_add_string(event_dict, "event", event_name) == FAIL
			|| dict_add_string(event_dict, "group",
					group_name == NULL ? (char_u *)""
							  : group_name) == FAIL
			|| (ap->buflocal_nr != 0
				&& (dict_add_number(event_dict, "bufnr",
						    ap->buflocal_nr) == FAIL))
			|| dict_add_string(event_dict, "pattern",
							      ap->pat) == FAIL
			|| dict_add_string(event_dict, "cmd", ac->cmd) == FAIL
			|| dict_add_bool(event_dict, "once", ac->once) == FAIL
			|| dict_add_bool(event_dict, "nested",
							   ac->nested) == FAIL)
		    return;
	    }
	}
    }

    vim_free(pat);
}