]> granicus.if.org Git - vim/commitdiff
patch 8.0.1023: it is not easy to identify a quickfix list v8.0.1023
authorBram Moolenaar <Bram@vim.org>
Wed, 30 Aug 2017 18:33:55 +0000 (20:33 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 30 Aug 2017 18:33:55 +0000 (20:33 +0200)
Problem:    It is not easy to identify a quickfix list.
Solution:   Add the "id" field. (Yegappan Lakshmanan)

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

index a75d4f680f7ad7dd9f5b18840d833a548237b8b6..ecb41c4b81519d8715e21241ea5521e0b472b693 100644 (file)
@@ -4632,6 +4632,9 @@ getqflist([{what}])                                       *getqflist()*
                returns only the items listed in {what} as a dictionary. The
                following string items are supported in {what}:
                        context get the context stored with |setqflist()|
+                       id      get information for the quickfix list with
+                               |quickfix-ID|; zero means the id for the
+                               current list or the list specifed by 'nr'
                        items   quickfix list entries
                        nr      get information for this quickfix list; zero
                                means the current quickfix list and '$' means
@@ -4646,6 +4649,8 @@ getqflist([{what}])                                       *getqflist()*
                        all     all of the above quickfix properties
                Non-string items in {what} are ignored.
                If "nr" is not present then the current quickfix list is used.
+               If both "nr" and a non-zero "id" are specified, then the list
+               specified by "id" is used.
                To get the number of lists in the quickfix stack, set 'nr' to
                '$' in {what}. The 'nr' value in the returned dictionary
                contains the quickfix stack size.
@@ -4657,6 +4662,7 @@ getqflist([{what}])                                       *getqflist()*
 
                The returned dictionary contains the following entries:
                        context context information stored with |setqflist()|
+                       id      quickfix list ID |quickfix-ID|
                        items   quickfix list entries
                        nr      quickfix list number
                        title   quickfix list title text
@@ -7069,6 +7075,7 @@ setqflist({list} [, {action}[, {what}]])          *setqflist()*
                                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.
+                   id          quickfix list identifier |quickfix-ID|
                    items       list of quickfix entries. Same as the {list}
                                argument.
                    nr          list number in the quickfix stack; zero
@@ -7079,6 +7086,9 @@ setqflist({list} [, {action}[, {what}]])          *setqflist()*
                If the "nr" item is not present, then the current quickfix list
                is modified. When creating a new quickfix list, "nr" can be
                set to a value one greater than the quickfix stack size.
+               When modifying a quickfix list, to guarantee that the correct
+               list is modified, 'id' should be used instead of 'nr' to
+               specify the list.
 
                Examples: >
                        :call setqflist([], 'r', {'title': 'My search'})
index 71270d9b9712a24911925dde05f7f9af9911f440..8277b937e9eccf9c379221a456bfc9ea3af04c55 100644 (file)
@@ -58,6 +58,7 @@ struct qfline_S
  */
 typedef struct qf_list_S
 {
+    int_u      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 */
@@ -96,6 +97,7 @@ struct qf_info_S
 };
 
 static qf_info_T ql_info;      /* global quickfix list */
+static int_u last_qf_id = 0;   /* Last used quickfix list id */
 
 #define FMT_PATTERNS 10                /* maximum number of % recognized */
 
@@ -1399,6 +1401,7 @@ qf_new_list(qf_info_T *qi, char_u *qf_title)
        qi->qf_curlist = qi->qf_listcount++;
     vim_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;
 }
 
 /*
@@ -1672,6 +1675,9 @@ 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)
@@ -2808,6 +2814,7 @@ qf_free(qf_info_T *qi, int idx)
     qfl->qf_title = NULL;
     free_tv(qfl->qf_ctx);
     qfl->qf_ctx = NULL;
+    qfl->qf_id = 0;
 }
 
 /*
@@ -4628,6 +4635,7 @@ enum {
     QF_GETLIST_NR      = 0x4,
     QF_GETLIST_WINID   = 0x8,
     QF_GETLIST_CONTEXT = 0x10,
+    QF_GETLIST_ID      = 0x20,
     QF_GETLIST_ALL     = 0xFF
 };
 
@@ -4688,17 +4696,17 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
        return qf_get_list_from_text(di, 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 = 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;
-       }
+
+    /* 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 = 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;
     }
 
     qf_idx = qi->qf_curlist;           /* default is the current list */
@@ -4714,41 +4722,52 @@ 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)
                && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
-       {
            /* 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 ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
     {
-       if (dict_find(what, (char_u *)"all", -1) != NULL)
-           flags |= QF_GETLIST_ALL;
+       /* 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 (dict_find(what, (char_u *)"title", -1) != NULL)
-           flags |= QF_GETLIST_TITLE;
+    if (dict_find(what, (char_u *)"all", -1) != NULL)
+       flags |= QF_GETLIST_ALL;
 
-       if (dict_find(what, (char_u *)"winid", -1) != NULL)
-           flags |= QF_GETLIST_WINID;
+    if (dict_find(what, (char_u *)"title", -1) != NULL)
+       flags |= QF_GETLIST_TITLE;
 
-       if (dict_find(what, (char_u *)"context", -1) != NULL)
-           flags |= QF_GETLIST_CONTEXT;
+    if (dict_find(what, (char_u *)"winid", -1) != NULL)
+       flags |= QF_GETLIST_WINID;
 
-       if (dict_find(what, (char_u *)"items", -1) != NULL)
-           flags |= QF_GETLIST_ITEMS;
-    }
+    if (dict_find(what, (char_u *)"context", -1) != NULL)
+       flags |= QF_GETLIST_CONTEXT;
+
+    if (dict_find(what, (char_u *)"items", -1) != NULL)
+       flags |= QF_GETLIST_ITEMS;
 
     if (flags & QF_GETLIST_TITLE)
     {
@@ -4798,6 +4817,10 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
            status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
     }
 
+    if ((status == OK) && (flags & QF_GETLIST_ID))
+       status = dict_add_nr_str(retdict, "id", qi->qf_lists[qf_idx].qf_id,
+                                                                        NULL);
+
     return status;
 }
 
@@ -4983,6 +5006,21 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
            return FAIL;
     }
 
+    if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != 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;
index 32b04c34e95a1973d02c03ac35ca7314cc482a70..076d583fd02df82d503efeccf8063d9c01dcd0e8 100644 (file)
@@ -1897,8 +1897,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})
@@ -2545,3 +2546,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
index 1b69d2b0c032024b47b2f2e69a3f16c175f5335f..4078912749fb915fe43c49bfca63b79e0dc856b4 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1023,
 /**/
     1022,
 /**/