Skip to content

Commit 8f77c5a

Browse files
committed
patch 8.0.0590: cannot add a context to locations
Problem: Cannot add a context to locations. Solution: Add the "context" entry in location entries. (Yegappan Lakshmanan, closes #1012)
1 parent a21ccb7 commit 8f77c5a

File tree

5 files changed

+125
-0
lines changed

5 files changed

+125
-0
lines changed

src/eval.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5327,6 +5327,10 @@ garbage_collect(int testing)
53275327
abort = abort || set_ref_in_timer(copyID);
53285328
#endif
53295329

5330+
#ifdef FEAT_QUICKFIX
5331+
abort = abort || set_ref_in_quickfix(copyID);
5332+
#endif
5333+
53305334
if (!abort)
53315335
{
53325336
/*

src/proto/quickfix.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ void ex_vimgrep(exarg_T *eap);
2929
int get_errorlist(win_T *wp, int qf_idx, list_T *list);
3030
int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict);
3131
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what);
32+
int set_ref_in_quickfix(int copyID);
3233
void ex_cbuffer(exarg_T *eap);
3334
void ex_cexpr(exarg_T *eap);
3435
void ex_helpgrep(exarg_T *eap);

src/quickfix.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ typedef struct qf_list_S
5757
int qf_nonevalid; /* TRUE if not a single valid entry found */
5858
char_u *qf_title; /* title derived from the command that created
5959
* the error list */
60+
typval_T *qf_ctx; /* context set by setqflist/setloclist */
6061
} qf_list_T;
6162

6263
struct qf_info_S
@@ -1596,6 +1597,14 @@ copy_loclist(win_T *from, win_T *to)
15961597
to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
15971598
else
15981599
to_qfl->qf_title = NULL;
1600+
if (from_qfl->qf_ctx != NULL)
1601+
{
1602+
to_qfl->qf_ctx = alloc_tv();
1603+
if (to_qfl->qf_ctx != NULL)
1604+
copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx);
1605+
}
1606+
else
1607+
to_qfl->qf_ctx = NULL;
15991608

16001609
if (from_qfl->qf_count)
16011610
{
@@ -2749,6 +2758,8 @@ qf_free(qf_info_T *qi, int idx)
27492758
}
27502759
vim_free(qi->qf_lists[idx].qf_title);
27512760
qi->qf_lists[idx].qf_title = NULL;
2761+
free_tv(qi->qf_lists[idx].qf_ctx);
2762+
qi->qf_lists[idx].qf_ctx = NULL;
27522763
qi->qf_lists[idx].qf_index = 0;
27532764
qi->qf_lists[idx].qf_start = NULL;
27542765
qi->qf_lists[idx].qf_last = NULL;
@@ -4629,6 +4640,7 @@ enum {
46294640
QF_GETLIST_ITEMS = 0x2,
46304641
QF_GETLIST_NR = 0x4,
46314642
QF_GETLIST_WINID = 0x8,
4643+
QF_GETLIST_CONTEXT = 0x10,
46324644
QF_GETLIST_ALL = 0xFF
46334645
};
46344646

@@ -4681,6 +4693,9 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
46814693
if (dict_find(what, (char_u *)"winid", -1) != NULL)
46824694
flags |= QF_GETLIST_WINID;
46834695

4696+
if (dict_find(what, (char_u *)"context", -1) != NULL)
4697+
flags |= QF_GETLIST_CONTEXT;
4698+
46844699
if (flags & QF_GETLIST_TITLE)
46854700
{
46864701
char_u *t;
@@ -4699,6 +4714,21 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
46994714
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
47004715
}
47014716

4717+
if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
4718+
{
4719+
if (qi->qf_lists[qf_idx].qf_ctx != NULL)
4720+
{
4721+
di = dictitem_alloc((char_u *)"context");
4722+
if (di != NULL)
4723+
{
4724+
copy_tv(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
4725+
dict_add(retdict, di);
4726+
}
4727+
}
4728+
else
4729+
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
4730+
}
4731+
47024732
return status;
47034733
}
47044734

@@ -4874,6 +4904,16 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action)
48744904
}
48754905
}
48764906

4907+
if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
4908+
{
4909+
typval_T *ctx;
4910+
free_tv(qi->qf_lists[qi->qf_curlist].qf_ctx);
4911+
ctx = alloc_tv();
4912+
if (ctx != NULL)
4913+
copy_tv(&di->di_tv, ctx);
4914+
qi->qf_lists[qi->qf_curlist].qf_ctx = ctx;
4915+
}
4916+
48774917
return retval;
48784918
}
48794919

@@ -4981,6 +5021,52 @@ set_errorlist(
49815021

49825022
return retval;
49835023
}
5024+
5025+
static int
5026+
mark_quickfix_ctx(qf_info_T *qi, int copyID)
5027+
{
5028+
int i;
5029+
int abort = FALSE;
5030+
typval_T *ctx;
5031+
5032+
for (i = 0; i < LISTCOUNT && !abort; ++i)
5033+
{
5034+
ctx = qi->qf_lists[i].qf_ctx;
5035+
if (ctx != NULL && ctx->v_type != VAR_NUMBER &&
5036+
ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT)
5037+
abort = set_ref_in_item(ctx, copyID, NULL, NULL);
5038+
}
5039+
5040+
return abort;
5041+
}
5042+
5043+
/*
5044+
* Mark the context of the quickfix list and the location lists (if present) as
5045+
* "in use". So that garabage collection doesn't free the context.
5046+
*/
5047+
int
5048+
set_ref_in_quickfix(int copyID)
5049+
{
5050+
int abort = FALSE;
5051+
tabpage_T *tp;
5052+
win_T *win;
5053+
5054+
abort = mark_quickfix_ctx(&ql_info, copyID);
5055+
if (abort)
5056+
return abort;
5057+
5058+
FOR_ALL_TAB_WINDOWS(tp, win)
5059+
{
5060+
if (win->w_llist != NULL)
5061+
{
5062+
abort = mark_quickfix_ctx(win->w_llist, copyID);
5063+
if (abort)
5064+
return abort;
5065+
}
5066+
}
5067+
5068+
return abort;
5069+
}
49845070
#endif
49855071

49865072
/*

src/testdir/test_quickfix.vim

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,38 @@ func Xproperty_tests(cchar)
17721772
if a:cchar == 'l'
17731773
call assert_equal({}, getloclist(99, {'title': 1}))
17741774
endif
1775+
1776+
" Context related tests
1777+
call g:Xsetlist([], 'a', {'context':[1,2,3]})
1778+
call test_garbagecollect_now()
1779+
let d = g:Xgetlist({'context':1})
1780+
call assert_equal([1,2,3], d.context)
1781+
call g:Xsetlist([], 'a', {'context':{'color':'green'}})
1782+
let d = g:Xgetlist({'context':1})
1783+
call assert_equal({'color':'green'}, d.context)
1784+
call g:Xsetlist([], 'a', {'context':"Context info"})
1785+
let d = g:Xgetlist({'context':1})
1786+
call assert_equal("Context info", d.context)
1787+
call g:Xsetlist([], 'a', {'context':246})
1788+
let d = g:Xgetlist({'context':1})
1789+
call assert_equal(246, d.context)
1790+
if a:cchar == 'l'
1791+
" Test for copying context across two different location lists
1792+
new | only
1793+
let w1_id = win_getid()
1794+
let l = [1]
1795+
call setloclist(0, [], 'a', {'context':l})
1796+
new
1797+
let w2_id = win_getid()
1798+
call add(l, 2)
1799+
call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
1800+
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1801+
unlet! l
1802+
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1803+
only
1804+
call setloclist(0, [], 'f')
1805+
call assert_equal({}, getloclist(0, {'context':1}))
1806+
endif
17751807
endfunc
17761808

17771809
func Test_qf_property()

src/version.c

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

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
590,
767769
/**/
768770
589,
769771
/**/

0 commit comments

Comments
 (0)