To: vim_dev@googlegroups.com Subject: Patch 8.0.0904 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0904 Problem: Cannot set a location list from text. Solution: Add the "text" argument to setqflist(). (Yegappan Lakshmanan) Files: runtime/doc/eval.txt, src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.0.0903/runtime/doc/eval.txt 2017-08-11 16:24:46.320283867 +0200 --- runtime/doc/eval.txt 2017-08-11 20:07:27.485252468 +0200 *************** *** 6973,6982 **** |winrestview()|. setqflist({list} [, {action}[, {what}]]) *setqflist()* ! Create or replace or add to the quickfix list using the items ! in {list}. Each item in {list} is a dictionary. ! Non-dictionary items in {list} are ignored. Each dictionary ! item can contain the following entries: bufnr buffer number; must be the number of a valid buffer --- 6973,6984 ---- |winrestview()|. setqflist({list} [, {action}[, {what}]]) *setqflist()* ! Create or replace or add to the quickfix list. ! ! When {what} is not present, use the items in {list}. Each ! item must be a dictionary. Non-dictionary items in {list} are ! ignored. Each dictionary item can contain the following ! entries: bufnr buffer number; must be the number of a valid buffer *************** *** 7028,7033 **** --- 7030,7039 ---- argument is ignored. The following items can be specified in {what}: context any Vim type can be stored as a context + text use 'errorformat' to extract items from the + text and add the resulting entries to the + quickfix list {nr}. The value can be a string + with one line or a list with multiple lines. items list of quickfix entries. Same as the {list} argument. nr list number in the quickfix stack; zero *** ../vim-8.0.0903/src/quickfix.c 2017-07-27 22:03:45.550703059 +0200 --- src/quickfix.c 2017-08-11 20:10:10.820097310 +0200 *************** *** 4885,4891 **** } static int ! qf_set_properties(qf_info_T *qi, dict_T *what, int action) { dictitem_T *di; int retval = FAIL; --- 4885,4891 ---- } static int ! qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) { dictitem_T *di; int retval = FAIL; *************** *** 4929,4935 **** if (newlist) { ! qf_new_list(qi, NULL); qf_idx = qi->qf_curlist; } --- 4929,4935 ---- if (newlist) { ! qf_new_list(qi, title); qf_idx = qi->qf_curlist; } *************** *** 4957,4962 **** --- 4957,4979 ---- } } + if ((di = dict_find(what, (char_u *)"text", -1)) != 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 (action == 'r') + qf_free_items(qi, qf_idx); + if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, p_efm, + FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) + retval = OK; + } + else + return FAIL; + } + if ((di = dict_find(what, (char_u *)"context", -1)) != NULL) { typval_T *ctx; *************** *** 5070,5076 **** qf_free_stack(wp, qi); } else if (what != NULL) ! retval = qf_set_properties(qi, what, action); else retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); --- 5087,5093 ---- qf_free_stack(wp, qi); } else if (what != NULL) ! retval = qf_set_properties(qi, what, action, title); else retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); *** ../vim-8.0.0903/src/testdir/test_quickfix.vim 2017-07-27 22:03:45.550703059 +0200 --- src/testdir/test_quickfix.vim 2017-08-11 20:11:19.535611302 +0200 *************** *** 1862,1867 **** --- 1862,1872 ---- let l = g:Xgetlist({'items':1}) call assert_equal(0, len(l.items)) + " The following used to crash Vim with address sanitizer + call g:Xsetlist([], 'f') + call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) + call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) + " Save and restore the quickfix stack call g:Xsetlist([], 'f') call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) *************** *** 2284,2291 **** endfunc func Test_changedtick() ! call Xchangedtick_tests('c') ! call Xchangedtick_tests('l') endfunc " Open multiple help windows using ":lhelpgrep --- 2289,2423 ---- endfunc func Test_changedtick() ! call Xchangedtick_tests('c') ! call Xchangedtick_tests('l') ! endfunc ! ! " Tests for parsing an expression using setqflist() ! 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"}) ! ! 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"}) ! 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 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 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 ! ! func Test_setexpr() ! call Xsetexpr_tests('c') ! call Xsetexpr_tests('l') ! endfunc ! ! " Tests for per quickfix/location list directory stack ! func Xmultidirstack_tests(cchar) ! call s:setup_commands(a: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"}) ! ! 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(3, l1.items[1].lnum) ! call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) ! call assert_equal(5, l2.items[1].lnum) ! endfunc ! ! func Test_multidirstack() ! call mkdir('Xone/a', 'p') ! call mkdir('Xtwo/a', 'p') ! let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] ! call writefile(lines, 'Xone/a/one.txt') ! call writefile(lines, 'Xtwo/a/two.txt') ! let save_efm = &efm ! set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' ! ! call Xmultidirstack_tests('c') ! call Xmultidirstack_tests('l') ! ! let &efm = save_efm ! call delete('Xone', 'rf') ! call delete('Xtwo', 'rf') ! endfunc ! ! " Tests for per quickfix/location list file stack ! func Xmultifilestack_tests(cchar) ! call s:setup_commands(a: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"}) ! ! let l1 = g:Xgetlist({'nr':1, 'items':1}) ! let l2 = g:Xgetlist({'nr':2, 'items':1}) ! call assert_equal('one.txt', bufname(l1.items[1].bufnr)) ! call assert_equal(3, l1.items[1].lnum) ! call assert_equal('two.txt', bufname(l2.items[1].bufnr)) ! call assert_equal(5, l2.items[1].lnum) ! endfunc ! ! func Test_multifilestack() ! let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] ! call writefile(lines, 'one.txt') ! call writefile(lines, 'two.txt') ! let save_efm = &efm ! set efm=%+P[%f],(%l\\,%c)\ %m,%-Q ! ! call Xmultifilestack_tests('c') ! call Xmultifilestack_tests('l') ! ! let &efm = save_efm ! call delete('one.txt') ! call delete('two.txt') ! endfunc ! ! " Tests for per buffer 'efm' setting ! func Test_perbuf_efm() ! call writefile(["File1-10-Line10"], 'one.txt') ! call writefile(["File2#20#Line20"], 'two.txt') ! set efm=%f#%l#%m ! new | only ! new ! setlocal efm=%f-%l-%m ! cfile one.txt ! wincmd w ! caddfile two.txt ! ! let l = getqflist() ! call assert_equal(10, l[0].lnum) ! call assert_equal('Line20', l[1].text) ! ! set efm& ! new | only ! call delete('one.txt') ! call delete('two.txt') endfunc " Open multiple help windows using ":lhelpgrep *** ../vim-8.0.0903/src/version.c 2017-08-11 20:20:23.863723207 +0200 --- src/version.c 2017-08-11 20:24:16.654038635 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 904, /**/ -- Kisses may last for as much as, but no more than, five minutes. [real standing law in Iowa, United States of America] /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///