mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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 vim/vim#1012)
8f77c5a4ec
This commit is contained in:
parent
53a530b2f5
commit
20708a07bf
@ -5173,6 +5173,8 @@ bool garbage_collect(bool testing)
|
|||||||
ABORTING(set_ref_list)(sub.additional_elements, copyID);
|
ABORTING(set_ref_list)(sub.additional_elements, copyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ABORTING(set_ref_in_quickfix)(copyID);
|
||||||
|
|
||||||
bool did_free = false;
|
bool did_free = false;
|
||||||
if (!abort) {
|
if (!abort) {
|
||||||
// 2. Free lists and dictionaries that are not referenced.
|
// 2. Free lists and dictionaries that are not referenced.
|
||||||
|
@ -85,6 +85,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 {
|
||||||
@ -1409,6 +1410,13 @@ void copy_loclist(win_T *from, win_T *to)
|
|||||||
else
|
else
|
||||||
to_qfl->qf_title = NULL;
|
to_qfl->qf_title = NULL;
|
||||||
|
|
||||||
|
if (from_qfl->qf_ctx != NULL) {
|
||||||
|
to_qfl->qf_ctx = xcalloc(1, sizeof(typval_T));
|
||||||
|
tv_copy(from_qfl->qf_ctx, to_qfl->qf_ctx);
|
||||||
|
} else {
|
||||||
|
to_qfl->qf_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (from_qfl->qf_count) {
|
if (from_qfl->qf_count) {
|
||||||
qfline_T *from_qfp;
|
qfline_T *from_qfp;
|
||||||
qfline_T *prevp;
|
qfline_T *prevp;
|
||||||
@ -2410,6 +2418,8 @@ static void qf_free(qf_info_T *qi, int idx)
|
|||||||
qi->qf_lists[idx].qf_start = NULL;
|
qi->qf_lists[idx].qf_start = NULL;
|
||||||
qi->qf_lists[idx].qf_ptr = NULL;
|
qi->qf_lists[idx].qf_ptr = NULL;
|
||||||
qi->qf_lists[idx].qf_title = NULL;
|
qi->qf_lists[idx].qf_title = NULL;
|
||||||
|
tv_free(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;
|
||||||
@ -4060,6 +4070,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
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4110,6 +4121,10 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
|||||||
flags |= QF_GETLIST_WINID;
|
flags |= QF_GETLIST_WINID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tv_dict_find(what, S_LEN("context")) != NULL) {
|
||||||
|
flags |= QF_GETLIST_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & QF_GETLIST_TITLE) {
|
if (flags & QF_GETLIST_TITLE) {
|
||||||
char_u *t = qi->qf_lists[qf_idx].qf_title;
|
char_u *t = qi->qf_lists[qf_idx].qf_title;
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
@ -4127,6 +4142,18 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) {
|
||||||
|
if (qi->qf_lists[qf_idx].qf_ctx != NULL) {
|
||||||
|
di = tv_dict_item_alloc_len(S_LEN("context"));
|
||||||
|
if (di != NULL) {
|
||||||
|
tv_copy(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
|
||||||
|
tv_dict_add(retdict, di);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = tv_dict_add_str(retdict, S_LEN("context"), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4276,6 +4303,14 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((di = tv_dict_find(what, S_LEN("context"))) != NULL) {
|
||||||
|
tv_free(qi->qf_lists[qi->qf_curlist].qf_ctx);
|
||||||
|
|
||||||
|
typval_T *ctx = xcalloc(1, sizeof(typval_T));
|
||||||
|
tv_copy(&di->di_tv, ctx);
|
||||||
|
qi->qf_lists[qi->qf_curlist].qf_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4362,6 +4397,42 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mark_quickfix_ctx(qf_info_T *qi, int copyID)
|
||||||
|
{
|
||||||
|
bool abort = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < LISTCOUNT && !abort; i++) {
|
||||||
|
typval_T *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.
|
||||||
|
bool set_ref_in_quickfix(int copyID)
|
||||||
|
{
|
||||||
|
bool 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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ":[range]cbuffer [bufnr]" command.
|
* ":[range]cbuffer [bufnr]" command.
|
||||||
* ":[range]caddbuffer [bufnr]" command.
|
* ":[range]caddbuffer [bufnr]" command.
|
||||||
|
@ -1754,6 +1754,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()
|
||||||
|
Loading…
Reference in New Issue
Block a user