forked from aniani/vim
patch 7.4.2200
Problem: Cannot get all information about a quickfix list. Solution: Add an optional argument to get/set loc/qf list(). (Yegappan Lakshmanan)
This commit is contained in:
@@ -171,6 +171,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getftime(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getftype(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getline(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED);
|
||||
static void f_getmatches(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getpid(typval_T *argvars, typval_T *rettv);
|
||||
static void f_getcurpos(typval_T *argvars, typval_T *rettv);
|
||||
@@ -591,11 +592,11 @@ static struct fst
|
||||
{"getftime", 1, 1, f_getftime},
|
||||
{"getftype", 1, 1, f_getftype},
|
||||
{"getline", 1, 2, f_getline},
|
||||
{"getloclist", 1, 1, f_getqflist},
|
||||
{"getloclist", 1, 2, f_getloclist},
|
||||
{"getmatches", 0, 0, f_getmatches},
|
||||
{"getpid", 0, 0, f_getpid},
|
||||
{"getpos", 1, 1, f_getpos},
|
||||
{"getqflist", 0, 0, f_getqflist},
|
||||
{"getqflist", 0, 1, f_getqflist},
|
||||
{"getreg", 0, 3, f_getreg},
|
||||
{"getregtype", 0, 1, f_getregtype},
|
||||
{"gettabvar", 2, 3, f_gettabvar},
|
||||
@@ -741,10 +742,10 @@ static struct fst
|
||||
{"setcmdpos", 1, 1, f_setcmdpos},
|
||||
{"setfperm", 2, 2, f_setfperm},
|
||||
{"setline", 2, 2, f_setline},
|
||||
{"setloclist", 2, 3, f_setloclist},
|
||||
{"setloclist", 2, 4, f_setloclist},
|
||||
{"setmatches", 1, 1, f_setmatches},
|
||||
{"setpos", 2, 2, f_setpos},
|
||||
{"setqflist", 1, 2, f_setqflist},
|
||||
{"setqflist", 1, 3, f_setqflist},
|
||||
{"setreg", 2, 3, f_setreg},
|
||||
{"settabvar", 3, 3, f_settabvar},
|
||||
{"settabwinvar", 4, 4, f_settabwinvar},
|
||||
@@ -4529,6 +4530,51 @@ f_getline(typval_T *argvars, typval_T *rettv)
|
||||
get_buffer_lines(curbuf, lnum, end, retlist, rettv);
|
||||
}
|
||||
|
||||
static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv);
|
||||
|
||||
static void
|
||||
get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv)
|
||||
{
|
||||
#ifdef FEAT_QUICKFIX
|
||||
if (what_arg->v_type == VAR_UNKNOWN)
|
||||
{
|
||||
if (rettv_list_alloc(rettv) == OK)
|
||||
if (is_qf || wp != NULL)
|
||||
(void)get_errorlist(wp, -1, rettv->vval.v_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rettv_dict_alloc(rettv) == OK)
|
||||
if (is_qf || (wp != NULL))
|
||||
{
|
||||
if (what_arg->v_type == VAR_DICT)
|
||||
{
|
||||
dict_T *d = what_arg->vval.v_dict;
|
||||
|
||||
if (d != NULL)
|
||||
get_errorlist_properties(wp, d, rettv->vval.v_dict);
|
||||
}
|
||||
else
|
||||
EMSG(_(e_dictreq));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* "getloclist()" function
|
||||
*/
|
||||
static void
|
||||
f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||
{
|
||||
#ifdef FEAT_QUICKFIX
|
||||
win_T *wp;
|
||||
|
||||
wp = find_win_by_nr(&argvars[0], NULL);
|
||||
get_qf_loc_list(FALSE, wp, &argvars[1], rettv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* "getmatches()" function
|
||||
*/
|
||||
@@ -4666,28 +4712,13 @@ f_getpos(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
|
||||
/*
|
||||
* "getqflist()" and "getloclist()" functions
|
||||
* "getqflist()" function
|
||||
*/
|
||||
static void
|
||||
f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||
{
|
||||
#ifdef FEAT_QUICKFIX
|
||||
win_T *wp;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_QUICKFIX
|
||||
if (rettv_list_alloc(rettv) == OK)
|
||||
{
|
||||
wp = NULL;
|
||||
if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */
|
||||
{
|
||||
wp = find_win_by_nr(&argvars[0], NULL);
|
||||
if (wp == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
(void)get_errorlist(wp, rettv->vval.v_list);
|
||||
}
|
||||
get_qf_loc_list(TRUE, NULL, &argvars[0], rettv);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -9525,7 +9556,7 @@ f_setline(typval_T *argvars, typval_T *rettv)
|
||||
appended_lines_mark(lcount, added);
|
||||
}
|
||||
|
||||
static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv);
|
||||
static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *what_arg, typval_T *rettv);
|
||||
|
||||
/*
|
||||
* Used by "setqflist()" and "setloclist()" functions
|
||||
@@ -9535,6 +9566,7 @@ set_qf_ll_list(
|
||||
win_T *wp UNUSED,
|
||||
typval_T *list_arg UNUSED,
|
||||
typval_T *action_arg UNUSED,
|
||||
typval_T *what_arg UNUSED,
|
||||
typval_T *rettv)
|
||||
{
|
||||
#ifdef FEAT_QUICKFIX
|
||||
@@ -9551,6 +9583,8 @@ set_qf_ll_list(
|
||||
else
|
||||
{
|
||||
list_T *l = list_arg->vval.v_list;
|
||||
dict_T *d = NULL;
|
||||
int valid_dict = TRUE;
|
||||
|
||||
if (action_arg->v_type == VAR_STRING)
|
||||
{
|
||||
@@ -9567,8 +9601,20 @@ set_qf_ll_list(
|
||||
else
|
||||
EMSG(_(e_stringreq));
|
||||
|
||||
if (l != NULL && action && set_errorlist(wp, l, action,
|
||||
(char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
|
||||
if (action_arg->v_type != VAR_UNKNOWN
|
||||
&& what_arg->v_type != VAR_UNKNOWN)
|
||||
{
|
||||
if (what_arg->v_type == VAR_DICT)
|
||||
d = what_arg->vval.v_dict;
|
||||
else
|
||||
{
|
||||
EMSG(_(e_dictreq));
|
||||
valid_dict = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (l != NULL && action && valid_dict && set_errorlist(wp, l, action,
|
||||
(char_u *)(wp == NULL ? "setqflist()" : "setloclist()"), d) == OK)
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
#endif
|
||||
@@ -9586,7 +9632,7 @@ f_setloclist(typval_T *argvars, typval_T *rettv)
|
||||
|
||||
win = find_win_by_nr(&argvars[0], NULL);
|
||||
if (win != NULL)
|
||||
set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
|
||||
set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9754,7 +9800,7 @@ f_setpos(typval_T *argvars, typval_T *rettv)
|
||||
static void
|
||||
f_setqflist(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
|
||||
set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -27,8 +27,9 @@ void ex_cnext(exarg_T *eap);
|
||||
void ex_cfile(exarg_T *eap);
|
||||
void ex_vimgrep(exarg_T *eap);
|
||||
char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags);
|
||||
int get_errorlist(win_T *wp, list_T *list);
|
||||
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title);
|
||||
int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict);
|
||||
int get_errorlist(win_T *wp, int qf_idx, list_T *list);
|
||||
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what);
|
||||
void ex_cbuffer(exarg_T *eap);
|
||||
void ex_cexpr(exarg_T *eap);
|
||||
void ex_helpgrep(exarg_T *eap);
|
||||
|
210
src/quickfix.c
210
src/quickfix.c
@@ -3140,6 +3140,24 @@ qf_find_buf(qf_info_T *qi)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the w:quickfix_title variable in the quickfix/location list window
|
||||
*/
|
||||
static void
|
||||
qf_update_win_titlevar(qf_info_T *qi)
|
||||
{
|
||||
win_T *win;
|
||||
win_T *curwin_save;
|
||||
|
||||
if ((win = qf_find_win(qi)) != NULL)
|
||||
{
|
||||
curwin_save = curwin;
|
||||
curwin = win;
|
||||
qf_set_title_var(qi);
|
||||
curwin = curwin_save;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the quickfix buffer. If it exists, update the contents.
|
||||
*/
|
||||
@@ -3148,7 +3166,6 @@ qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
|
||||
{
|
||||
buf_T *buf;
|
||||
win_T *win;
|
||||
win_T *curwin_save;
|
||||
aco_save_T aco;
|
||||
|
||||
/* Check if a buffer for the quickfix list exists. Update it. */
|
||||
@@ -3161,13 +3178,7 @@ qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
|
||||
/* set curwin/curbuf to buf and save a few things */
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
|
||||
if ((win = qf_find_win(qi)) != NULL)
|
||||
{
|
||||
curwin_save = curwin;
|
||||
curwin = win;
|
||||
qf_set_title_var(qi);
|
||||
curwin = curwin_save;
|
||||
}
|
||||
qf_update_win_titlevar(qi);
|
||||
|
||||
qf_fill_buffer(qi, buf, old_last);
|
||||
|
||||
@@ -4532,9 +4543,10 @@ unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
/*
|
||||
* Add each quickfix error to list "list" as a dictionary.
|
||||
* If qf_idx is -1, use the current list. Otherwise, use the specified list.
|
||||
*/
|
||||
int
|
||||
get_errorlist(win_T *wp, list_T *list)
|
||||
get_errorlist(win_T *wp, int qf_idx, list_T *list)
|
||||
{
|
||||
qf_info_T *qi = &ql_info;
|
||||
dict_T *dict;
|
||||
@@ -4550,12 +4562,15 @@ get_errorlist(win_T *wp, list_T *list)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (qi->qf_curlist >= qi->qf_listcount
|
||||
|| qi->qf_lists[qi->qf_curlist].qf_count == 0)
|
||||
if (qf_idx == -1)
|
||||
qf_idx = qi->qf_curlist;
|
||||
|
||||
if (qf_idx >= qi->qf_listcount
|
||||
|| qi->qf_lists[qf_idx].qf_count == 0)
|
||||
return FAIL;
|
||||
|
||||
qfp = qi->qf_lists[qi->qf_curlist].qf_start;
|
||||
for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i)
|
||||
qfp = qi->qf_lists[qf_idx].qf_start;
|
||||
for (i = 1; !got_int && i <= qi->qf_lists[qf_idx].qf_count; ++i)
|
||||
{
|
||||
/* Handle entries with a non-existing buffer number. */
|
||||
bufnum = qfp->qf_fnum;
|
||||
@@ -4590,16 +4605,93 @@ get_errorlist(win_T *wp, list_T *list)
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate the quickfix list with the items supplied in the list
|
||||
* of dictionaries. "title" will be copied to w:quickfix_title.
|
||||
* "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
|
||||
* Flags used by getqflist()/getloclist() to determine which fields to return.
|
||||
*/
|
||||
enum {
|
||||
QF_GETLIST_NONE = 0x0,
|
||||
QF_GETLIST_TITLE = 0x1,
|
||||
QF_GETLIST_ITEMS = 0x2,
|
||||
QF_GETLIST_NR = 0x4,
|
||||
QF_GETLIST_WINID = 0x8,
|
||||
QF_GETLIST_ALL = 0xFF
|
||||
};
|
||||
|
||||
/*
|
||||
* Return quickfix/location list details (title) as a
|
||||
* dictionary. 'what' contains the details to return. If 'list_idx' is -1,
|
||||
* then current list is used. Otherwise the specified list is used.
|
||||
*/
|
||||
int
|
||||
set_errorlist(
|
||||
win_T *wp,
|
||||
list_T *list,
|
||||
int action,
|
||||
char_u *title)
|
||||
get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
{
|
||||
qf_info_T *qi = &ql_info;
|
||||
int status = OK;
|
||||
int qf_idx;
|
||||
dictitem_T *di;
|
||||
int flags = QF_GETLIST_NONE;
|
||||
|
||||
if (wp != NULL)
|
||||
{
|
||||
qi = GET_LOC_LIST(wp);
|
||||
if (qi == NULL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
qf_idx = qi->qf_curlist; /* default is the current list */
|
||||
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
{
|
||||
/* Use the specified quickfix/location list */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
qf_idx = di->di_tv.vval.v_number - 1;
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
|
||||
return FAIL;
|
||||
flags |= QF_GETLIST_NR;
|
||||
}
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (dict_find(what, (char_u *)"all", -1) != NULL)
|
||||
flags |= QF_GETLIST_ALL;
|
||||
|
||||
if (dict_find(what, (char_u *)"title", -1) != NULL)
|
||||
flags |= QF_GETLIST_TITLE;
|
||||
|
||||
if (dict_find(what, (char_u *)"winid", -1) != NULL)
|
||||
flags |= QF_GETLIST_WINID;
|
||||
|
||||
if (flags & QF_GETLIST_TITLE)
|
||||
{
|
||||
char_u *t;
|
||||
t = qi->qf_lists[qf_idx].qf_title;
|
||||
if (t == NULL)
|
||||
t = (char_u *)"";
|
||||
status = dict_add_nr_str(retdict, "title", 0L, t);
|
||||
}
|
||||
if ((status == OK) && (flags & QF_GETLIST_NR))
|
||||
status = dict_add_nr_str(retdict, "nr", qf_idx + 1, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_WINID))
|
||||
{
|
||||
win_T *win;
|
||||
win = qf_find_win(qi);
|
||||
if (win != NULL)
|
||||
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add list of entries to quickfix/location list. Each list entry is
|
||||
* a dictionary with item information.
|
||||
*/
|
||||
static int
|
||||
qf_add_entries(
|
||||
qf_info_T *qi,
|
||||
list_T *list,
|
||||
char_u *title,
|
||||
int action)
|
||||
{
|
||||
listitem_T *li;
|
||||
dict_T *d;
|
||||
@@ -4613,16 +4705,8 @@ set_errorlist(
|
||||
#endif
|
||||
int valid, status;
|
||||
int retval = OK;
|
||||
qf_info_T *qi = &ql_info;
|
||||
int did_bufnr_emsg = FALSE;
|
||||
|
||||
if (wp != NULL)
|
||||
{
|
||||
qi = ll_get_or_alloc_list(wp);
|
||||
if (qi == NULL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
|
||||
/* make place for a new list */
|
||||
qf_new_list(qi, title);
|
||||
@@ -4719,6 +4803,74 @@ set_errorlist(
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
qf_set_properties(qf_info_T *qi, dict_T *what)
|
||||
{
|
||||
dictitem_T *di;
|
||||
int retval = FAIL;
|
||||
int qf_idx;
|
||||
|
||||
qf_idx = qi->qf_curlist; /* default is the current list */
|
||||
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
{
|
||||
/* Use the specified quickfix/location list */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
qf_idx = di->di_tv.vval.v_number - 1;
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if ((di = dict_find(what, (char_u *)"title", -1)) != NULL)
|
||||
{
|
||||
if (di->di_tv.v_type == VAR_STRING)
|
||||
{
|
||||
vim_free(qi->qf_lists[qf_idx].qf_title);
|
||||
qi->qf_lists[qf_idx].qf_title =
|
||||
get_dict_string(what, (char_u *)"title", TRUE);
|
||||
if (qf_idx == qi->qf_curlist)
|
||||
qf_update_win_titlevar(qi);
|
||||
retval = OK;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate the quickfix list with the items supplied in the list
|
||||
* of dictionaries. "title" will be copied to w:quickfix_title.
|
||||
* "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
|
||||
*/
|
||||
int
|
||||
set_errorlist(
|
||||
win_T *wp,
|
||||
list_T *list,
|
||||
int action,
|
||||
char_u *title,
|
||||
dict_T *what)
|
||||
{
|
||||
qf_info_T *qi = &ql_info;
|
||||
int retval = OK;
|
||||
|
||||
if (wp != NULL)
|
||||
{
|
||||
qi = ll_get_or_alloc_list(wp);
|
||||
if (qi == NULL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (what != NULL)
|
||||
retval = qf_set_properties(qi, what);
|
||||
else
|
||||
retval = qf_add_entries(qi, list, title, action);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@@ -916,7 +916,7 @@ do_tag(
|
||||
}
|
||||
|
||||
vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
|
||||
set_errorlist(curwin, list, ' ', IObuff);
|
||||
set_errorlist(curwin, list, ' ', IObuff, NULL);
|
||||
|
||||
list_free(list);
|
||||
vim_free(fname);
|
||||
|
@@ -1505,3 +1505,42 @@ func Test_duplicate_buf()
|
||||
|
||||
call delete('Xgrepthis')
|
||||
endfunc
|
||||
|
||||
" Quickfix/Location list set/get properties tests
|
||||
function Xproperty_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" Error cases
|
||||
call assert_fails('call g:Xgetlist(99)', 'E715:')
|
||||
call assert_fails('call g:Xsetlist(99)', 'E714:')
|
||||
call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
|
||||
|
||||
" Set and get the title
|
||||
Xopen
|
||||
wincmd p
|
||||
call g:Xsetlist([{'filename':'foo', 'lnum':27}])
|
||||
call g:Xsetlist([], 'a', {'title' : 'Sample'})
|
||||
let d = g:Xgetlist({"title":1})
|
||||
call assert_equal('Sample', d.title)
|
||||
|
||||
Xopen
|
||||
call assert_equal('Sample', w:quickfix_title)
|
||||
Xclose
|
||||
|
||||
" Invalid arguments
|
||||
call assert_fails('call g:Xgetlist([])', 'E715')
|
||||
call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
|
||||
let s = g:Xsetlist([], 'a', {'abc':1})
|
||||
call assert_equal(-1, s)
|
||||
|
||||
call assert_equal({}, g:Xgetlist({'abc':1}))
|
||||
|
||||
if a:cchar == 'l'
|
||||
call assert_equal({}, getloclist(99, ['title']))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function Test_qf_property()
|
||||
call Xproperty_tests('c')
|
||||
call Xproperty_tests('l')
|
||||
endfunction
|
||||
|
@@ -763,6 +763,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2200,
|
||||
/**/
|
||||
2199,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user