forked from aniani/vim
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)
This commit is contained in:
@@ -5327,6 +5327,10 @@ garbage_collect(int testing)
|
|||||||
abort = abort || set_ref_in_timer(copyID);
|
abort = abort || set_ref_in_timer(copyID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_QUICKFIX
|
||||||
|
abort = abort || set_ref_in_quickfix(copyID);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!abort)
|
if (!abort)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@@ -29,6 +29,7 @@ void ex_vimgrep(exarg_T *eap);
|
|||||||
int get_errorlist(win_T *wp, int qf_idx, list_T *list);
|
int get_errorlist(win_T *wp, int qf_idx, list_T *list);
|
||||||
int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict);
|
int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict);
|
||||||
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what);
|
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what);
|
||||||
|
int set_ref_in_quickfix(int copyID);
|
||||||
void ex_cbuffer(exarg_T *eap);
|
void ex_cbuffer(exarg_T *eap);
|
||||||
void ex_cexpr(exarg_T *eap);
|
void ex_cexpr(exarg_T *eap);
|
||||||
void ex_helpgrep(exarg_T *eap);
|
void ex_helpgrep(exarg_T *eap);
|
||||||
|
@@ -57,6 +57,7 @@ typedef struct qf_list_S
|
|||||||
int qf_nonevalid; /* TRUE if not a single valid entry found */
|
int qf_nonevalid; /* TRUE if not a single valid entry found */
|
||||||
char_u *qf_title; /* title derived from the command that created
|
char_u *qf_title; /* title derived from the command that created
|
||||||
* the error list */
|
* the error list */
|
||||||
|
typval_T *qf_ctx; /* context set by setqflist/setloclist */
|
||||||
} qf_list_T;
|
} qf_list_T;
|
||||||
|
|
||||||
struct qf_info_S
|
struct qf_info_S
|
||||||
@@ -1596,6 +1597,14 @@ copy_loclist(win_T *from, win_T *to)
|
|||||||
to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
|
to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
|
||||||
else
|
else
|
||||||
to_qfl->qf_title = NULL;
|
to_qfl->qf_title = NULL;
|
||||||
|
if (from_qfl->qf_ctx != NULL)
|
||||||
|
{
|
||||||
|
to_qfl->qf_ctx = alloc_tv();
|
||||||
|
if (to_qfl->qf_ctx != NULL)
|
||||||
|
copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to_qfl->qf_ctx = NULL;
|
||||||
|
|
||||||
if (from_qfl->qf_count)
|
if (from_qfl->qf_count)
|
||||||
{
|
{
|
||||||
@@ -2749,6 +2758,8 @@ qf_free(qf_info_T *qi, int idx)
|
|||||||
}
|
}
|
||||||
vim_free(qi->qf_lists[idx].qf_title);
|
vim_free(qi->qf_lists[idx].qf_title);
|
||||||
qi->qf_lists[idx].qf_title = NULL;
|
qi->qf_lists[idx].qf_title = NULL;
|
||||||
|
free_tv(qi->qf_lists[idx].qf_ctx);
|
||||||
|
qi->qf_lists[idx].qf_ctx = NULL;
|
||||||
qi->qf_lists[idx].qf_index = 0;
|
qi->qf_lists[idx].qf_index = 0;
|
||||||
qi->qf_lists[idx].qf_start = NULL;
|
qi->qf_lists[idx].qf_start = NULL;
|
||||||
qi->qf_lists[idx].qf_last = NULL;
|
qi->qf_lists[idx].qf_last = NULL;
|
||||||
@@ -4629,6 +4640,7 @@ enum {
|
|||||||
QF_GETLIST_ITEMS = 0x2,
|
QF_GETLIST_ITEMS = 0x2,
|
||||||
QF_GETLIST_NR = 0x4,
|
QF_GETLIST_NR = 0x4,
|
||||||
QF_GETLIST_WINID = 0x8,
|
QF_GETLIST_WINID = 0x8,
|
||||||
|
QF_GETLIST_CONTEXT = 0x10,
|
||||||
QF_GETLIST_ALL = 0xFF
|
QF_GETLIST_ALL = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4681,6 +4693,9 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
|||||||
if (dict_find(what, (char_u *)"winid", -1) != NULL)
|
if (dict_find(what, (char_u *)"winid", -1) != NULL)
|
||||||
flags |= QF_GETLIST_WINID;
|
flags |= QF_GETLIST_WINID;
|
||||||
|
|
||||||
|
if (dict_find(what, (char_u *)"context", -1) != NULL)
|
||||||
|
flags |= QF_GETLIST_CONTEXT;
|
||||||
|
|
||||||
if (flags & QF_GETLIST_TITLE)
|
if (flags & QF_GETLIST_TITLE)
|
||||||
{
|
{
|
||||||
char_u *t;
|
char_u *t;
|
||||||
@@ -4699,6 +4714,21 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
|||||||
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
|
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
|
||||||
|
{
|
||||||
|
if (qi->qf_lists[qf_idx].qf_ctx != NULL)
|
||||||
|
{
|
||||||
|
di = dictitem_alloc((char_u *)"context");
|
||||||
|
if (di != NULL)
|
||||||
|
{
|
||||||
|
copy_tv(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
|
||||||
|
dict_add(retdict, di);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4874,6 +4904,16 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
|
||||||
|
{
|
||||||
|
typval_T *ctx;
|
||||||
|
free_tv(qi->qf_lists[qi->qf_curlist].qf_ctx);
|
||||||
|
ctx = alloc_tv();
|
||||||
|
if (ctx != NULL)
|
||||||
|
copy_tv(&di->di_tv, ctx);
|
||||||
|
qi->qf_lists[qi->qf_curlist].qf_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4981,6 +5021,52 @@ set_errorlist(
|
|||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mark_quickfix_ctx(qf_info_T *qi, int copyID)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int abort = FALSE;
|
||||||
|
typval_T *ctx;
|
||||||
|
|
||||||
|
for (i = 0; i < LISTCOUNT && !abort; ++i)
|
||||||
|
{
|
||||||
|
ctx = qi->qf_lists[i].qf_ctx;
|
||||||
|
if (ctx != NULL && ctx->v_type != VAR_NUMBER &&
|
||||||
|
ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT)
|
||||||
|
abort = set_ref_in_item(ctx, copyID, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark the context of the quickfix list and the location lists (if present) as
|
||||||
|
* "in use". So that garabage collection doesn't free the context.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
set_ref_in_quickfix(int copyID)
|
||||||
|
{
|
||||||
|
int abort = FALSE;
|
||||||
|
tabpage_T *tp;
|
||||||
|
win_T *win;
|
||||||
|
|
||||||
|
abort = mark_quickfix_ctx(&ql_info, copyID);
|
||||||
|
if (abort)
|
||||||
|
return abort;
|
||||||
|
|
||||||
|
FOR_ALL_TAB_WINDOWS(tp, win)
|
||||||
|
{
|
||||||
|
if (win->w_llist != NULL)
|
||||||
|
{
|
||||||
|
abort = mark_quickfix_ctx(win->w_llist, copyID);
|
||||||
|
if (abort)
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1772,6 +1772,38 @@ func Xproperty_tests(cchar)
|
|||||||
if a:cchar == 'l'
|
if a:cchar == 'l'
|
||||||
call assert_equal({}, getloclist(99, {'title': 1}))
|
call assert_equal({}, getloclist(99, {'title': 1}))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Context related tests
|
||||||
|
call g:Xsetlist([], 'a', {'context':[1,2,3]})
|
||||||
|
call test_garbagecollect_now()
|
||||||
|
let d = g:Xgetlist({'context':1})
|
||||||
|
call assert_equal([1,2,3], d.context)
|
||||||
|
call g:Xsetlist([], 'a', {'context':{'color':'green'}})
|
||||||
|
let d = g:Xgetlist({'context':1})
|
||||||
|
call assert_equal({'color':'green'}, d.context)
|
||||||
|
call g:Xsetlist([], 'a', {'context':"Context info"})
|
||||||
|
let d = g:Xgetlist({'context':1})
|
||||||
|
call assert_equal("Context info", d.context)
|
||||||
|
call g:Xsetlist([], 'a', {'context':246})
|
||||||
|
let d = g:Xgetlist({'context':1})
|
||||||
|
call assert_equal(246, d.context)
|
||||||
|
if a:cchar == 'l'
|
||||||
|
" Test for copying context across two different location lists
|
||||||
|
new | only
|
||||||
|
let w1_id = win_getid()
|
||||||
|
let l = [1]
|
||||||
|
call setloclist(0, [], 'a', {'context':l})
|
||||||
|
new
|
||||||
|
let w2_id = win_getid()
|
||||||
|
call add(l, 2)
|
||||||
|
call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
|
||||||
|
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
|
||||||
|
unlet! l
|
||||||
|
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
|
||||||
|
only
|
||||||
|
call setloclist(0, [], 'f')
|
||||||
|
call assert_equal({}, getloclist(0, {'context':1}))
|
||||||
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_qf_property()
|
func Test_qf_property()
|
||||||
|
@@ -764,6 +764,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 */
|
||||||
|
/**/
|
||||||
|
590,
|
||||||
/**/
|
/**/
|
||||||
589,
|
589,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user