From b4acf609ac2ec39260b9e42bd61fc476d36763ad Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 7 Sep 2018 22:22:37 -0400 Subject: vim-patch:8.0.1006: quickfix list changes when parsing text with 'erroformat' Problem: Cannot parse text with 'erroformat' without changing a quickfix list. Solution: Add the "text" argument to getqflist(). (Yegappan Lakshmanan) https://github.com/vim/vim/commit/7adf06f4e25c795ba32ff0b2e8591330f6a41afb --- src/nvim/eval.c | 2 +- src/nvim/quickfix.c | 52 ++++++++++++++++++++++++++++++++------ src/nvim/testdir/test_quickfix.vim | 26 +++++++++++++++++++ 3 files changed, 71 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d750a47588..309c0fc062 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -9943,7 +9943,7 @@ static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, if (what_arg->v_type == VAR_UNKNOWN) { tv_list_alloc_ret(rettv, kListLenMayKnow); if (is_qf || wp != NULL) { - (void)get_errorlist(wp, -1, rettv->vval.v_list); + (void)get_errorlist(NULL, wp, -1, rettv->vval.v_list); } } else { tv_dict_alloc_ret(rettv); diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 263b8b3a77..d290beac59 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2414,7 +2414,7 @@ static void qf_free_items(qf_info_T *qi, int idx) while (qfl->qf_count && qfl->qf_start != NULL) { qfp = qfl->qf_start; qfpnext = qfp->qf_next; - if (qfl->qf_title != NULL && !stop) { + if (!stop) { xfree(qfp->qf_text); stop = (qfp == qfpnext); xfree(qfp->qf_pattern); @@ -4031,18 +4031,22 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start) /// Add each quickfix error to list "list" as a dictionary. /// If qf_idx is -1, use the current list. Otherwise, use the specified list. -int get_errorlist(win_T *wp, int qf_idx, list_T *list) +int get_errorlist(const qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) { - qf_info_T *qi = &ql_info; + const qf_info_T *qi = qi_arg; char_u buf[2]; qfline_T *qfp; int i; int bufnum; - if (wp != NULL) { - qi = GET_LOC_LIST(wp); - if (qi == NULL) - return FAIL; + if (qi == NULL) { + qi = &ql_info; + if (wp != NULL) { + qi = GET_LOC_LIST(wp); + if (qi == NULL) { + return FAIL; + } + } } if (qf_idx == -1) { @@ -4109,6 +4113,34 @@ enum { QF_GETLIST_ALL = 0xFF }; +// Parse text from 'di' and return the quickfix list items +static int qf_get_list_from_text(dictitem_T *di, dict_T *retdict) +{ + int status = FAIL; + + // Only string and list values are supported + if ((di->di_tv.v_type == VAR_STRING + && di->di_tv.vval.v_string != NULL) + || (di->di_tv.v_type == VAR_LIST + && di->di_tv.vval.v_list != NULL)) { + qf_info_T *qi = xmalloc(sizeof(*qi)); + memset(qi, 0, sizeof(*qi)); + qi->qf_refcount++; + + if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, p_efm, + true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { + list_T *l = tv_list_alloc(kListLenMayKnow); + (void)get_errorlist(qi, NULL, 0, l); + tv_dict_add_list(retdict, S_LEN("items"), l); + status = OK; + qf_free(qi, 0); + } + xfree(qi); + } + + return status; +} + /// Return quickfix/location list details (title) as a /// dictionary. 'what' contains the details to return. If 'list_idx' is -1, /// then current list is used. Otherwise the specified list is used. @@ -4117,6 +4149,10 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) qf_info_T *qi = &ql_info; dictitem_T *di; + if ((di = tv_dict_find(what, S_LEN("text"))) != NULL) { + return qf_get_list_from_text(di, retdict); + } + if (wp != NULL) { qi = GET_LOC_LIST(wp); if (qi == NULL) { @@ -4201,7 +4237,7 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) } if ((status == OK) && (flags & QF_GETLIST_ITEMS)) { list_T *l = tv_list_alloc(kListLenMayKnow); - (void)get_errorlist(wp, qf_idx, l); + (void)get_errorlist(qi, NULL, qf_idx, l); tv_dict_add_list(retdict, S_LEN("items"), l); } diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index f603f46d63..fd51fb22b4 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2501,3 +2501,29 @@ func Test_add_qf() call XaddQf_tests('c') call XaddQf_tests('l') endfunc + +" Test for getting the quickfix list items from some text without modifying +" the quickfix stack +func XgetListFromText(cchar) + call s:setup_commands(a:cchar) + call g:Xsetlist([], 'f') + + let l = g:Xgetlist({'text' : "File1:10:Line10"}).items + call assert_equal(1, len(l)) + call assert_equal('Line10', l[0].text) + + let l = g:Xgetlist({'text' : ["File2:20:Line20", "File2:30:Line30"]}).items + call assert_equal(2, len(l)) + call assert_equal(30, l[1].lnum) + + call assert_equal({}, g:Xgetlist({'text' : 10})) + call assert_equal({}, g:Xgetlist({'text' : []})) + + " Make sure that the quickfix stack is not modified + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) +endfunc + +func Test_get_list_from_text() + call XgetListFromText('c') + call XgetListFromText('l') +endfunc -- cgit From 9bf2741ba4dda8f7b0864858daaad52e596dd856 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 8 Sep 2018 06:13:23 -0400 Subject: vim-patch:8.0.1023: it is not easy to identify a quickfix list Problem: It is not easy to identify a quickfix list. Solution: Add the "id" field. (Yegappan Lakshmanan) https://github.com/vim/vim/commit/a539f4f1ae4a2b3a7dfce89cd3800214c9e990cf --- src/nvim/quickfix.c | 106 +++++++++++++++++++++++++------------ src/nvim/testdir/test_quickfix.vim | 40 +++++++++++++- 2 files changed, 109 insertions(+), 37 deletions(-) (limited to 'src') 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 -- cgit From 1790f81f56087e45f24e82fb8d5f99a9e0f59d49 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 8 Sep 2018 09:38:14 -0400 Subject: vim-patch:8.0.1029: return value of getqflist() is inconsistent Problem: Return value of getqflist() is inconsistent. (Lcd47) Solution: Always return an "items" entry. https://github.com/vim/vim/commit/da73253a0b908bad03ddcd625fe3fb32008efbf6 --- src/nvim/quickfix.c | 7 ++++--- src/nvim/testdir/test_quickfix.vim | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 1c03bd2d42..ec11e5d849 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4131,19 +4131,20 @@ static int qf_get_list_from_text(dictitem_T *di, dict_T *retdict) && di->di_tv.vval.v_string != NULL) || (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)) { + list_T *l = tv_list_alloc(kListLenMayKnow); qf_info_T *qi = xmalloc(sizeof(*qi)); memset(qi, 0, sizeof(*qi)); qi->qf_refcount++; if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, p_efm, true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { - list_T *l = tv_list_alloc(kListLenMayKnow); (void)get_errorlist(qi, NULL, 0, l); - tv_dict_add_list(retdict, S_LEN("items"), l); - status = OK; qf_free(qi, 0); } xfree(qi); + + tv_dict_add_list(retdict, S_LEN("items"), l); + status = OK; } return status; diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index c2c4f0bfdd..c6324b1dc2 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2518,7 +2518,7 @@ func XgetListFromText(cchar) call assert_equal(30, l[1].lnum) call assert_equal({}, g:Xgetlist({'text' : 10})) - call assert_equal({}, g:Xgetlist({'text' : []})) + call assert_equal([], g:Xgetlist({'text' : []}).items) " Make sure that the quickfix stack is not modified call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) -- cgit From 213a66441fb1b01ed30ed1beef4d1aa540549171 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 8 Sep 2018 11:19:55 -0400 Subject: vim-patch:8.0.1031: "text" argument for getqflist() is confusing Problem: "text" argument for getqflist() is confusing. (Lcd47) Solution: Use "lines" instead. (Yegappan Lakshmanan) https://github.com/vim/vim/commit/2c809b7c7d2bb5e4b7fd09c3d312cadecf0c1ff0 --- src/nvim/quickfix.c | 22 ++++++--------- src/nvim/testdir/test_quickfix.vim | 55 +++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index ec11e5d849..5b701695fd 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4122,15 +4122,12 @@ enum { }; // Parse text from 'di' and return the quickfix list items -static int qf_get_list_from_text(dictitem_T *di, dict_T *retdict) +static int qf_get_list_from_lines(dictitem_T *di, dict_T *retdict) { int status = FAIL; - // Only string and list values are supported - if ((di->di_tv.v_type == VAR_STRING - && di->di_tv.vval.v_string != NULL) - || (di->di_tv.v_type == VAR_LIST - && di->di_tv.vval.v_list != NULL)) { + // Only a List value is supported + if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { list_T *l = tv_list_alloc(kListLenMayKnow); qf_info_T *qi = xmalloc(sizeof(*qi)); memset(qi, 0, sizeof(*qi)); @@ -4158,8 +4155,8 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) qf_info_T *qi = &ql_info; dictitem_T *di; - if ((di = tv_dict_find(what, S_LEN("text"))) != NULL) { - return qf_get_list_from_text(di, retdict); + if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) { + return qf_get_list_from_lines(di, retdict); } if (wp != NULL) { @@ -4474,12 +4471,9 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action, } } - if ((di = tv_dict_find(what, S_LEN("text"))) != NULL) { - // Only string and list values are supported - if ((di->di_tv.v_type == VAR_STRING - && di->di_tv.vval.v_string != NULL) - || (di->di_tv.v_type == VAR_LIST - && di->di_tv.vval.v_list != NULL)) { + if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) { + // Only a List value is supported + if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { if (action == 'r') { qf_free_items(qi, qf_idx); } diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index c6324b1dc2..f1dc3d37be 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2281,25 +2281,26 @@ func Xsetexpr_tests(cchar) call s:setup_commands(a:cchar) let t = ["File1:10:Line10", "File1:20:Line20"] - call g:Xsetlist([], ' ', {'text' : t}) - call g:Xsetlist([], 'a', {'text' : "File1:30:Line30"}) + call g:Xsetlist([], ' ', {'lines' : t}) + call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) let l = g:Xgetlist() call assert_equal(3, len(l)) call assert_equal(20, l[1].lnum) call assert_equal('Line30', l[2].text) - call g:Xsetlist([], 'r', {'text' : "File2:5:Line5"}) + call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) let l = g:Xgetlist() call assert_equal(1, len(l)) call assert_equal('Line5', l[0].text) - call assert_equal(-1, g:Xsetlist([], 'a', {'text' : 10})) + call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) + call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) call g:Xsetlist([], 'f') " Add entries to multiple lists - call g:Xsetlist([], 'a', {'nr' : 1, 'text' : ["File1:10:Line10"]}) - call g:Xsetlist([], 'a', {'nr' : 2, 'text' : ["File2:20:Line20"]}) - call g:Xsetlist([], 'a', {'nr' : 1, 'text' : ["File1:15:Line15"]}) - call g:Xsetlist([], 'a', {'nr' : 2, 'text' : ["File2:25:Line25"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) endfunc @@ -2316,10 +2317,10 @@ func Xmultidirstack_tests(cchar) call g:Xsetlist([], 'f') Xexpr "" | Xexpr "" - call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "Entering dir 'Xone/a'"}) - call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "Entering dir 'Xtwo/a'"}) - call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "one.txt:3:one one one"}) - call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "two.txt:5:two two two"}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) let l1 = g:Xgetlist({'nr':1, 'items':1}) let l2 = g:Xgetlist({'nr':2, 'items':1}) @@ -2353,10 +2354,10 @@ func Xmultifilestack_tests(cchar) call g:Xsetlist([], 'f') Xexpr "" | Xexpr "" - call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "[one.txt]"}) - call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "[two.txt]"}) - call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "(3,5) one one one"}) - call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "(5,9) two two two"}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) let l1 = g:Xgetlist({'nr':1, 'items':1}) let l2 = g:Xgetlist({'nr':2, 'items':1}) @@ -2505,28 +2506,26 @@ endfunc " Test for getting the quickfix list items from some text without modifying " the quickfix stack -func XgetListFromText(cchar) +func XgetListFromLines(cchar) call s:setup_commands(a:cchar) call g:Xsetlist([], 'f') - let l = g:Xgetlist({'text' : "File1:10:Line10"}).items - call assert_equal(1, len(l)) - call assert_equal('Line10', l[0].text) - - let l = g:Xgetlist({'text' : ["File2:20:Line20", "File2:30:Line30"]}).items + let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items call assert_equal(2, len(l)) call assert_equal(30, l[1].lnum) - call assert_equal({}, g:Xgetlist({'text' : 10})) - call assert_equal([], g:Xgetlist({'text' : []}).items) + call assert_equal({}, g:Xgetlist({'lines' : 10})) + call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) + call assert_equal([], g:Xgetlist({'lines' : []}).items) + call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) " Make sure that the quickfix stack is not modified call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) endfunc -func Test_get_list_from_text() - call XgetListFromText('c') - call XgetListFromText('l') +func Test_get_list_from_lines() + call XgetListFromLines('c') + call XgetListFromLines('l') endfunc " Tests for the quickfix list id @@ -2549,7 +2548,7 @@ func Xqfid_tests(cchar) 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 g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['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'})) -- cgit From a8b996160d2749e4f4592ece92a1107521b1beb4 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 8 Sep 2018 11:31:55 -0400 Subject: lint --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 5b701695fd..9e415b31a1 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -117,7 +117,7 @@ struct qf_info_S { qf_list_T qf_lists[LISTCOUNT]; }; -static qf_info_T ql_info; /* global quickfix list */ +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 */ -- cgit From 3794e83d9881b2f3dd695b8a2f05a7d39980f43e Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 8 Sep 2018 11:37:59 -0400 Subject: vim-patch:8.0.1040: cannot use another error format in getqflist() Problem: Cannot use another error format in getqflist(). Solution: Add the "efm" argument to getqflist(). (Yegappan Lakshmanan) https://github.com/vim/vim/commit/3653822546fb0f1005c32bb5b70dc9bfacdfc954 --- src/nvim/quickfix.c | 28 ++++++++++++++++++++++++---- src/nvim/testdir/test_quickfix.vim | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 9e415b31a1..ba2f2ba969 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4122,18 +4122,30 @@ enum { }; // Parse text from 'di' and return the quickfix list items -static int qf_get_list_from_lines(dictitem_T *di, dict_T *retdict) +static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict) { int status = FAIL; + char_u *errorformat = p_efm; + dictitem_T *efm_di; // Only a List value is supported if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { + // If errorformat is supplied then use it, otherwise use the 'efm' + // option setting + if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) { + if (efm_di->di_tv.v_type != VAR_STRING + || efm_di->di_tv.vval.v_string == NULL) { + return FAIL; + } + errorformat = efm_di->di_tv.vval.v_string; + } + list_T *l = tv_list_alloc(kListLenMayKnow); qf_info_T *qi = xmalloc(sizeof(*qi)); memset(qi, 0, sizeof(*qi)); qi->qf_refcount++; - if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, p_efm, + if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { (void)get_errorlist(qi, NULL, 0, l); qf_free(qi, 0); @@ -4156,7 +4168,7 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) dictitem_T *di; if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) { - return qf_get_list_from_lines(di, retdict); + return qf_get_list_from_lines(what, di, retdict); } if (wp != NULL) { @@ -4390,6 +4402,7 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action, dictitem_T *di; int retval = FAIL; int newlist = false; + char_u *errorformat = p_efm; if (action == ' ' || qi->qf_curlist == qi->qf_listcount) { newlist = true; @@ -4471,13 +4484,20 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action, } } + if ((di = tv_dict_find(what, S_LEN("efm"))) != NULL) { + if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL) { + return FAIL; + } + errorformat = di->di_tv.vval.v_string; + } + if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) { // Only a List value is supported if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { if (action == 'r') { qf_free_items(qi, qf_idx); } - if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, p_efm, + if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat, false, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { retval = OK; } diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index f1dc3d37be..36be956b92 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2303,6 +2303,17 @@ func Xsetexpr_tests(cchar) call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) + + " Adding entries using a custom efm + set efm& + call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', + \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) + call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) + call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) + call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) + call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) + call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], + \ 'lines' : ['F1:10:L10']})) endfunc func Test_setexpr() @@ -2519,6 +2530,17 @@ func XgetListFromLines(cchar) call assert_equal([], g:Xgetlist({'lines' : []}).items) call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) + " Parse text using a custom efm + set efm& + let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items + call assert_equal('Line30', l[0].text) + let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items + call assert_equal('File3:30:Line30', l[0].text) + let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) + call assert_equal({}, l) + call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') + call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') + " Make sure that the quickfix stack is not modified call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) endfunc -- cgit From 40e894f59570a6192aabbe4fe34c456bd00ae871 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 8 Sep 2018 12:25:05 -0400 Subject: oldtests: win: fix buffer pathsep --- src/nvim/testdir/test_quickfix.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 36be956b92..7a53db7605 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2335,9 +2335,9 @@ func Xmultidirstack_tests(cchar) let l1 = g:Xgetlist({'nr':1, 'items':1}) let l2 = g:Xgetlist({'nr':2, 'items':1}) - call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) + call assert_equal(expand('Xone/a/one.txt'), bufname(l1.items[1].bufnr)) call assert_equal(3, l1.items[1].lnum) - call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) + call assert_equal(expand('Xtwo/a/two.txt'), bufname(l2.items[1].bufnr)) call assert_equal(5, l2.items[1].lnum) endfunc -- cgit