Hi all,

I am attaching a patch to add support for storing context (any Vim type)
information with a quickfix/location list. The context information is stored
using the setqflist/setloclist functions and retrieved using the
getqflist/getloclist 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 69fa6e8..c9673a6 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4472,6 +4472,7 @@ getqflist([{what}])                                       
*getqflist()*
                If the optional {what} dictionary argument is supplied, then
                returns only the items listed in {what} as a dictionary. The
                following string items are supported in {what}:
+                       context get the context stored using setqflist
                        nr      get information for this quickfix list
                        title   get the list title
                        winid   get the |window-ID| (if opened)
@@ -4482,6 +4483,7 @@ getqflist([{what}])                                       
*getqflist()*
                returned.
 
                The returned dictionary contains the following entries:
+                       context context information stored using setqflist
                        nr      quickfix list number
                        title   quickfix list title text
                        winid   quickfix |window-ID| (if opened)
@@ -6789,6 +6791,7 @@ setqflist({list} [, {action}[, {what}]])          
*setqflist()*
                only the items listed in {what} are set. The first {list}
                argument is ignored.  The following items can be specified in
                {what}:
+                   context     any vim type can be stored as a context
                    nr          list number in the quickfix stack
                    title       quickfix list title text
                Unsupported keys in {what} are ignored.
diff --git a/src/eval.c b/src/eval.c
index cbfd98f..de86cdc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5340,6 +5340,10 @@ garbage_collect(int testing)
     abort = abort || set_ref_in_timer(copyID);
 #endif
 
+#ifdef FEAT_QUICKFIX
+    abort = abort || set_ref_in_quickfix(copyID);
+#endif
+
     if (!abort)
     {
        /*
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
index d48eb25..137ed74 100644
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -29,6 +29,7 @@ void ex_vimgrep(exarg_T *eap);
 int get_errorlist(win_T *wp, int qf_idx, list_T *list);
 int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict);
 int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T 
*what);
+int set_ref_in_quickfix(int copyID);
 void ex_cbuffer(exarg_T *eap);
 void ex_cexpr(exarg_T *eap);
 void ex_helpgrep(exarg_T *eap);
diff --git a/src/quickfix.c b/src/quickfix.c
index f808da4..2c2fb3c 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -57,6 +57,7 @@ typedef struct qf_list_S
     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
@@ -1545,6 +1546,14 @@ copy_loclist(win_T *from, win_T *to)
            to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
        else
            to_qfl->qf_title = NULL;
+       if (from_qfl->qf_ctx != NULL)
+       {
+           to_qfl->qf_ctx = alloc_tv();
+           if (to_qfl->qf_ctx != NULL)
+               copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx);
+       }
+       else
+           to_qfl->qf_ctx = NULL;
 
        if (from_qfl->qf_count)
        {
@@ -2698,6 +2707,8 @@ qf_free(qf_info_T *qi, int 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;
     qi->qf_lists[idx].qf_index = 0;
 
     qf_clean_dir_stack(&qi->qf_dir_stack);
@@ -4561,6 +4572,7 @@ enum {
     QF_GETLIST_ITEMS   = 0x2,
     QF_GETLIST_NR      = 0x4,
     QF_GETLIST_WINID   = 0x8,
+    QF_GETLIST_CONTEXT = 0x10,
     QF_GETLIST_ALL     = 0xFF
 };
 
@@ -4609,6 +4621,9 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T 
*retdict)
     if (dict_find(what, (char_u *)"winid", -1) != NULL)
        flags |= QF_GETLIST_WINID;
 
+    if (dict_find(what, (char_u *)"context", -1) != NULL)
+       flags |= QF_GETLIST_CONTEXT;
+
     if (flags & QF_GETLIST_TITLE)
     {
        char_u  *t;
@@ -4627,6 +4642,22 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T 
*retdict)
            status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
     }
 
+    if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
+    {
+       if (qi->qf_lists[qf_idx].qf_ctx != NULL)
+       {
+           dictitem_T  *di;
+           di = dictitem_alloc((char_u *)"context");
+           if (di != NULL)
+           {
+               copy_tv(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
+               dict_add(retdict, di);
+           }
+       }
+       else
+           status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
+    }
+
     return status;
 }
 
@@ -4786,6 +4817,16 @@ qf_set_properties(qf_info_T *qi, dict_T *what)
        }
     }
 
+    if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
+    {
+       typval_T        *ctx;
+       free_tv(qi->qf_lists[qi->qf_curlist].qf_ctx);
+       ctx =  alloc_tv();
+       if (ctx != NULL)
+           copy_tv(&di->di_tv, ctx);
+       qi->qf_lists[qi->qf_curlist].qf_ctx = ctx;
+    }
+
     return retval;
 }
 
@@ -4819,6 +4860,52 @@ set_errorlist(
 
     return retval;
 }
+
+    static int
+mark_quickfix_ctx(qf_info_T *qi, int copyID)
+{
+    int                i;
+    int                abort = FALSE;
+    typval_T   *ctx;
+
+    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)
+           abort = set_ref_in_item(ctx, copyID, NULL, NULL);
+    }
+
+    return abort;
+}
+
+/*
+ * Mark the context of the quickfix list and the location lists (if present) as
+ * "in use". So that garabage collection doesn't free the context.
+ */
+    int
+set_ref_in_quickfix(int copyID)
+{
+    int                abort = FALSE;
+    tabpage_T  *tp;
+    win_T      *win;
+
+    abort = mark_quickfix_ctx(&ql_info, copyID);
+    if (abort)
+       return abort;
+
+    FOR_ALL_TAB_WINDOWS(tp, win)
+    {
+       if (win->w_llist_ref != NULL)
+       {
+           abort = mark_quickfix_ctx(win->w_llist_ref, copyID);
+           if (abort)
+               return abort;
+       }
+    }
+
+    return abort;
+}
 #endif
 
 /*
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index b7d985d..f00186f 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -1538,6 +1538,21 @@ function Xproperty_tests(cchar)
     if a:cchar == 'l'
        call assert_equal({}, getloclist(99, ['title']))
     endif
+
+    " Context related tests
+    call g:Xsetlist([], 'a', {'context':[1,2,3]})
+    call garbagecollect()
+    let d = g:Xgetlist({'context':1})
+    call assert_equal([1,2,3], d.context)
+    call g:Xsetlist([], 'a', {'context':{'color':'green'}})
+    let d = g:Xgetlist({'context':1})
+    call assert_equal({'color':'green'}, d.context)
+    call g:Xsetlist([], 'a', {'context':"Context info"})
+    let d = g:Xgetlist({'context':1})
+    call assert_equal("Context info", d.context)
+    call g:Xsetlist([], 'a', {'context':246})
+    let d = g:Xgetlist({'context':1})
+    call assert_equal(246, d.context)
 endfunction
 
 function Test_qf_property()

Raspunde prin e-mail lui