Skip to content

Commit a539f4f

Browse files
committed
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)
1 parent 1a333bc commit a539f4f

4 files changed

Lines changed: 120 additions & 34 deletions

File tree

runtime/doc/eval.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4632,6 +4632,9 @@ getqflist([{what}]) *getqflist()*
46324632
returns only the items listed in {what} as a dictionary. The
46334633
following string items are supported in {what}:
46344634
context get the context stored with |setqflist()|
4635+
id get information for the quickfix list with
4636+
|quickfix-ID|; zero means the id for the
4637+
current list or the list specifed by 'nr'
46354638
items quickfix list entries
46364639
nr get information for this quickfix list; zero
46374640
means the current quickfix list and '$' means
@@ -4646,6 +4649,8 @@ getqflist([{what}]) *getqflist()*
46464649
all all of the above quickfix properties
46474650
Non-string items in {what} are ignored.
46484651
If "nr" is not present then the current quickfix list is used.
4652+
If both "nr" and a non-zero "id" are specified, then the list
4653+
specified by "id" is used.
46494654
To get the number of lists in the quickfix stack, set 'nr' to
46504655
'$' in {what}. The 'nr' value in the returned dictionary
46514656
contains the quickfix stack size.
@@ -4657,6 +4662,7 @@ getqflist([{what}]) *getqflist()*
46574662

46584663
The returned dictionary contains the following entries:
46594664
context context information stored with |setqflist()|
4665+
id quickfix list ID |quickfix-ID|
46604666
items quickfix list entries
46614667
nr quickfix list number
46624668
title quickfix list title text
@@ -7069,6 +7075,7 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
70697075
text and add the resulting entries to the
70707076
quickfix list {nr}. The value can be a string
70717077
with one line or a list with multiple lines.
7078+
id quickfix list identifier |quickfix-ID|
70727079
items list of quickfix entries. Same as the {list}
70737080
argument.
70747081
nr list number in the quickfix stack; zero
@@ -7079,6 +7086,9 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
70797086
If the "nr" item is not present, then the current quickfix list
70807087
is modified. When creating a new quickfix list, "nr" can be
70817088
set to a value one greater than the quickfix stack size.
7089+
When modifying a quickfix list, to guarantee that the correct
7090+
list is modified, 'id' should be used instead of 'nr' to
7091+
specify the list.
70827092

70837093
Examples: >
70847094
:call setqflist([], 'r', {'title': 'My search'})

src/quickfix.c

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct qfline_S
5858
*/
5959
typedef struct qf_list_S
6060
{
61+
int_u qf_id; /* Unique identifier for this list */
6162
qfline_T *qf_start; /* pointer to the first error */
6263
qfline_T *qf_last; /* pointer to the last error */
6364
qfline_T *qf_ptr; /* pointer to the current error */
@@ -96,6 +97,7 @@ struct qf_info_S
9697
};
9798

9899
static qf_info_T ql_info; /* global quickfix list */
100+
static int_u last_qf_id = 0; /* Last used quickfix list id */
99101

100102
#define FMT_PATTERNS 10 /* maximum number of % recognized */
101103

@@ -1399,6 +1401,7 @@ qf_new_list(qf_info_T *qi, char_u *qf_title)
13991401
qi->qf_curlist = qi->qf_listcount++;
14001402
vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
14011403
qf_store_title(qi, qi->qf_curlist, qf_title);
1404+
qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id;
14021405
}
14031406

14041407
/*
@@ -1672,6 +1675,9 @@ copy_loclist(win_T *from, win_T *to)
16721675

16731676
to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */
16741677

1678+
/* Assign a new ID for the location list */
1679+
to_qfl->qf_id = ++last_qf_id;
1680+
16751681
/* When no valid entries are present in the list, qf_ptr points to
16761682
* the first item in the list */
16771683
if (to_qfl->qf_nonevalid)
@@ -2808,6 +2814,7 @@ qf_free(qf_info_T *qi, int idx)
28082814
qfl->qf_title = NULL;
28092815
free_tv(qfl->qf_ctx);
28102816
qfl->qf_ctx = NULL;
2817+
qfl->qf_id = 0;
28112818
}
28122819

28132820
/*
@@ -4628,6 +4635,7 @@ enum {
46284635
QF_GETLIST_NR = 0x4,
46294636
QF_GETLIST_WINID = 0x8,
46304637
QF_GETLIST_CONTEXT = 0x10,
4638+
QF_GETLIST_ID = 0x20,
46314639
QF_GETLIST_ALL = 0xFF
46324640
};
46334641

@@ -4688,17 +4696,17 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
46884696
return qf_get_list_from_text(di, retdict);
46894697

46904698
if (wp != NULL)
4691-
{
46924699
qi = GET_LOC_LIST(wp);
4693-
if (qi == NULL)
4694-
{
4695-
/* If querying for the size of the location list, return 0 */
4696-
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
4697-
&& (di->di_tv.v_type == VAR_STRING)
4698-
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
4699-
return dict_add_nr_str(retdict, "nr", 0, NULL);
4700-
return FAIL;
4701-
}
4700+
4701+
/* List is not present or is empty */
4702+
if (qi == NULL || qi->qf_listcount == 0)
4703+
{
4704+
/* If querying for the size of the list, return 0 */
4705+
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
4706+
&& (di->di_tv.v_type == VAR_STRING)
4707+
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
4708+
return dict_add_nr_str(retdict, "nr", 0, NULL);
4709+
return FAIL;
47024710
}
47034711

47044712
qf_idx = qi->qf_curlist; /* default is the current list */
@@ -4714,41 +4722,52 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
47144722
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
47154723
return FAIL;
47164724
}
4717-
else if (qi->qf_listcount == 0) /* stack is empty */
4718-
return FAIL;
4719-
flags |= QF_GETLIST_NR;
47204725
}
47214726
else if ((di->di_tv.v_type == VAR_STRING)
47224727
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
4723-
{
47244728
/* Get the last quickfix list number */
4725-
if (qi->qf_listcount > 0)
4726-
qf_idx = qi->qf_listcount - 1;
4727-
else
4728-
qf_idx = -1; /* Quickfix stack is empty */
4729-
flags |= QF_GETLIST_NR;
4730-
}
4729+
qf_idx = qi->qf_listcount - 1;
47314730
else
47324731
return FAIL;
4732+
flags |= QF_GETLIST_NR;
47334733
}
47344734

4735-
if (qf_idx != -1)
4735+
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
47364736
{
4737-
if (dict_find(what, (char_u *)"all", -1) != NULL)
4738-
flags |= QF_GETLIST_ALL;
4737+
/* Look for a list with the specified id */
4738+
if (di->di_tv.v_type == VAR_NUMBER)
4739+
{
4740+
/* For zero, use the current list or the list specifed by 'nr' */
4741+
if (di->di_tv.vval.v_number != 0)
4742+
{
4743+
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
4744+
{
4745+
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
4746+
break;
4747+
}
4748+
if (qf_idx == qi->qf_listcount)
4749+
return FAIL; /* List not found */
4750+
}
4751+
flags |= QF_GETLIST_ID;
4752+
}
4753+
else
4754+
return FAIL;
4755+
}
47394756

4740-
if (dict_find(what, (char_u *)"title", -1) != NULL)
4741-
flags |= QF_GETLIST_TITLE;
4757+
if (dict_find(what, (char_u *)"all", -1) != NULL)
4758+
flags |= QF_GETLIST_ALL;
47424759

4743-
if (dict_find(what, (char_u *)"winid", -1) != NULL)
4744-
flags |= QF_GETLIST_WINID;
4760+
if (dict_find(what, (char_u *)"title", -1) != NULL)
4761+
flags |= QF_GETLIST_TITLE;
47454762

4746-
if (dict_find(what, (char_u *)"context", -1) != NULL)
4747-
flags |= QF_GETLIST_CONTEXT;
4763+
if (dict_find(what, (char_u *)"winid", -1) != NULL)
4764+
flags |= QF_GETLIST_WINID;
47484765

4749-
if (dict_find(what, (char_u *)"items", -1) != NULL)
4750-
flags |= QF_GETLIST_ITEMS;
4751-
}
4766+
if (dict_find(what, (char_u *)"context", -1) != NULL)
4767+
flags |= QF_GETLIST_CONTEXT;
4768+
4769+
if (dict_find(what, (char_u *)"items", -1) != NULL)
4770+
flags |= QF_GETLIST_ITEMS;
47524771

47534772
if (flags & QF_GETLIST_TITLE)
47544773
{
@@ -4798,6 +4817,10 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
47984817
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
47994818
}
48004819

4820+
if ((status == OK) && (flags & QF_GETLIST_ID))
4821+
status = dict_add_nr_str(retdict, "id", qi->qf_lists[qf_idx].qf_id,
4822+
NULL);
4823+
48014824
return status;
48024825
}
48034826

@@ -4983,6 +5006,21 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
49835006
return FAIL;
49845007
}
49855008

5009+
if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
5010+
{
5011+
/* Use the quickfix/location list with the specified id */
5012+
if (di->di_tv.v_type == VAR_NUMBER)
5013+
{
5014+
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
5015+
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
5016+
break;
5017+
if (qf_idx == qi->qf_listcount)
5018+
return FAIL; /* List not found */
5019+
}
5020+
else
5021+
return FAIL;
5022+
}
5023+
49865024
if (newlist)
49875025
{
49885026
qi->qf_curlist = qf_idx;

src/testdir/test_quickfix.vim

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,8 +1897,9 @@ func Xproperty_tests(cchar)
18971897
call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
18981898
let l1=g:Xgetlist({'nr':1,'all':1})
18991899
let l2=g:Xgetlist({'nr':2,'all':1})
1900-
let l1.nr=2
1901-
let l2.nr=1
1900+
let save_id = l1.id
1901+
let l1.id=l2.id
1902+
let l2.id=save_id
19021903
call g:Xsetlist([], 'r', l1)
19031904
call g:Xsetlist([], 'r', l2)
19041905
let newl1=g:Xgetlist({'nr':1,'all':1})
@@ -2545,3 +2546,38 @@ func Test_get_list_from_text()
25452546
call XgetListFromText('c')
25462547
call XgetListFromText('l')
25472548
endfunc
2549+
2550+
" Tests for the quickfix list id
2551+
func Xqfid_tests(cchar)
2552+
call s:setup_commands(a:cchar)
2553+
2554+
call g:Xsetlist([], 'f')
2555+
call assert_equal({}, g:Xgetlist({'id':0}))
2556+
Xexpr ''
2557+
let start_id = g:Xgetlist({'id' : 0}).id
2558+
Xexpr '' | Xexpr ''
2559+
Xolder
2560+
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
2561+
call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
2562+
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
2563+
call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
2564+
call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
2565+
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
2566+
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
2567+
2568+
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
2569+
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
2570+
call g:Xsetlist([], 'a', {'id':start_id+1, 'text':'F1:10:L10'})
2571+
call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
2572+
call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
2573+
call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
2574+
2575+
let qfid = g:Xgetlist({'id':0, 'nr':0})
2576+
call g:Xsetlist([], 'f')
2577+
call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
2578+
endfunc
2579+
2580+
func Test_qf_id()
2581+
call Xqfid_tests('c')
2582+
call Xqfid_tests('l')
2583+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
1023,
772774
/**/
773775
1022,
774776
/**/

0 commit comments

Comments
 (0)