Hi all,

I am attaching a patch to get and set the quickfix list items using the
getqflist() and setqflist() functions. After this patch, it will be easier
to save and restore any quickfix list in the quickfix stack.

This will also make it consistent to get or set any attributes (title,
context, items) of the quickfix list using the getqflist() and setqflist()
functions.

- Yegappan

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 701fd3985..0ddde0bd1 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4586,6 +4586,7 @@ 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()|
+                       items   quickfix list entries
                        nr      get information for this quickfix list; zero
                                means the current quickfix list and '$' means
                                the last quickfix list
@@ -4602,6 +4603,7 @@ getqflist([{what}])                                       
*getqflist()*
 
                The returned dictionary contains the following entries:
                        context context information stored with |setqflist()|
+                       items   quickfix list entries
                        nr      quickfix list number
                        title   quickfix list title text
                        winid   quickfix |window-ID| (if opened)
@@ -6995,6 +6997,8 @@ setqflist({list} [, {action}[, {what}]])          
*setqflist()*
                argument is ignored.  The following items can be specified in
                {what}:
                    context     any Vim type can be stored as a context
+                   items       list of quickfix entries. Same as the {list}
+                               argument.
                    nr          list number in the quickfix stack; zero
                                means the current quickfix list and '$' means
                                the last quickfix list
diff --git a/src/quickfix.c b/src/quickfix.c
index 8b61e10bc..f4d6cfb9c 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1347,6 +1347,9 @@ qf_init_end:
     static void
 qf_store_title(qf_info_T *qi, int qf_idx, char_u *title)
 {
+    vim_free(qi->qf_lists[qf_idx].qf_title);
+    qi->qf_lists[qf_idx].qf_title = NULL;
+
     if (title != NULL)
     {
        char_u *p = alloc((int)STRLEN(title) + 2);
@@ -2738,7 +2741,7 @@ qf_history(exarg_T *eap)
  * Free all the entries in the error list "idx".
  */
     static void
-qf_free(qf_info_T *qi, int idx)
+qf_free_items(qf_info_T *qi, int idx)
 {
     qfline_T   *qfp;
     qfline_T   *qfpnext;
@@ -2763,10 +2766,7 @@ qf_free(qf_info_T *qi, int idx)
        qi->qf_lists[idx].qf_start = qfpnext;
        --qi->qf_lists[idx].qf_count;
     }
-    vim_free(qi->qf_lists[idx].qf_title);
-    qi->qf_lists[idx].qf_title = NULL;
-    free_tv(qi->qf_lists[idx].qf_ctx);
-    qi->qf_lists[idx].qf_ctx = NULL;
+
     qi->qf_lists[idx].qf_index = 0;
     qi->qf_lists[idx].qf_start = NULL;
     qi->qf_lists[idx].qf_last = NULL;
@@ -2783,6 +2783,20 @@ qf_free(qf_info_T *qi, int idx)
 }
 
 /*
+ * Free error list "idx".
+ */
+    static void
+qf_free(qf_info_T *qi, int idx)
+{
+    qf_free_items(qi, idx);
+
+    vim_free(qi->qf_lists[idx].qf_title);
+    qi->qf_lists[idx].qf_title = NULL;
+    free_tv(qi->qf_lists[idx].qf_ctx);
+    qi->qf_lists[idx].qf_ctx = NULL;
+}
+
+/*
  * qf_mark_adjust: adjust marks
  */
    void
@@ -4698,13 +4712,11 @@ get_errorlist_properties(win_T *wp, dict_T *what, 
dict_T *retdict)
        } 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 */
-           }
+           /* 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;
        }
        else
@@ -4724,6 +4736,9 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T 
*retdict)
 
        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)
@@ -4743,6 +4758,15 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T 
*retdict)
        if (win != NULL)
            status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
     }
+    if ((status == OK) && (flags & QF_GETLIST_ITEMS))
+    {
+       list_T  *l = list_alloc();
+       if (l != NULL)
+       {
+           (void)get_errorlist(wp, qf_idx, l);
+           dict_add_list(retdict, "items", l);
+       }
+    }
 
     if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
     {
@@ -4802,7 +4826,7 @@ qf_add_entries(
 #endif
     else if (action == 'r')
     {
-       qf_free(qi, qf_idx);
+       qf_free_items(qi, qf_idx);
        qf_store_title(qi, qf_idx, title);
     }
 
@@ -4915,15 +4939,27 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int 
action)
            /* for zero use the current list */
            if (di->di_tv.vval.v_number != 0)
                qf_idx = di->di_tv.vval.v_number - 1;
-           if (qf_idx < 0 || 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
+                */
+               newlist = TRUE;
+           else if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
                return FAIL;
+           else
+               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)
+       {
            qf_idx = qi->qf_listcount - 1;
+           newlist = FALSE;
+       }
        else
            return FAIL;
-       newlist = FALSE;        /* use the specified list */
     }
 
     if (newlist)
@@ -4944,6 +4980,17 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int 
action)
            retval = OK;
        }
     }
+    if ((di = dict_find(what, (char_u *)"items", -1)) != NULL)
+    {
+       if (di->di_tv.v_type == VAR_LIST)
+       {
+           char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
+
+           retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
+                   title_save, action == ' ' ? 'a' : action);
+           vim_free(title_save);
+       }
+    }
 
     if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
     {
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 16187be76..c23e597e3 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -1835,6 +1835,73 @@ func Xproperty_tests(cchar)
     call test_garbagecollect_now()
     let m = g:Xgetlist({'context' : 1})
     call assert_equal(["red", "blue", "green"], m.context)
+
+    " Test for setting/getting items
+    Xexpr ""
+    let qfprev = g:Xgetlist({'nr':0})
+    call g:Xsetlist([], ' ', {'title':'Green',
+               \ 'items' : [{'filename':'F1', 'lnum':10}]})
+    let qfcur = g:Xgetlist({'nr':0})
+    call assert_true(qfcur.nr == qfprev.nr + 1)
+    let l = g:Xgetlist({'items':1})
+    call assert_equal('F1', bufname(l.items[0].bufnr))
+    call assert_equal(10, l.items[0].lnum)
+    call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
+               \  {'filename':'F2', 'lnum':30}]})
+    let l = g:Xgetlist({'items':1})
+    call assert_equal('F2', bufname(l.items[2].bufnr))
+    call assert_equal(30, l.items[2].lnum)
+    call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
+    let l = g:Xgetlist({'items':1})
+    call assert_equal('F3', bufname(l.items[0].bufnr))
+    call assert_equal(40, l.items[0].lnum)
+    call g:Xsetlist([], 'r', {'items' : []})
+    let l = g:Xgetlist({'items':1})
+    call assert_equal(0, len(l.items))
+
+    " Save and restore the quickfix stack
+    call g:Xsetlist([], 'f')
+    call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
+    Xexpr "File1:10:Line1"
+    Xexpr "File2:20:Line2"
+    Xexpr "File3:30:Line3"
+    let last_qf = g:Xgetlist({'nr':'$'}).nr
+    call assert_equal(3, last_qf)
+    let qstack = []
+    for i in range(1, last_qf)
+       let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
+    endfor
+    call g:Xsetlist([], 'f')
+    for i in range(len(qstack))
+       call g:Xsetlist([], ' ', qstack[i])
+    endfor
+    call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
+    call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
+    call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
+    call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
+    call g:Xsetlist([], 'f')
+
+    " Swap two quickfix lists
+    Xexpr "File1:10:Line10"
+    Xexpr "File2:20:Line20"
+    Xexpr "File3:30:Line30"
+    call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
+    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
+    call g:Xsetlist([], 'r', l1)
+    call g:Xsetlist([], 'r', l2)
+    let newl1=g:Xgetlist({'nr':1,'all':1})
+    let newl2=g:Xgetlist({'nr':2,'all':1})
+    call assert_equal(':Fruits', newl1.title)
+    call assert_equal(['Fruits'], newl1.context)
+    call assert_equal('Line20', newl1.items[0].text)
+    call assert_equal(':Colors', newl2.title)
+    call assert_equal(['Colors'], newl2.context)
+    call assert_equal('Line10', newl2.items[0].text)
+    call g:Xsetlist([], 'f')
 endfunc
 
 func Test_qf_property()

Raspunde prin e-mail lui