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_in_quickfix)(copyID);
|
||||
|
||||
bool did_free = false;
|
||||
if (!abort) {
|
||||
// 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
|
||||
char_u *qf_title; // title derived from the command that created
|
||||
// the error list
|
||||
typval_T *qf_ctx; // context set by setqflist/setloclist
|
||||
} qf_list_T;
|
||||
|
||||
struct qf_info_S {
|
||||
@ -1409,6 +1410,13 @@ void copy_loclist(win_T *from, win_T *to)
|
||||
else
|
||||
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) {
|
||||
qfline_T *from_qfp;
|
||||
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_ptr = 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_start = NULL;
|
||||
qi->qf_lists[idx].qf_last = NULL;
|
||||
@ -4060,6 +4070,7 @@ enum {
|
||||
QF_GETLIST_ITEMS = 0x2,
|
||||
QF_GETLIST_NR = 0x4,
|
||||
QF_GETLIST_WINID = 0x8,
|
||||
QF_GETLIST_CONTEXT = 0x10,
|
||||
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;
|
||||
}
|
||||
|
||||
if (tv_dict_find(what, S_LEN("context")) != NULL) {
|
||||
flags |= QF_GETLIST_CONTEXT;
|
||||
}
|
||||
|
||||
if (flags & QF_GETLIST_TITLE) {
|
||||
char_u *t = qi->qf_lists[qf_idx].qf_title;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -4362,6 +4397,42 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
|
||||
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]caddbuffer [bufnr]" command.
|
||||
|
@ -1754,6 +1754,38 @@ func Xproperty_tests(cchar)
|
||||
if a:cchar == 'l'
|
||||
call assert_equal({}, getloclist(99, {'title': 1}))
|
||||
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
|
||||
|
||||
func Test_qf_property()
|
||||
|
Loading…
Reference in New Issue
Block a user