Patch 8.0.0657
Problem:    Cannot get and set quickfix list items.
Solution:   Add the "items" argument to getqflist() and setqflist(). (Yegappan
            Lakshmanan)
Files:      runtime/doc/eval.txt, src/quickfix.c,
            src/testdir/test_quickfix.vim


*** ../vim-8.0.0656/runtime/doc/eval.txt        2017-06-22 19:11:45.015344791 
+0200
--- runtime/doc/eval.txt        2017-06-22 21:22:46.076559393 +0200
***************
*** 4585,4590 ****
--- 4586,4592 ----
                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
***************
*** 4601,4606 ****
--- 4603,4609 ----
  
                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)
***************
*** 6994,6999 ****
--- 7000,7007 ----
                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
*** ../vim-8.0.0656/src/quickfix.c      2017-06-17 18:44:16.990001010 +0200
--- src/quickfix.c      2017-06-22 21:22:46.076559393 +0200
***************
*** 47,65 ****
   */
  #define LISTCOUNT   10
  
  typedef struct qf_list_S
  {
      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 */
!     int               qf_count;       /* number of errors (0 means no error 
list) */
      int               qf_index;       /* current index in the error list */
      int               qf_nonevalid;   /* TRUE if not a single valid entry 
found */
      char_u    *qf_title;      /* title derived from the command that created
!                                * the error list */
      typval_T  *qf_ctx;        /* context set by setqflist/setloclist */
  } qf_list_T;
  
  struct qf_info_S
  {
      /*
--- 47,78 ----
   */
  #define LISTCOUNT   10
  
+ /*
+  * Quickfix/Location list definition
+  * Contains a list of entries (qfline_T). qf_start points to the first entry
+  * and qf_last points to the last entry. qf_count contains the list size.
+  *
+  * Usually the list contains one or more entries. But an empty list can be
+  * 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
  {
      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 */
!     int               qf_count;       /* number of errors (0 means empty 
list) */
      int               qf_index;       /* current index in the error list */
      int               qf_nonevalid;   /* TRUE if not a single valid entry 
found */
      char_u    *qf_title;      /* title derived from the command that created
!                                * the error list or set by setqflist */
      typval_T  *qf_ctx;        /* context set by setqflist/setloclist */
  } qf_list_T;
  
+ /*
+  * Quickfix/Location list stack definition
+  * Contains a list of quickfix/location lists (qf_list_T)
+  */
  struct qf_info_S
  {
      /*
***************
*** 1347,1352 ****
--- 1360,1368 ----
      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);
***************
*** 2735,2744 ****
  }
  
  /*
!  * Free all the entries in the error list "idx".
   */
      static void
! qf_free(qf_info_T *qi, int idx)
  {
      qfline_T  *qfp;
      qfline_T  *qfpnext;
--- 2751,2761 ----
  }
  
  /*
!  * Free all the entries in the error list "idx". Note that other information
!  * associated with the list like context and title are not freed.
   */
      static void
! qf_free_items(qf_info_T *qi, int idx)
  {
      qfline_T  *qfp;
      qfline_T  *qfpnext;
***************
*** 2763,2772 ****
        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;
--- 2780,2786 ----
        qi->qf_lists[idx].qf_start = qfpnext;
        --qi->qf_lists[idx].qf_count;
      }
! 
      qi->qf_lists[idx].qf_index = 0;
      qi->qf_lists[idx].qf_start = NULL;
      qi->qf_lists[idx].qf_last = NULL;
***************
*** 2783,2788 ****
--- 2797,2817 ----
  }
  
  /*
+  * Free error list "idx". Frees all the entries in the quickfix list,
+  * associated context information and the title.
+  */
+     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,4710 ****
        } 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;
        }
        else
--- 4727,4737 ----
        } 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;
        }
        else
***************
*** 4724,4729 ****
--- 4751,4759 ----
  
        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,4748 ****
--- 4773,4787 ----
        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,4808 ****
  #endif
      else if (action == 'r')
      {
!       qf_free(qi, qf_idx);
        qf_store_title(qi, qf_idx, title);
      }
  
--- 4841,4847 ----
  #endif
      else if (action == 'r')
      {
!       qf_free_items(qi, qf_idx);
        qf_store_title(qi, qf_idx, title);
      }
  
***************
*** 4915,4929 ****
            /* 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)
                return FAIL;
        } 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;
        else
            return FAIL;
-       newlist = FALSE;        /* use the specified list */
      }
  
      if (newlist)
--- 4954,4980 ----
            /* for zero use the current list */
            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)
!               /*
!                * 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;
      }
  
      if (newlist)
***************
*** 4944,4949 ****
--- 4995,5011 ----
            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)
      {
*** ../vim-8.0.0656/src/testdir/test_quickfix.vim       2017-06-11 
16:07:20.702719866 +0200
--- src/testdir/test_quickfix.vim       2017-06-22 21:22:46.076559393 +0200
***************
*** 1835,1840 ****
--- 1835,1907 ----
      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()
*** ../vim-8.0.0656/src/version.c       2017-06-22 20:39:13.393435240 +0200
--- src/version.c       2017-06-22 21:28:33.985747647 +0200
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     657,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
61. Your best friends know your e-mail address, but neither your phone number
    nor the address where you live.

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
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.

Raspunde prin e-mail lui