]> granicus.if.org Git - vim/commitdiff
patch 8.0.0922: quickfix list always added after current one v8.0.0922
authorBram Moolenaar <Bram@vim.org>
Sun, 13 Aug 2017 11:42:01 +0000 (13:42 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 13 Aug 2017 11:42:01 +0000 (13:42 +0200)
Problem:    Quickfix list always added after current one.
Solution:   Make it possible to add a quickfix list after the last one.
            (Yegappan Lakshmanan)

runtime/doc/eval.txt
src/quickfix.c
src/testdir/test_quickfix.vim
src/version.c

index de142ee8024e8c7f2361a25e08c737d0c0d9deae..35e5670939032ef48ba5cdab23ccdf5d85537ceb 100644 (file)
@@ -7023,7 +7023,10 @@ setqflist({list} [, {action}[, {what}]])         *setqflist()*
                        freed.
 
                If {action} is not present or is set to ' ', then a new list
-               is created.
+               is created. The new quickfix list is added after the current
+               quickfix list in the stack and all the following lists are
+               freed. To add a new quickfix list at the end of the stack,
+               set "nr" in {what} to '$'.
 
                If the optional {what} dictionary argument is supplied, then
                only the items listed in {what} are set. The first {list}
index 75b58af3b704f94fea9b5c6899d1ece1aae371cc..8c55a16c7f59eb1f2c0b6e077af51f9b70e792ae 100644 (file)
@@ -1189,8 +1189,7 @@ qf_init_ext(
     fields.errmsglen = CMDBUFFSIZE + 1;
     fields.errmsg = alloc_id(fields.errmsglen, aid_qf_errmsg);
     fields.pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern);
-    if (fields.namebuf == NULL || fields.errmsg == NULL ||
-           fields.pattern == NULL)
+    if (fields.namebuf == NULL || fields.errmsg == NULL || fields.pattern == NULL)
        goto qf_init_end;
 
     if (efile != NULL && (state.fd = mch_fopen((char *)efile, "r")) == NULL)
@@ -1368,7 +1367,9 @@ qf_store_title(qf_info_T *qi, int qf_idx, char_u *title)
 }
 
 /*
- * Prepare for adding a new quickfix list.
+ * Prepare for adding a new quickfix list. If the current list is in the
+ * middle of the stack, then all the following lists are freed and then
+ * the new list is added.
  */
     static void
 qf_new_list(qf_info_T *qi, char_u *qf_title)
@@ -3830,8 +3831,8 @@ ex_cc(exarg_T *eap)
     /* For cdo and ldo commands, jump to the nth valid error.
      * For cfdo and lfdo commands, jump to the nth valid file entry.
      */
-    if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo ||
-           eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
+    if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
+           || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
        errornr = qf_get_nth_valid_entry(qi,
                eap->addr_count > 0 ? (int)eap->line1 : 1,
                eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo);
@@ -3867,9 +3868,9 @@ ex_cnext(exarg_T *eap)
        }
     }
 
-    if (eap->addr_count > 0 &&
-           (eap->cmdidx != CMD_cdo && eap->cmdidx != CMD_ldo &&
-            eap->cmdidx != CMD_cfdo && eap->cmdidx != CMD_lfdo))
+    if (eap->addr_count > 0
+           && (eap->cmdidx != CMD_cdo && eap->cmdidx != CMD_ldo
+               && eap->cmdidx != CMD_cfdo && eap->cmdidx != CMD_lfdo))
        errornr = (int)eap->line2;
     else
        errornr = 1;
@@ -4086,8 +4087,8 @@ ex_vimgrep(exarg_T *eap)
        goto theend;
     }
 
-    if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd &&
-        eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
+    if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd
+               && eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
                                        || qi->qf_curlist == qi->qf_listcount)
        /* make place for a new list */
        qf_new_list(qi, title != NULL ? title : *eap->cmdlinep);
@@ -4646,10 +4647,10 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
        if (qi == NULL)
        {
            /* If querying for the size of the location list, return 0 */
-           if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL) &&
-                   (di->di_tv.v_type == VAR_STRING) &&
-                   (STRCMP(di->di_tv.vval.v_string, "$") == 0))
-                   return dict_add_nr_str(retdict, "nr", 0, NULL);
+           if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
+                   && (di->di_tv.v_type == VAR_STRING)
+                   && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
+               return dict_add_nr_str(retdict, "nr", 0, NULL);
            return FAIL;
        }
     }
@@ -4666,11 +4667,13 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
                qf_idx = di->di_tv.vval.v_number - 1;
                if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
                    return FAIL;
-           } else if (qi->qf_listcount == 0)       /* stack is empty */
+           }
+           else if (qi->qf_listcount == 0)         /* stack is empty */
                return FAIL;
            flags |= QF_GETLIST_NR;
-       } else if ((di->di_tv.v_type == VAR_STRING) &&
-               (STRCMP(di->di_tv.vval.v_string, "$") == 0))
+       }
+       else if ((di->di_tv.v_type == VAR_STRING)
+               && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
        {
            /* Get the last quickfix list number */
            if (qi->qf_listcount > 0)
@@ -4905,23 +4908,30 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
            if (di->di_tv.vval.v_number != 0)
                qf_idx = di->di_tv.vval.v_number - 1;
 
-           if ((action == ' ' || action == 'a') &&
-                   qf_idx == qi->qf_listcount)
+           if ((action == ' ' || action == 'a') && qf_idx == qi->qf_listcount)
+           {
                /*
                 * When creating a new list, accept qf_idx pointing to the next
-                * non-available list
+                * non-available list and add the new list at the end of the
+                * stack.
                 */
                newlist = TRUE;
+               qf_idx = qi->qf_listcount - 1;
+           }
            else if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
                return FAIL;
-           else
+           else if (action != ' ')
                newlist = FALSE;        /* use the specified list */
-       } else if (di->di_tv.v_type == VAR_STRING &&
-               STRCMP(di->di_tv.vval.v_string, "$") == 0 &&
-               qi->qf_listcount > 0)
+       }
+       else if (di->di_tv.v_type == VAR_STRING
+               && STRCMP(di->di_tv.vval.v_string, "$") == 0)
        {
-           qf_idx = qi->qf_listcount - 1;
-           newlist = FALSE;
+           if (qi->qf_listcount > 0)
+               qf_idx = qi->qf_listcount - 1;
+           else if (newlist)
+               qf_idx = 0;
+           else
+               return FAIL;
        }
        else
            return FAIL;
@@ -4929,6 +4939,7 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
 
     if (newlist)
     {
+       qi->qf_curlist = qf_idx;
        qf_new_list(qi, title);
        qf_idx = qi->qf_curlist;
     }
@@ -5104,8 +5115,8 @@ mark_quickfix_ctx(qf_info_T *qi, int copyID)
     for (i = 0; i < LISTCOUNT && !abort; ++i)
     {
        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)
+       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);
     }
 
index 3acbd12dffb78750df6b550ae4ced9557558d5e5..8fa715395ce36cadf45cd0ff18d09da77fd1982f 100644 (file)
@@ -11,7 +11,7 @@ func s:setup_commands(cchar)
     command! -nargs=* -bang Xlist <mods>clist<bang> <args>
     command! -nargs=* Xgetexpr <mods>cgetexpr <args>
     command! -nargs=* Xaddexpr <mods>caddexpr <args>
-    command! -nargs=* Xolder <mods>colder <args>
+    command! -nargs=* -count Xolder <mods><count>colder <args>
     command! -nargs=* Xnewer <mods>cnewer <args>
     command! -nargs=* Xopen <mods>copen <args>
     command! -nargs=* Xwindow <mods>cwindow <args>
@@ -43,7 +43,7 @@ func s:setup_commands(cchar)
     command! -nargs=* -bang Xlist <mods>llist<bang> <args>
     command! -nargs=* Xgetexpr <mods>lgetexpr <args>
     command! -nargs=* Xaddexpr <mods>laddexpr <args>
-    command! -nargs=* Xolder <mods>lolder <args>
+    command! -nargs=* -count Xolder <mods><count>lolder <args>
     command! -nargs=* Xnewer <mods>lnewer <args>
     command! -nargs=* Xopen <mods>lopen <args>
     command! -nargs=* Xwindow <mods>lwindow <args>
@@ -1745,7 +1745,7 @@ func Xproperty_tests(cchar)
     call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
 
     " Changing the title of an earlier quickfix list
-    call g:Xsetlist([], ' ', {'title' : 'NewTitle', 'nr' : 2})
+    call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
     call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
 
     " Changing the title of an invalid quickfix list
@@ -1812,10 +1812,10 @@ func Xproperty_tests(cchar)
     Xexpr "One"
     Xexpr "Two"
     Xexpr "Three"
-    call g:Xsetlist([], ' ', {'context' : [1], 'nr' : 1})
-    call g:Xsetlist([], ' ', {'context' : [2], 'nr' : 2})
+    call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
+    call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
     " Also, check for setting the context using quickfix list number zero.
-    call g:Xsetlist([], ' ', {'context' : [3], 'nr' : 0})
+    call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
     call test_garbagecollect_now()
     let l = g:Xgetlist({'nr' : 1, 'context' : 1})
     call assert_equal([1], l.context)
@@ -2433,3 +2433,89 @@ func Test_Multi_LL_Help()
     call assert_true(len(getloclist(2)) != 0)
     new | only
 endfunc
+
+" Tests for adding new quickfix lists using setqflist()
+func XaddQf_tests(cchar)
+  call s:setup_commands(a:cchar)
+
+  " Create a new list using ' ' for action
+  call g:Xsetlist([], 'f')
+  call g:Xsetlist([], ' ', {'title' : 'Test1'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(1, l.nr)
+  call assert_equal('Test1', l.title)
+
+  " Create a new list using ' ' for action and '$' for 'nr'
+  call g:Xsetlist([], 'f')
+  call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(1, l.nr)
+  call assert_equal('Test2', l.title)
+
+  " Create a new list using 'a' for action
+  call g:Xsetlist([], 'f')
+  call g:Xsetlist([], 'a', {'title' : 'Test3'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(1, l.nr)
+  call assert_equal('Test3', l.title)
+
+  " Create a new list using 'a' for action and '$' for 'nr'
+  call g:Xsetlist([], 'f')
+  call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
+  call g:Xsetlist([], 'a', {'title' : 'Test4'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(1, l.nr)
+  call assert_equal('Test4', l.title)
+
+  " Adding a quickfix list should remove all the lists following the current
+  " list.
+  Xexpr "" | Xexpr "" | Xexpr ""
+  silent! 10Xolder
+  call g:Xsetlist([], ' ', {'title' : 'Test5'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(2, l.nr)
+  call assert_equal('Test5', l.title)
+
+  " Add a quickfix list using '$' as the list number.
+  let lastqf = g:Xgetlist({'nr':'$'}).nr
+  silent! 99Xolder
+  call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(lastqf + 1, l.nr)
+  call assert_equal('Test6', l.title)
+
+  " Add a quickfix list using 'nr' set to one more than the quickfix
+  " list size.
+  let lastqf = g:Xgetlist({'nr':'$'}).nr
+  silent! 99Xolder
+  call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(lastqf + 1, l.nr)
+  call assert_equal('Test7', l.title)
+
+  " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
+  exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
+  silent! 99Xolder
+  call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
+  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+  call assert_equal(10, l.nr)
+  call assert_equal('Test8', l.title)
+
+  " Add a quickfix list using 'nr' set to a value greater than 10
+  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
+
+  " Try adding a quickfix list with 'nr' set to a value greater than the
+  " quickfix list size but less than 10.
+  call g:Xsetlist([], 'f')
+  Xexpr "" | Xexpr "" | Xexpr ""
+  silent! 99Xolder
+  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
+
+  " Add a quickfix list using 'nr' set to a some string or list
+  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
+endfunc
+
+func Test_add_qf()
+  call XaddQf_tests('c')
+  call XaddQf_tests('l')
+endfunc
index 72cd083dd92e25d10436faac9fcc132c06ed670e..2200bf091a6e3265be6283117193af16f888fd97 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    922,
 /**/
     921,
 /**/