diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/quickfix.c | 106 | ||||
-rw-r--r-- | src/nvim/testdir/test_quickfix.vim | 40 |
2 files changed, 109 insertions, 37 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index d290beac59..1c03bd2d42 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -82,6 +82,7 @@ struct qfline_S { /// created using setqflist()/setloclist() with a title and/or user context /// information and entries can be added later using setqflist()/setloclist(). typedef struct qf_list_S { + unsigned qf_id; ///< Unique identifier for this list qfline_T *qf_start; ///< pointer to the first error qfline_T *qf_last; ///< pointer to the last error qfline_T *qf_ptr; ///< pointer to the current error @@ -117,6 +118,7 @@ struct qf_info_S { }; static qf_info_T ql_info; /* global quickfix list */ +static unsigned last_qf_id = 0; // Last Used quickfix list id #define FMT_PATTERNS 10 /* maximum number of % recognized */ @@ -1224,6 +1226,7 @@ static void qf_new_list(qf_info_T *qi, char_u *qf_title) qi->qf_curlist = qi->qf_listcount++; memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); qf_store_title(qi, qi->qf_curlist, qf_title); + qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id; } /* @@ -1467,6 +1470,9 @@ void copy_loclist(win_T *from, win_T *to) to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */ + // Assign a new ID for the location list + to_qfl->qf_id = ++last_qf_id; + /* When no valid entries are present in the list, qf_ptr points to * the first item in the list */ if (to_qfl->qf_nonevalid) { @@ -2458,6 +2464,7 @@ static void qf_free(qf_info_T *qi, int idx) qfl->qf_title = NULL; tv_free(qfl->qf_ctx); qfl->qf_ctx = NULL; + qfl->qf_id = 0; } /* @@ -4110,6 +4117,7 @@ enum { QF_GETLIST_NR = 0x4, QF_GETLIST_WINID = 0x8, QF_GETLIST_CONTEXT = 0x10, + QF_GETLIST_ID = 0x20, QF_GETLIST_ALL = 0xFF }; @@ -4155,15 +4163,16 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) if (wp != NULL) { qi = GET_LOC_LIST(wp); - if (qi == NULL) { - // If querying for the size of the location list, return 0 - if (((di = tv_dict_find(what, S_LEN("nr"))) != NULL) - && (di->di_tv.v_type == VAR_STRING) - && strequal((const char *)di->di_tv.vval.v_string, "$")) { - return tv_dict_add_nr(retdict, S_LEN("nr"), 0); - } - return FAIL; + } + // List is not present or is empty + if (qi == NULL || qi->qf_listcount == 0) { + // If querying for the size of the list, return 0 + if (((di = tv_dict_find(what, S_LEN("nr"))) != NULL) + && (di->di_tv.v_type == VAR_STRING) + && (STRCMP(di->di_tv.vval.v_string, "$") == 0)) { + return tv_dict_add_nr(retdict, S_LEN("nr"), 0); } + return FAIL; } int status = OK; @@ -4179,44 +4188,51 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) if (qf_idx < 0 || qf_idx >= qi->qf_listcount) { return FAIL; } - } else if (qi->qf_listcount == 0) { // stack is empty - return FAIL; } - flags |= QF_GETLIST_NR; } else if (di->di_tv.v_type == VAR_STRING && strequal((const char *)di->di_tv.vval.v_string, "$")) { // Get the last quickfix list number - if (qi->qf_listcount > 0) { - qf_idx = qi->qf_listcount - 1; - } else { - qf_idx = -1; // Quickfix stack is empty - } - flags |= QF_GETLIST_NR; + qf_idx = qi->qf_listcount - 1; } else { return FAIL; } + flags |= QF_GETLIST_NR; } - if (qf_idx != -1) { - if (tv_dict_find(what, S_LEN("all")) != NULL) { - flags |= QF_GETLIST_ALL; - } - - if (tv_dict_find(what, S_LEN("title")) != NULL) { - flags |= QF_GETLIST_TITLE; - } - - if (tv_dict_find(what, S_LEN("winid")) != NULL) { - flags |= QF_GETLIST_WINID; - } - - if (tv_dict_find(what, S_LEN("context")) != NULL) { - flags |= QF_GETLIST_CONTEXT; + if ((di = tv_dict_find(what, S_LEN("id"))) != NULL) { + // Look for a list with the specified id + if (di->di_tv.v_type == VAR_NUMBER) { + // For zero, use the current list or the list specifed by 'nr' + if (di->di_tv.vval.v_number != 0) { + for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) { + if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number) { + break; + } + } + if (qf_idx == qi->qf_listcount) { + return FAIL; // List not found + } + } + flags |= QF_GETLIST_ID; + } else { + return FAIL; } + } - if (tv_dict_find(what, S_LEN("items")) != NULL) { - flags |= QF_GETLIST_ITEMS; - } + if (tv_dict_find(what, S_LEN("all")) != NULL) { + flags |= QF_GETLIST_ALL; + } + if (tv_dict_find(what, S_LEN("title")) != NULL) { + flags |= QF_GETLIST_TITLE; + } + if (tv_dict_find(what, S_LEN("winid")) != NULL) { + flags |= QF_GETLIST_WINID; + } + if (tv_dict_find(what, S_LEN("context")) != NULL) { + flags |= QF_GETLIST_CONTEXT; + } + if (tv_dict_find(what, S_LEN("items")) != NULL) { + flags |= QF_GETLIST_ITEMS; } if (flags & QF_GETLIST_TITLE) { @@ -4254,6 +4270,10 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) } } + if ((status == OK) && (flags & QF_GETLIST_ID)) { + status = tv_dict_add_nr(retdict, S_LEN("id"), qi->qf_lists[qf_idx].qf_id); + } + return status; } @@ -4410,6 +4430,22 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action, } } + if (!newlist && (di = tv_dict_find(what, S_LEN("id"))) != NULL) { + // Use the quickfix/location list with the specified id + if (di->di_tv.v_type == VAR_NUMBER) { + for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) { + if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number) { + break; + } + } + if (qf_idx == qi->qf_listcount) { + return FAIL; // List not found + } + } else { + return FAIL; + } + } + if (newlist) { qi->qf_curlist = qf_idx; qf_new_list(qi, title); diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index fd51fb22b4..c2c4f0bfdd 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -1879,8 +1879,9 @@ func Xproperty_tests(cchar) call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) let l1=g:Xgetlist({'nr':1,'all':1}) let l2=g:Xgetlist({'nr':2,'all':1}) - let l1.nr=2 - let l2.nr=1 + let save_id = l1.id + let l1.id=l2.id + let l2.id=save_id call g:Xsetlist([], 'r', l1) call g:Xsetlist([], 'r', l2) let newl1=g:Xgetlist({'nr':1,'all':1}) @@ -2527,3 +2528,38 @@ func Test_get_list_from_text() call XgetListFromText('c') call XgetListFromText('l') endfunc + +" Tests for the quickfix list id +func Xqfid_tests(cchar) + call s:setup_commands(a:cchar) + + call g:Xsetlist([], 'f') + call assert_equal({}, g:Xgetlist({'id':0})) + Xexpr '' + let start_id = g:Xgetlist({'id' : 0}).id + Xexpr '' | Xexpr '' + Xolder + call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) + call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) + call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) + call assert_equal({}, g:Xgetlist({'id':0, 'nr':99})) + call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) + call assert_equal({}, g:Xgetlist({'id':99, 'nr':0})) + call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0})) + + call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) + call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) + call g:Xsetlist([], 'a', {'id':start_id+1, 'text':'F1:10:L10'}) + call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) + call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) + call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) + + let qfid = g:Xgetlist({'id':0, 'nr':0}) + call g:Xsetlist([], 'f') + call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0})) +endfunc + +func Test_qf_id() + call Xqfid_tests('c') + call Xqfid_tests('l') +endfunc |