Hi Bram!

On So, 12 Mai 2013, Bram Moolenaar wrote:

> 
> Christian Brabandt wrote:
> 
> > On So, 12 Mai 2013, Bram Moolenaar wrote:
> > 
> > > Wouldn't it be better to have the entries and the titles in a list?
> > 
> > We could do this as well. I don't mind.
> > 
> > > If getqfstack() is to be used to restore, how does one do that restore?
> > 
> > The idea is to do something like
> > " get location list stack
> > : let stack = getlocstack(0)
> > " jump to first location list
> > :lolder 10
> > " repopulate location lists
> > :for id in range(10)
> >      exe printf("call setqflist(a.entry%d, '', a.title%d)", id,id)
> >  endfor
> 
> Hmm, that's doable, but not simple.  What if the returned structure
> changes?  It's probably better to add setlocstac().

Here is an updated patch, containing setlocstack()/setqfstack() function 
and which also includes the title list suggestion. For some reason, the 
stack returned by getqfstack()/getlocstack() looks a little bit weird:

Here an example for an empty stack:
{'entry6': [{}], 'entry7': [{}], 'entry8': [{}], 'entry9': [{}],
'title': ['', '', '', '', '', '', '', '', '', ''], 'cur': 0, 'entry0':
[{}], 'entry1': [{}], 'entry2': [{}], 'entry3': [{}], 'entry4': [{}],
'entry5': [{}]}

(Note, that there are entry6, entry7, entry8, entry9, then comes the 
title list and current item and finally there are the remaining entry0 
till entry5 items).

I am not sure, what causes this. But other then that, it seems to work.

regards,
Christian
-- 
Gute Vorsätze sind vorsorgliche Bußübungen.
                -- Helmar Nahr

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1793,10 +1793,12 @@
 getline( {lnum})		String	line {lnum} of current buffer
 getline( {lnum}, {end})		List	lines {lnum} to {end} of current buffer
 getloclist( {nr})		List	list of location list items
+getlocstack( {nr})		Dict	stack of location lists
 getmatches()			List	list of current matches
 getpid()			Number	process ID of Vim
 getpos( {expr})			List	position of cursor, mark, etc.
 getqflist()			List	list of quickfix items
+getqfstack()			Dict	stack of quickfix lists
 getreg( [{regname} [, 1]])	String	contents of register
 getregtype( [{regname}])	String	type of register
 gettabvar( {nr}, {varname} [, {def}])
@@ -1926,10 +1928,14 @@
 setline( {lnum}, {line})	Number	set line {lnum} to {line}
 setloclist( {nr}, {list}[, {action}[, {title}]])
 				Number	modify location list using {list}
+setlocstack( {nr}, {dict})
+				Number	set location list stack using {dict}
 setmatches( {list})		Number	restore a list of matches
 setpos( {expr}, {list})		Number	set the {expr} position to {list}
 setqflist( {list}[, {action}[, {title}]])
 				Number	modify quickfix list using {list}
+setqfstack( {dict})
+				Number	set quickfix stack using {dict}
 setreg( {n}, {v}[, {opt}])	Number	set register to value and type
 settabvar( {nr}, {varname}, {val})	set {varname} in tab page {nr} to {val}
 settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
@@ -3380,6 +3386,14 @@
 		returned.  For an invalid window number {nr}, an empty list is
 		returned. Otherwise, same as |getqflist()|.
 
+getlocstack({nr})					*getlocstack()*
+		Returns a dictionary with the complete stack of location
+		lists for window {nr}. When {nr} is zero the current
+		window is used.
+		For a location list window, the displayed location list is
+		returned.  For an invalid window number {nr}, an empty
+		dictionary is returned. Otherwise, same as |getqfstack()|.
+
 getmatches()						*getmatches()*
 		Returns a |List| with all matches previously defined by
 		|matchadd()| and the |:match| commands.  |getmatches()| is
@@ -3402,7 +3416,7 @@
 			:unlet m
 <
 
-getqflist()						*getqflist()*
+getqflist()							*getqflist()*
 		Returns a list with all the current quickfix errors.  Each
 		list item is a dictionary with these entries:
 			bufnr	number of buffer that has the file name, use
@@ -3428,6 +3442,18 @@
 			:   echo bufname(d.bufnr) ':' d.lnum '=' d.text
 			:endfor
 
+getqfstack({nr})						*getqfstack()*
+		Returns a dictionary with the stack of the quickfix lists
+		with the following items:
+		  "cur"	    The current position in the quickfix stack
+		  "title"   A list containing all |w:quickfix_title| for
+			    each quickfix list.
+		  "entry0"  A list with all errors of the first quickfix list.
+			    See |getqflist()| for detail information on the
+			    entries.
+		  "entry1"  A list with all errors of the second quickfix list.
+		  ...
+		  "entry9"  A list with all errors of the last quickfix list.
 
 getreg([{regname} [, 1]])				*getreg()*
 		The result is a String, which is the contents of register
@@ -5210,6 +5236,11 @@
 		Otherwise, same as |setqflist()|.
 		Also see |location-list|.
 
+setlocstack({dict})					*setlocstack()*
+		Sets the stack of location lists using the dictionary {dict}.
+		For the structure of {dict} set |getqfstack()|.
+
+
 setmatches({list})					*setmatches()*
 		Restores a list of matches saved by |getmatches()|.  Returns 0
 		if successful, otherwise -1.  All current matches are cleared
@@ -5295,6 +5326,9 @@
 		independent of the 'errorformat' setting.  Use a command like
 		":cc 1" to jump to the first position.
 
+setqfstack({dict})					*setqfstack()*
+		Sets the stack of quickfix lists using the dictionary {dict}.
+		For the structure of {dict} set |getqfstack()|.
 
 							*setreg()*
 setreg({regname}, {value} [,{options}])
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -779,8 +779,10 @@
 
 Quickfix and location lists:			*quickfix-functions*
 	getqflist()		list of quickfix errors
+	getqfstack()		stack of quickfix lists
 	setqflist()		modify a quickfix list
 	getloclist()		list of location list items
+	getlocstack()		stack of location lists
 	setloclist()		modify a location list
 
 Insert mode completion:				*completion-functions*
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -556,6 +556,7 @@
 static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getqfstack __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv));
@@ -675,6 +676,8 @@
 static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setqfstack __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setlocstack __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_settabvar __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
@@ -7936,10 +7939,12 @@
     {"getftype",	1, 1, f_getftype},
     {"getline",		1, 2, f_getline},
     {"getloclist",	1, 1, f_getqflist},
+    {"getlocstack",	1, 1, f_getqfstack},
     {"getmatches",	0, 0, f_getmatches},
     {"getpid",		0, 0, f_getpid},
     {"getpos",		1, 1, f_getpos},
     {"getqflist",	0, 0, f_getqflist},
+    {"getqfstack",	0, 0, f_getqfstack},
     {"getreg",		0, 2, f_getreg},
     {"getregtype",	0, 1, f_getregtype},
     {"gettabvar",	2, 3, f_gettabvar},
@@ -8058,9 +8063,11 @@
     {"setcmdpos",	1, 1, f_setcmdpos},
     {"setline",		2, 2, f_setline},
     {"setloclist",	2, 4, f_setloclist},
+    {"setlocstack",	2, 2, f_setlocstack},
     {"setmatches",	1, 1, f_setmatches},
     {"setpos",		2, 2, f_setpos},
     {"setqflist",	1, 3, f_setqflist},
+    {"setqfstack",	1, 1, f_setqfstack},
     {"setreg",		2, 3, f_setreg},
     {"settabvar",	3, 3, f_settabvar},
     {"settabwinvar",	4, 4, f_settabwinvar},
@@ -11711,7 +11718,37 @@
 		return;
 	}
 
-	(void)get_errorlist(wp, rettv->vval.v_list);
+	(void)get_errorlist(wp, rettv->vval.v_list, NULL);
+    }
+#endif
+}
+
+/*
+ * "getqfstack()" functions
+ */
+    static void
+f_getqfstack(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+#ifdef FEAT_QUICKFIX
+    win_T	*wp;
+    list_T	*l = list_alloc();
+#endif
+
+#ifdef FEAT_QUICKFIX
+    if (rettv_dict_alloc(rettv) == OK && l != NULL)
+    {
+	wp = NULL;
+	++l->lv_refcount;
+	if (argvars[0].v_type != VAR_UNKNOWN)	/* getlocstack() */
+	{
+	    wp = find_win_by_nr(&argvars[0], NULL);
+	    if (wp == NULL)
+		return;
+	}
+
+	(void)get_errorlist(wp, l, rettv->vval.v_dict);
     }
 #endif
 }
@@ -16443,6 +16480,112 @@
 	set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv);
 }
 
+static void set_qf_ll_stack __ARGS((win_T *wp, dict_T *dict, typval_T *rettv));
+
+    static void
+set_qf_ll_stack(wp, dict, rettv)
+    win_T	*wp;
+    dict_T	*dict;
+    typval_T	*rettv;
+{
+    dictitem_T	*di;
+    int		i;
+
+    if (!(dict_find(dict, (char_u *)"cur", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry0", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry1", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry2", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry3", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry4", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry5", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry6", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry7", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry8", -1) != NULL
+	    && dict_find(dict, (char_u *)"entry9", -1) != NULL
+	    && dict_find(dict, (char_u *)"title", -1) != NULL))
+	    {
+		EMSG(_(e_invarg));
+		return;
+	    }
+    qf_free_all(NULL);
+    qf_reset_listcount(NULL);
+    for (i=0; i < 10; i++)
+    {
+	char	    key[7];
+	char_u	    *title;
+	list_T	    *list;
+	listitem_T  *l;
+
+	sprintf((char *)key, "entry%d", i);
+	di = dict_find(dict, (char_u *)key, -1);
+	if (di != NULL)
+	    list = (list_T *)(&di->di_tv)->vval.v_list;
+	di = dict_find(dict, (char_u *)"title", -1);
+	if (di != NULL)
+	{
+	    l = list_find((&di->di_tv)->vval.v_list, i);
+	    title = (&l->li_tv)->vval.v_string;
+	}
+	if (list != NULL && list->lv_first != NULL
+		&& list->lv_first->li_tv.vval.v_dict != NULL
+		&& list->lv_first->li_tv.vval.v_dict->dv_hashtab.ht_used > 0)
+	    set_errorlist(wp, list, ' ', title);
+
+    }
+    qf_set_curitem(wp, get_dict_number(dict, (char_u *)"cur"));
+    rettv->vval.v_number = 0;
+}
+
+/*
+ * "setqfstack()" function
+ */
+    static void
+f_setqfstack(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_T	*dict;
+
+    rettv->vval.v_number = -1;
+
+    if (argvars[0].v_type != VAR_DICT
+	    || (dict = argvars[0].vval.v_dict) == NULL)
+	EMSG(_(e_invarg));
+    else
+    {
+	set_qf_ll_stack(NULL, dict, rettv);
+	qf_update(FALSE);
+    }
+}
+
+/*
+ * "setlocstack()" function
+ */
+    static void
+f_setlocstack(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_T	*dict;
+    win_T	*win;
+
+    rettv->vval.v_number = -1;
+
+    win = find_win_by_nr(&argvars[0], NULL);
+    if (win != NULL)
+    {
+	if (argvars[1].v_type != VAR_DICT
+		|| (dict = argvars[1].vval.v_dict) == NULL)
+	    EMSG(_(e_invarg));
+	else
+	{
+	    set_qf_ll_stack(win, dict, rettv);
+	    qf_update(FALSE);
+	}
+    }
+}
+
+
 /*
  * "setmatches()" function
  */
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -1,5 +1,8 @@
 /* quickfix.c */
 int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title));
+void qf_reset_listcount __ARGS((win_T *wp));
+void qf_update __ARGS((int llist));
+void qf_set_curitem __ARGS((win_T *wp, int count));
 void qf_free_all __ARGS((win_T *wp));
 void copy_loclist __ARGS((win_T *from, win_T *to));
 void qf_jump __ARGS((qf_info_T *qi, int dir, int errornr, int forceit));
@@ -23,7 +26,7 @@
 void ex_cfile __ARGS((exarg_T *eap));
 void ex_vimgrep __ARGS((exarg_T *eap));
 char_u *skip_vimgrep_pat __ARGS((char_u *p, char_u **s, int *flags));
-int get_errorlist __ARGS((win_T *wp, list_T *list));
+int get_errorlist __ARGS((win_T *wp, list_T *list, dict_T *dict));
 int set_errorlist __ARGS((win_T *wp, list_T *list, int action, char_u *title));
 void ex_cbuffer __ARGS((exarg_T *eap));
 void ex_cexpr __ARGS((exarg_T *eap));
diff --git a/src/quickfix.c b/src/quickfix.c
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -943,6 +943,48 @@
 }
 
     void
+qf_reset_listcount(wp)
+    win_T	*wp;
+{
+    qf_info_T	*qi = &ql_info;
+
+    if (wp != NULL)
+	qi = (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist);
+
+    qi->qf_listcount = 0;
+    qi->qf_curlist = 0;
+}
+
+/* update the location/quickfix list */
+    void
+qf_update(llist)
+    int	llist; /* True, update location list, else quickfix list */
+{
+    qf_info_T *qi = &ql_info;
+
+    if (llist)
+	qi = ll_get_or_alloc_list(curwin);
+
+    qf_update_buffer(qi);
+}
+
+
+/* set the current item for the quickfix/location list */
+    void
+qf_set_curitem(wp, count)
+    win_T	*wp;
+    int		count;
+{
+    qf_info_T	*qi = &ql_info;
+
+    if (wp != NULL)
+	qi = (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist);
+
+    if (count < qi->qf_listcount)
+	qi->qf_curlist = count;
+}
+
+    void
 qf_free_all(wp)
     win_T	*wp;
 {
@@ -3739,9 +3781,10 @@
  * Add each quickfix error to list "list" as a dictionary.
  */
     int
-get_errorlist(wp, list)
+get_errorlist(wp, list, dict_all)
     win_T	*wp;
     list_T	*list;
+    dict_T 	*dict_all;
 {
     qf_info_T	*qi = &ql_info;
     dict_T	*dict;
@@ -3749,47 +3792,106 @@
     qfline_T	*qfp;
     int		i;
     int		bufnum;
+    int		j;
+    char_u	*qf_title;
+    list_T	*tlist;
 
     if (wp != NULL)
     {
 	qi = GET_LOC_LIST(wp);
-	if (qi == NULL)
+	if (dict_all == NULL && qi == NULL)
 	    return FAIL;
     }
 
-    if (qi->qf_curlist >= qi->qf_listcount
-	    || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+    if (dict_all != NULL)
+    {
+	tlist = list_alloc();
+	if (tlist == NULL)
+		return FAIL;
+    }
+
+    if (dict_all == NULL && (qi->qf_curlist >= qi->qf_listcount
+	    || qi->qf_lists[qi->qf_curlist].qf_count == 0))
 	return FAIL;
 
-    qfp = qi->qf_lists[qi->qf_curlist].qf_start;
-    for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i)
+    j = (dict_all != NULL ? 0 : qi->qf_curlist);
+
+    for (; j < LISTCOUNT; j++)
     {
-	/* Handle entries with a non-existing buffer number. */
-	bufnum = qfp->qf_fnum;
-	if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
-	    bufnum = 0;
-
-	if ((dict = dict_alloc()) == NULL)
-	    return FAIL;
-	if (list_append_dict(list, dict) == FAIL)
-	    return FAIL;
-
-	buf[0] = qfp->qf_type;
-	buf[1] = NUL;
-	if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL
-	  || dict_add_nr_str(dict, "lnum",  (long)qfp->qf_lnum, NULL) == FAIL
-	  || dict_add_nr_str(dict, "col",   (long)qfp->qf_col, NULL) == FAIL
-	  || dict_add_nr_str(dict, "vcol",  (long)qfp->qf_viscol, NULL) == FAIL
-	  || dict_add_nr_str(dict, "nr",    (long)qfp->qf_nr, NULL) == FAIL
-	  || dict_add_nr_str(dict, "pattern",  0L,
-	     qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
-	  || dict_add_nr_str(dict, "text",  0L,
-		   qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL
-	  || dict_add_nr_str(dict, "type",  0L, buf) == FAIL
-	  || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL)
-	    return FAIL;
-
-	qfp = qfp->qf_next;
+	if (qi != NULL)
+	{
+	    qfp = qi->qf_lists[j].qf_start;
+	    qf_title = qi->qf_lists[j].qf_title;
+	}
+	else
+	{
+	    qfp = NULL;
+	    qf_title = (char_u *)"";
+	}
+	for (i = 1; !got_int && qi != NULL && i <= qi->qf_lists[j].qf_count; ++i)
+	{
+	    /* Handle entries with a non-existing buffer number. */
+	    bufnum = qfp->qf_fnum;
+	    if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
+		bufnum = 0;
+
+	    if ((dict = dict_alloc()) == NULL)
+		return FAIL;
+	    if (list_append_dict(list, dict) == FAIL)
+		return FAIL;
+
+	    buf[0] = qfp->qf_type;
+	    buf[1] = NUL;
+	    if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL
+	    || dict_add_nr_str(dict, "lnum",  (long)qfp->qf_lnum, NULL) == FAIL
+	    || dict_add_nr_str(dict, "col",   (long)qfp->qf_col, NULL) == FAIL
+	    || dict_add_nr_str(dict, "vcol",  (long)qfp->qf_viscol, NULL) == FAIL
+	    || dict_add_nr_str(dict, "nr",    (long)qfp->qf_nr, NULL) == FAIL
+	    || dict_add_nr_str(dict, "pattern",  0L,
+		qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
+	    || dict_add_nr_str(dict, "text",  0L,
+		    qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL
+	    || dict_add_nr_str(dict, "type",  0L, buf) == FAIL
+	    || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL)
+		return FAIL;
+
+	    qfp = qfp->qf_next;
+	}
+	if (dict_all == NULL)
+	    break;
+	else
+	{
+	    if (qi == NULL || qi->qf_lists[j].qf_count == 0)
+	    {
+		dict = dict_alloc();
+		list_append_dict(list,dict);
+	    }
+	    if (list != NULL)
+	    {
+		char label[7] = "";
+		sprintf(label, "entry%d", j);
+		dict_add_list(dict_all, (char *)&label, list);
+#if 0
+		sprintf(label, "title%d", j);
+		if ((dict_add_nr_str(dict_all, (char *)&label,  0L,
+		    qf_title == NULL ? (char_u *)"" : qf_title) == FAIL))
+		    return FAIL;
+#endif
+		list_append_string(tlist,
+		    (qf_title == NULL ? (char_u *)"" : qf_title), -1);
+
+		if ((list = list_alloc()) == NULL)
+		    return FAIL;
+	    }
+	}
+    }
+    if (dict_all != NULL)
+    {
+	if (dict_add_nr_str(dict_all, "cur",
+		    (qi == NULL ? 0 : qi->qf_curlist), NULL) == FAIL ||
+	    dict_add_list(dict_all, "title", tlist) == FAIL)
+		return FAIL;
+	list_free(list, TRUE);
     }
     return OK;
 }

Raspunde prin e-mail lui