0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.0.1023: it is not easy to identify a quickfix list

Problem:    It is not easy to identify a quickfix list.
Solution:   Add the "id" field. (Yegappan Lakshmanan)
This commit is contained in:
Bram Moolenaar
2017-08-30 20:33:55 +02:00
parent 1a333bc44a
commit a539f4f1ae
4 changed files with 120 additions and 34 deletions

View File

@@ -4632,6 +4632,9 @@ getqflist([{what}]) *getqflist()*
returns only the items listed in {what} as a dictionary. The returns only the items listed in {what} as a dictionary. The
following string items are supported in {what}: following string items are supported in {what}:
context get the context stored with |setqflist()| context get the context stored with |setqflist()|
id get information for the quickfix list with
|quickfix-ID|; zero means the id for the
current list or the list specifed by 'nr'
items quickfix list entries items quickfix list entries
nr get information for this quickfix list; zero nr get information for this quickfix list; zero
means the current quickfix list and '$' means means the current quickfix list and '$' means
@@ -4646,6 +4649,8 @@ getqflist([{what}]) *getqflist()*
all all of the above quickfix properties all all of the above quickfix properties
Non-string items in {what} are ignored. Non-string items in {what} are ignored.
If "nr" is not present then the current quickfix list is used. If "nr" is not present then the current quickfix list is used.
If both "nr" and a non-zero "id" are specified, then the list
specified by "id" is used.
To get the number of lists in the quickfix stack, set 'nr' to To get the number of lists in the quickfix stack, set 'nr' to
'$' in {what}. The 'nr' value in the returned dictionary '$' in {what}. The 'nr' value in the returned dictionary
contains the quickfix stack size. contains the quickfix stack size.
@@ -4657,6 +4662,7 @@ getqflist([{what}]) *getqflist()*
The returned dictionary contains the following entries: The returned dictionary contains the following entries:
context context information stored with |setqflist()| context context information stored with |setqflist()|
id quickfix list ID |quickfix-ID|
items quickfix list entries items quickfix list entries
nr quickfix list number nr quickfix list number
title quickfix list title text title quickfix list title text
@@ -7069,6 +7075,7 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
text and add the resulting entries to the text and add the resulting entries to the
quickfix list {nr}. The value can be a string quickfix list {nr}. The value can be a string
with one line or a list with multiple lines. with one line or a list with multiple lines.
id quickfix list identifier |quickfix-ID|
items list of quickfix entries. Same as the {list} items list of quickfix entries. Same as the {list}
argument. argument.
nr list number in the quickfix stack; zero nr list number in the quickfix stack; zero
@@ -7079,6 +7086,9 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
If the "nr" item is not present, then the current quickfix list If the "nr" item is not present, then the current quickfix list
is modified. When creating a new quickfix list, "nr" can be is modified. When creating a new quickfix list, "nr" can be
set to a value one greater than the quickfix stack size. set to a value one greater than the quickfix stack size.
When modifying a quickfix list, to guarantee that the correct
list is modified, 'id' should be used instead of 'nr' to
specify the list.
Examples: > Examples: >
:call setqflist([], 'r', {'title': 'My search'}) :call setqflist([], 'r', {'title': 'My search'})

View File

@@ -58,6 +58,7 @@ struct qfline_S
*/ */
typedef struct qf_list_S typedef struct qf_list_S
{ {
int_u qf_id; /* Unique identifier for this list */
qfline_T *qf_start; /* pointer to the first error */ qfline_T *qf_start; /* pointer to the first error */
qfline_T *qf_last; /* pointer to the last error */ qfline_T *qf_last; /* pointer to the last error */
qfline_T *qf_ptr; /* pointer to the current error */ qfline_T *qf_ptr; /* pointer to the current error */
@@ -96,6 +97,7 @@ struct qf_info_S
}; };
static qf_info_T ql_info; /* global quickfix list */ static qf_info_T ql_info; /* global quickfix list */
static int_u last_qf_id = 0; /* Last used quickfix list id */
#define FMT_PATTERNS 10 /* maximum number of % recognized */ #define FMT_PATTERNS 10 /* maximum number of % recognized */
@@ -1399,6 +1401,7 @@ qf_new_list(qf_info_T *qi, char_u *qf_title)
qi->qf_curlist = qi->qf_listcount++; qi->qf_curlist = qi->qf_listcount++;
vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
qf_store_title(qi, qi->qf_curlist, qf_title); qf_store_title(qi, qi->qf_curlist, qf_title);
qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id;
} }
/* /*
@@ -1672,6 +1675,9 @@ copy_loclist(win_T *from, win_T *to)
to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */ to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */
/* Assign a new ID for the location list */
to_qfl->qf_id = ++last_qf_id;
/* When no valid entries are present in the list, qf_ptr points to /* When no valid entries are present in the list, qf_ptr points to
* the first item in the list */ * the first item in the list */
if (to_qfl->qf_nonevalid) if (to_qfl->qf_nonevalid)
@@ -2808,6 +2814,7 @@ qf_free(qf_info_T *qi, int idx)
qfl->qf_title = NULL; qfl->qf_title = NULL;
free_tv(qfl->qf_ctx); free_tv(qfl->qf_ctx);
qfl->qf_ctx = NULL; qfl->qf_ctx = NULL;
qfl->qf_id = 0;
} }
/* /*
@@ -4628,6 +4635,7 @@ enum {
QF_GETLIST_NR = 0x4, QF_GETLIST_NR = 0x4,
QF_GETLIST_WINID = 0x8, QF_GETLIST_WINID = 0x8,
QF_GETLIST_CONTEXT = 0x10, QF_GETLIST_CONTEXT = 0x10,
QF_GETLIST_ID = 0x20,
QF_GETLIST_ALL = 0xFF QF_GETLIST_ALL = 0xFF
}; };
@@ -4688,18 +4696,18 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
return qf_get_list_from_text(di, retdict); return qf_get_list_from_text(di, retdict);
if (wp != NULL) if (wp != NULL)
{
qi = GET_LOC_LIST(wp); qi = GET_LOC_LIST(wp);
if (qi == NULL)
/* List is not present or is empty */
if (qi == NULL || qi->qf_listcount == 0)
{ {
/* If querying for the size of the location list, return 0 */ /* If querying for the size of the list, return 0 */
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL) if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
&& (di->di_tv.v_type == VAR_STRING) && (di->di_tv.v_type == VAR_STRING)
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0)) && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
return dict_add_nr_str(retdict, "nr", 0, NULL); return dict_add_nr_str(retdict, "nr", 0, NULL);
return FAIL; return FAIL;
} }
}
qf_idx = qi->qf_curlist; /* default is the current list */ qf_idx = qi->qf_curlist; /* default is the current list */
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
@@ -4714,26 +4722,38 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (qf_idx < 0 || qf_idx >= qi->qf_listcount) if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
return FAIL; return FAIL;
} }
else if (qi->qf_listcount == 0) /* stack is empty */
return FAIL;
flags |= QF_GETLIST_NR;
} }
else if ((di->di_tv.v_type == VAR_STRING) else if ((di->di_tv.v_type == VAR_STRING)
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0)) && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
{
/* Get the last quickfix list number */ /* Get the last quickfix list number */
if (qi->qf_listcount > 0)
qf_idx = qi->qf_listcount - 1; qf_idx = qi->qf_listcount - 1;
else else
qf_idx = -1; /* Quickfix stack is empty */ return FAIL;
flags |= QF_GETLIST_NR; flags |= QF_GETLIST_NR;
} }
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
{
/* Look for a list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER)
{
/* For zero, use the current list or the list specifed by 'nr' */
if (di->di_tv.vval.v_number != 0)
{
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
{
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
break;
}
if (qf_idx == qi->qf_listcount)
return FAIL; /* List not found */
}
flags |= QF_GETLIST_ID;
}
else else
return FAIL; return FAIL;
} }
if (qf_idx != -1)
{
if (dict_find(what, (char_u *)"all", -1) != NULL) if (dict_find(what, (char_u *)"all", -1) != NULL)
flags |= QF_GETLIST_ALL; flags |= QF_GETLIST_ALL;
@@ -4748,7 +4768,6 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (dict_find(what, (char_u *)"items", -1) != NULL) if (dict_find(what, (char_u *)"items", -1) != NULL)
flags |= QF_GETLIST_ITEMS; flags |= QF_GETLIST_ITEMS;
}
if (flags & QF_GETLIST_TITLE) if (flags & QF_GETLIST_TITLE)
{ {
@@ -4798,6 +4817,10 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)""); status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
} }
if ((status == OK) && (flags & QF_GETLIST_ID))
status = dict_add_nr_str(retdict, "id", qi->qf_lists[qf_idx].qf_id,
NULL);
return status; return status;
} }
@@ -4983,6 +5006,21 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
return FAIL; return FAIL;
} }
if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
{
/* Use the quickfix/location list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER)
{
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
break;
if (qf_idx == qi->qf_listcount)
return FAIL; /* List not found */
}
else
return FAIL;
}
if (newlist) if (newlist)
{ {
qi->qf_curlist = qf_idx; qi->qf_curlist = qf_idx;

View File

@@ -1897,8 +1897,9 @@ func Xproperty_tests(cchar)
call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
let l1=g:Xgetlist({'nr':1,'all':1}) let l1=g:Xgetlist({'nr':1,'all':1})
let l2=g:Xgetlist({'nr':2,'all':1}) let l2=g:Xgetlist({'nr':2,'all':1})
let l1.nr=2 let save_id = l1.id
let l2.nr=1 let l1.id=l2.id
let l2.id=save_id
call g:Xsetlist([], 'r', l1) call g:Xsetlist([], 'r', l1)
call g:Xsetlist([], 'r', l2) call g:Xsetlist([], 'r', l2)
let newl1=g:Xgetlist({'nr':1,'all':1}) let newl1=g:Xgetlist({'nr':1,'all':1})
@@ -2545,3 +2546,38 @@ func Test_get_list_from_text()
call XgetListFromText('c') call XgetListFromText('c')
call XgetListFromText('l') call XgetListFromText('l')
endfunc endfunc
" Tests for the quickfix list id
func Xqfid_tests(cchar)
call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':0}))
Xexpr ''
let start_id = g:Xgetlist({'id' : 0}).id
Xexpr '' | Xexpr ''
Xolder
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
call g:Xsetlist([], 'a', {'id':start_id+1, 'text':'F1:10:L10'})
call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
let qfid = g:Xgetlist({'id':0, 'nr':0})
call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
endfunc
func Test_qf_id()
call Xqfid_tests('c')
call Xqfid_tests('l')
endfunc

View File

@@ -769,6 +769,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1023,
/**/ /**/
1022, 1022,
/**/ /**/