Hi LCD!

On Mi, 22 Mai 2013, LCD 47 wrote:
> On 22 May 2013, LCD 47 <lcd...@gmail.com> wrote:
> [...]
> >     Excellent, thank you!  I'll play with it for a while, then post my
> > conclusions.
> 
>     There seems to be a bug in getlocstack(), it misses the first entry.
> Example: after a single run of syntastic check:
> 
>     :echo len(getlocstack(0))
>     3
> 
>     :echo len(getloctitle(0))
>     4
> Here getloctitle() seems to work correctly.   

I don't see this. How did you make this? (I only checked by calling 
:setloclist(0, [...]) several times and not sure how to make syntastic 
do this.

> Also getlocstackptr() should probably return -1 rather than 0 if the
> stack is empty (calling getlocstack() to find out is expensive in
> terms of memory).

Ok. Updated the patch.

>     I haven't looked at setlocstack() and getqf*() / setqf*().
> 
>     There are a few mistakes and omissions in the manual:
> 
> (1) getlocstackptr() and getloctitle() take an argument, while
>     getqfstack() doesn't;
> (2) the arguments for the new functions are not described;
> (3) it's not clear if the stack pointers are 0- or 1-based.

Ok, seems I mixed up the documentation yesterday. I have updated it now. 
> 
>     From the point of view of design, I still claim it would have been
> cleaner to assign handle IDs to loclists, the same way it's done for
> buffers, windows, tabs, and basically everything else.  It would have
> allowed to solve the last piece of the puzzle, namely converting between
> the current window, the associated loclist, and the associated loclist
> window: these might all have been attributes of the loclists.
> 
>     Without handle IDs, you basically have to use the stack to point
> functions to the relevant loclist.  This works, but it's a rather ugly
> hack, and it doesn't extend easily to finding, say, the loclist window
> associated to the current window.

I have still no idea how to approach this yet. 

regards,
Christian
-- 

-- 
-- 
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,16 @@
 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})		List	stack of location lists
+getlocstackptr( {nr})		Number	Returns index of current location list in stack
+getloctitle( {nr})		Lists	Returns list of titles for location list stack
 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()			List	stack of quickfix lists
+getqfstackptr()			Number	Returns index of current quickfix list in stack
+getqftitle()			Lists	Returns list of titles for quickfix list stack
 getreg( [{regname} [, 1]])	String	contents of register
 getregtype( [{regname}])	String	type of register
 gettabvar( {nr}, {varname} [, {def}])
@@ -1924,11 +1930,18 @@
 setbufvar( {expr}, {varname}, {val})	set {varname} in buffer {expr} to {val}
 setcmdpos( {pos})		Number	set cursor position in command-line
 setline( {lnum}, {line})	Number	set line {lnum} to {line}
-setloclist( {nr}, {list}[, {action}])
+setloclist( {nr}, {list}[, {action}[, {title}]])
 				Number	modify location list using {list}
+setloctitle( {nr}, {string})	Number	set the |w:quickfix_title| for the
+					current location list.
+setlocstackptr( {nr}, {nr})	Number	moves within the location list stack.
 setmatches( {list})		Number	restore a list of matches
 setpos( {expr}, {list})		Number	set the {expr} position to {list}
-setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
+setqflist( {list}[, {action}[, {title}]])
+				Number	modify quickfix list using {list}
+setqfstackptr( {nr})		Number	moves within the quickfix stack.
+setqftitle( {string})		Number	set the |w:quickfix_title| for the
+					current quickfix list.
 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
@@ -3365,6 +3378,28 @@
 		returned.  For an invalid window number {nr}, an empty list is
 		returned. Otherwise, same as |getqflist()|.
 
+
+getlocstack({nr})					*getlocstack()*
+		Returns a list with the stack of the location lists for window
+		{nr}. When {nr} is zero the current window is used. The
+		location list can currently handle 10 different error list,
+		which can be traversed by using |:lolder| and |:lnewer|. The
+		getlocstack() function returns the complete stack of those
+		quickfix lists. 
+
+getlocstackptr({nr})					*getlocstackptr()*
+		Returns the index within the stack of the location lists for window
+		{nr}. When {nr} is zero the current window is used. The
+		index can be used with the |getlocstack()| function to access the current
+		active list. Index is in the range 0 - 9
+		On error, or for an empty stack, -1 is returned.
+
+getloctitle({nr})			    		*getloctitle()*
+		Returns a list containing the title for each of the location
+		lists in window {nr} in the stack. When {nr} is zero, the
+		current window is used. The title will also available in the
+		|w:quickfix_title| variable of the location list.
+
 getmatches()						*getmatches()*
 		Returns a |List| with all matches previously defined by
 		|matchadd()| and the |:match| commands.  |getmatches()| is
@@ -3387,7 +3422,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
@@ -3413,6 +3448,25 @@
 			:   echo bufname(d.bufnr) ':' d.lnum '=' d.text
 			:endfor
 
+getqfstack()						*getqfstack()*
+		Returns a list with the stack of the quickfix lists. The
+		quickfix list can currently handle 10 different error list,
+		which can be traversed by using |:colder| and |:cnewer|. The
+		getqfstack() function returns the complete stack of those
+		quickfix lists. 
+
+getqfstackptr()						*getqfstackptr()*
+		Returns the index of the quickfix stack, that can be used with
+		the |getqfstack()| function to access the current active list.
+		The index goes from 0 for the oldes entry up to a 
+		maximum of 9 since the stack can currently hold up to 10
+		items.
+		On error, or for an empty stack, -1 is returned.
+
+getqftitle()				    		*getqftitle()*
+		Returns a list containing the title for each of the quickfix
+		lists in the stack. The title is also available in the
+		|w:quickfix_title| variable of the quickfix window.
 
 getreg([{regname} [, 1]])				*getreg()*
 		The result is a String, which is the contents of register
@@ -5186,14 +5240,26 @@
 			:endfor
 <		Note: The '[ and '] marks are not set.
 
-setloclist({nr}, {list} [, {action}])			*setloclist()*
+setloclist({nr}, {list} [, {action}[, {title}]])		*setloclist()*
 		Create or replace or add to the location list for window {nr}.
 		When {nr} is zero the current window is used. For a location
 		list window, the displayed location list is modified.  For an
-		invalid window number {nr}, -1 is returned.
+		invalid window number {nr}, -1 is returned. If {title} is
+		given, it will be stored in the variable |w:quickfix_title|.
 		Otherwise, same as |setqflist()|.
 		Also see |location-list|.
 
+setlocstackptr({nr}, {index})				 *setlocstackptr()*
+		Sets the current item in the location list stack to {index}.
+		Returns -1 for invalid index item.
+		That is the same as using |:lolder| or |:lnewer|
+
+setloctitle({nr}, {string})					 *setloctitle()*
+		Set {string} as title for the current item in the location
+		list stack for window {nr}. If {nr} is zero, the current
+		window will be used. The title will then be available as
+		|w:quickfix_title| variable. Also see |location-list|.
+
 setmatches({list})					*setmatches()*
 		Restores a list of matches saved by |getmatches()|.  Returns 0
 		if successful, otherwise -1.  All current matches are cleared
@@ -5233,7 +5299,7 @@
 		vertically.  See |winrestview()| for that.
 
 
-setqflist({list} [, {action}])				*setqflist()*
+setqflist({list} [, {action}[, {title}]])			*setqflist()*
 		Create or replace or add to the quickfix list using the items
 		in {list}.  Each item in {list} is a dictionary.
 		Non-dictionary items in {list} are ignored.  Each dictionary
@@ -5270,7 +5336,8 @@
 		list, then a new list is created. If {action} is set to 'r',
 		then the items from the current quickfix list are replaced
 		with the items from {list}. If {action} is not present or is
-		set to ' ', then a new list is created.
+		set to ' ', then a new list is created. If {title} is
+		given, it will be stored in the variable |w:quickfix_title|.
 
 		Returns zero for success, -1 for failure.
 
@@ -5278,6 +5345,15 @@
 		independent of the 'errorformat' setting.  Use a command like
 		":cc 1" to jump to the first position.
 
+setqfstackptr({index})					 *setqfstackptr()*
+		Sets the current item in the quickfix list stack to {index}.
+		Returns -1 for invalid index item.
+		That is the same as using |:colder| or |:cnewer|
+
+setqftitle({string})					 *setqftitle()*
+		Set {string} as title for the current item in the quickfix
+		list stack. The title will then be available as
+		|w:quickfix_title| variable.
 
 							*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,9 +779,19 @@
 
 Quickfix and location lists:			*quickfix-functions*
 	getqflist()		list of quickfix errors
+	getqfstack()		stack of quickfix lists
+	getqfstackptr()		index in stack of quickfix lists
+	getqftitle()		list of titles of quickfix list stack
 	setqflist()		modify a quickfix list
+	setqftitle()		sets the title for the quickfix list
+	setqfstackptr()		moves within the quickfix stack
 	getloclist()		list of location list items
+	getlocstack()		stack of location lists
+	getlocstackptr()	index in stack of location lists
+	getloctitle()		list of titles of location list stack
 	setloclist()		modify a location list
+	setloctitle()		sets the title for the location list
+	setlocstackptr()	moves within the location list stack
 
 Insert mode completion:				*completion-functions*
 	complete()		set found matches
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -553,6 +553,9 @@
 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_getqfstackptr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getqftitle __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));
@@ -669,6 +672,10 @@
 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setloctitle __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setlocstackptr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setqfstackptr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setqftitle __ARGS((typval_T *argvars, typval_T *rettv));
 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));
@@ -7932,10 +7939,16 @@
     {"getftype",	1, 1, f_getftype},
     {"getline",		1, 2, f_getline},
     {"getloclist",	1, 1, f_getqflist},
+    {"getlocstack",	1, 1, f_getqfstack},
+    {"getlocstackptr",	1, 1, f_getqfstackptr},
+    {"getloctitle",	1, 1, f_getqftitle},
     {"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},
+    {"getqfstackptr",	0, 0, f_getqfstackptr},
+    {"getqftitle",	0, 0, f_getqftitle},
     {"getreg",		0, 2, f_getreg},
     {"getregtype",	0, 1, f_getregtype},
     {"gettabvar",	2, 3, f_gettabvar},
@@ -8053,10 +8066,14 @@
     {"setbufvar",	3, 3, f_setbufvar},
     {"setcmdpos",	1, 1, f_setcmdpos},
     {"setline",		2, 2, f_setline},
-    {"setloclist",	2, 3, f_setloclist},
+    {"setloclist",	2, 4, f_setloclist},
+    {"setlocstackptr",	2, 2, f_setlocstackptr},
+    {"setloctitle",	2, 2, f_setloctitle},
     {"setmatches",	1, 1, f_setmatches},
     {"setpos",		2, 2, f_setpos},
-    {"setqflist",	1, 2, f_setqflist},
+    {"setqflist",	1, 3, f_setqflist},
+    {"setqfstackptr",	1, 1, f_setqfstackptr},
+    {"setqftitle",	1, 1, f_setqftitle},
     {"setreg",		2, 3, f_setreg},
     {"settabvar",	3, 3, f_settabvar},
     {"settabwinvar",	4, 4, f_settabwinvar},
@@ -11670,7 +11687,91 @@
 		return;
 	}
 
-	(void)get_errorlist(wp, rettv->vval.v_list);
+	(void)get_errorlist(wp, rettv->vval.v_list, NULL);
+    }
+#endif
+}
+
+/*
+ * "getqfstackptr()" and "getlocstackptr()" functions
+ */
+    static void
+f_getqfstackptr(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+#ifdef FEAT_QUICKFIX
+    win_T	*wp;
+#endif
+
+#ifdef FEAT_QUICKFIX
+    rettv->vval.v_number = -1;
+    wp = NULL;
+    if (argvars[0].v_type != VAR_UNKNOWN)	/* getloclist() */
+    {
+	wp = find_win_by_nr(&argvars[0], NULL);
+	if (wp == NULL)
+	    return;
+    }
+
+    rettv->vval.v_number = qf_get_curitem(wp);
+#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_list_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_list);
+    }
+#endif
+}
+
+/*
+ * "getqftitle()" functions
+ */
+    static void
+f_getqftitle(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+#ifdef FEAT_QUICKFIX
+    win_T	*wp;
+#endif
+
+#ifdef FEAT_QUICKFIX
+    if (rettv_list_alloc(rettv) == OK)
+    {
+	wp = NULL;
+	if (argvars[0].v_type != VAR_UNKNOWN)	/* getloctitle() */
+	{
+	    wp = find_win_by_nr(&argvars[0], NULL);
+	    if (wp == NULL)
+		return;
+	}
+
+	(void)get_errortitle(wp, rettv->vval.v_list);
     }
 #endif
 }
@@ -16331,21 +16432,23 @@
 	appended_lines_mark(lcount, added);
 }
 
-static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv));
+static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *title_arg, typval_T *rettv));
 
 /*
  * Used by "setqflist()" and "setloclist()" functions
  */
     static void
-set_qf_ll_list(wp, list_arg, action_arg, rettv)
+set_qf_ll_list(wp, list_arg, action_arg, title_arg, rettv)
     win_T	*wp UNUSED;
     typval_T	*list_arg UNUSED;
     typval_T	*action_arg UNUSED;
+    typval_T	*title_arg UNUSED;
     typval_T	*rettv;
 {
 #ifdef FEAT_QUICKFIX
     char_u	*act;
     int		action = ' ';
+    char_u	*title = NULL;
 #endif
 
     rettv->vval.v_number = -1;
@@ -16365,9 +16468,16 @@
 	    if (*act == 'a' || *act == 'r')
 		action = *act;
 	}
-
-	if (l != NULL && set_errorlist(wp, l, action,
-	       (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
+	if (title_arg->v_type == VAR_STRING)
+	{
+	    title = get_tv_string_chk(title_arg);
+	    if (title == NULL)
+		return;		/* type error; errmsg already given */
+	}
+	if (title == NULL)
+	    title =  (char_u*)(wp == NULL ? "setqflist()" : "setloclist()");
+
+	if (l != NULL && set_errorlist(wp, l, action, title) == OK)
 	    rettv->vval.v_number = 0;
     }
 #endif
@@ -16387,8 +16497,9 @@
 
     win = find_win_by_nr(&argvars[0], NULL);
     if (win != NULL)
-	set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
-}
+	set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv);
+}
+
 
 /*
  * "setmatches()" function
@@ -16502,7 +16613,95 @@
     typval_T	*argvars;
     typval_T	*rettv;
 {
-    set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
+    set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv);
+}
+
+/*
+ * "setqftitle()" functions
+ */
+    static void
+f_setqftitle(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+    char_u  *varname;
+    varname = get_tv_string_chk(&argvars[0]);
+
+#ifdef FEAT_QUICKFIX
+    if (varname != NULL)
+	(void)win_set_qf_title(NULL, varname );
+#endif
+}
+
+/*
+ * "setlocstackptr()" functions
+ */
+    static void
+f_setlocstackptr(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+#ifdef FEAT_QUICKFIX
+    int	    number;
+    win_T   *wp;
+
+    rettv->vval.v_number = -1;
+    wp = NULL;
+    wp = find_win_by_nr(&argvars[0], NULL);
+    if (wp == NULL)
+	return;
+    number = (int)get_tv_number_chk(&argvars[1], NULL);
+    if (number == -1)
+	return;
+    else
+	rettv->vval.v_number = qf_set_curitem(wp, number);
+#endif
+}
+
+/*
+ * "setloctitle()" functions
+ */
+    static void
+f_setloctitle(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+#ifdef FEAT_QUICKFIX
+    char_u  *varname;
+    win_T	*wp;
+
+    wp = NULL;
+    if (argvars[0].v_type != VAR_UNKNOWN)	/* getloclist() */
+    {
+	wp = find_win_by_nr(&argvars[0], NULL);
+	if (wp == NULL)
+	    return;
+    }
+    varname = get_tv_string_chk(&argvars[1]);
+
+    if (varname != NULL)
+	(void)win_set_qf_title(wp, varname );
+#endif
+}
+
+/*
+ * "setqfstackptr()" functions
+ */
+    static void
+f_setqfstackptr(argvars, rettv)
+    typval_T	*argvars UNUSED;
+    typval_T	*rettv UNUSED;
+{
+#ifdef FEAT_QUICKFIX
+    int	    number;
+
+    rettv->vval.v_number = -1;
+    number = (int)get_tv_number_chk(&argvars[0], NULL);
+    if (number == -1)
+	return;
+    else
+	rettv->vval.v_number = qf_set_curitem(NULL, number);
+#endif
 }
 
 /*
@@ -16698,6 +16897,15 @@
 		STRCPY(winvarname, "w:");
 		STRCPY(winvarname + 2, varname);
 		set_var(winvarname, varp, TRUE);
+		if (STRCMP(varname, "quickfix_title") == 0)
+		{
+		    dictitem_T	*v;
+
+		    v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE);
+		    if (v != NULL)
+			win_set_qf_title(curwin, (&v->di_tv)->vval.v_string); 
+		}
+
 		vim_free(winvarname);
 	    }
 	}
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -1,10 +1,14 @@
 /* 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));
+int qf_set_curitem __ARGS((win_T *wp, int count));
+int qf_get_curitem __ARGS((win_T *wp));
 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));
 void qf_list __ARGS((exarg_T *eap));
 void qf_age __ARGS((exarg_T *eap));
+void win_set_qf_title __ARGS((win_T *wp, char_u *title));
 void qf_mark_adjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after));
 void ex_cwindow __ARGS((exarg_T *eap));
 void ex_cclose __ARGS((exarg_T *eap));
@@ -22,7 +26,8 @@
 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_errortitle __ARGS((win_T *wp, list_T *list));
+int get_errorlist __ARGS((win_T *wp, list_T *list, list_T *list_all));
 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
@@ -914,13 +914,7 @@
 	qi->qf_curlist = qi->qf_listcount++;
     vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
     if (qf_title != NULL)
-    {
-	char_u *p = alloc((int)STRLEN(qf_title) + 2);
-
-	qi->qf_lists[qi->qf_curlist].qf_title = p;
-	if (p != NULL)
-	    sprintf((char *)p, ":%s", (char *)qf_title);
-    }
+	qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(qf_title);
 }
 
 /*
@@ -949,6 +943,59 @@
 }
 
     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;
+}
+
+/* set the current item for the quickfix/location list */
+    int
+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 (qi == NULL || count >= qi->qf_listcount)
+	return -1;
+    else
+    {
+	qi->qf_curlist = count;
+	qf_update_buffer(qi);
+	return OK;
+    }
+}
+
+/* get the current item for the quickfix/location list */
+    int
+qf_get_curitem(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);
+
+    if (qi == NULL)
+	return -1;
+    else if ((wp == NULL && qi->qf_lists[qi->qf_curlist].qf_count == 0)
+	    || qi->qf_curlist >= qi->qf_listcount)
+	return -1;
+    else
+	return qi->qf_curlist;
+}
+
+    void
 qf_free_all(wp)
     win_T	*wp;
 {
@@ -2587,6 +2634,31 @@
 				    qi->qf_lists[qi->qf_curlist].qf_title);
 }
 
+    void
+win_set_qf_title(wp, title)
+    win_T   *wp;
+    char_u  *title;
+{
+    qf_info_T	*qi;
+
+    if (wp == NULL || IS_QF_WINDOW(wp))
+	qi  = &ql_info;
+    else if (IS_LL_WINDOW(wp))
+	qi  = wp->w_llist_ref;
+    else
+	return;
+
+    if (title != NULL)
+    {
+	vim_free(qi->qf_lists[qi->qf_curlist].qf_title);
+	qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(title);
+	qf_set_title(qi);
+#ifdef FEAT_WINDOWS
+	qf_update_buffer(qi);
+#endif
+    }
+}
+
 /*
  * Fill current buffer with quickfix errors, replacing any previous contents.
  * curbuf must be the quickfix buffer!
@@ -2784,6 +2856,7 @@
     int		res;
 #ifdef FEAT_AUTOCMD
     char_u	*au_name = NULL;
+    char_u	title[130] = ":";
 
     /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */
     if (grep_internal(eap->cmdidx))
@@ -2856,10 +2929,10 @@
 #endif
 
     res = qf_init(wp, fname, (eap->cmdidx != CMD_make
-			    && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
-					   (eap->cmdidx != CMD_grepadd
-					    && eap->cmdidx != CMD_lgrepadd),
-					   *eap->cmdlinep);
+	    && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
+		(eap->cmdidx != CMD_grepadd
+		&& eap->cmdidx != CMD_lgrepadd),
+		(char_u *)STRNCAT(title, *eap->cmdlinep, (size_t) 128));
     if (wp != NULL)
 	qi = GET_LOC_LIST(wp);
 #ifdef FEAT_AUTOCMD
@@ -3022,6 +3095,7 @@
 #ifdef FEAT_AUTOCMD
     char_u	*au_name = NULL;
 #endif
+    char_u	title[130] = ":";
 
     if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile
 					       || eap->cmdidx == CMD_laddfile)
@@ -3067,10 +3141,10 @@
      * quickfix list then a new list is created.
      */
     if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
-				  && eap->cmdidx != CMD_laddfile),
-							   *eap->cmdlinep) > 0
-				  && (eap->cmdidx == CMD_cfile
-					     || eap->cmdidx == CMD_lfile))
+	    && eap->cmdidx != CMD_laddfile),
+	    (char_u*) STRNCAT(title, *eap->cmdlinep, (size_t) 128)) > 0
+	    && (eap->cmdidx == CMD_cfile
+			    || eap->cmdidx == CMD_lfile))
     {
 #ifdef FEAT_AUTOCMD
 	if (au_name != NULL)
@@ -3131,6 +3205,8 @@
     char_u	*dirname_start = NULL;
     char_u	*dirname_now = NULL;
     char_u	*target_dir = NULL;
+    char_u	title[130] = ":";
+    char_u      *q = vim_strnsave(*eap->cmdlinep, 128);
 #ifdef FEAT_AUTOCMD
     char_u	*au_name =  NULL;
 
@@ -3208,7 +3284,7 @@
 	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
 					|| qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list(qi, *eap->cmdlinep);
+	qf_new_list(qi, (char_u *)STRNCAT(title, q, (size_t) 128));
     else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
 	/* Adding to existing list, find last entry. */
 	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
@@ -3310,7 +3386,7 @@
 	    if (idx == LISTCOUNT)
 	    {
 		/* List cannot be found, create a new one. */
-		qf_new_list(qi, *eap->cmdlinep);
+		qf_new_list(qi, (char_u *)STRNCAT(title, q, (size_t) 128));
 		cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
 	    }
 	}
@@ -3488,6 +3564,7 @@
     vim_free(dirname_start);
     vim_free(target_dir);
     vim_free(regmatch.regprog);
+    vim_free(q);
 }
 
 /*
@@ -3715,12 +3792,42 @@
 
 #if defined(FEAT_EVAL) || defined(PROTO)
 /*
+ * Populate the list "list" with all quickfix/location list titles
+ */
+    int
+get_errortitle(wp, list)
+    win_T	*wp;
+    list_T	*list;
+{
+    char_u	*title;
+    qf_info_T	*qi = &ql_info;
+    int		j;
+
+    if (wp != NULL)
+	qi = GET_LOC_LIST(wp);
+
+    if (qi == NULL)
+	return FAIL;
+
+    for (j = 0; qi != NULL && j < qi->qf_listcount; j++)
+    {
+	if (list != NULL)
+	{
+	    title = qi->qf_lists[j].qf_title;
+
+	    list_append_string(list, title == NULL ? (char_u *)"" : title, -1);
+	}
+    }
+    return OK;
+}
+/*
  * Add each quickfix error to list "list" as a dictionary.
  */
     int
-get_errorlist(wp, list)
+get_errorlist(wp, list, list_all)
     win_T	*wp;
     list_T	*list;
+    list_T 	*list_all;
 {
     qf_info_T	*qi = &ql_info;
     dict_T	*dict;
@@ -3728,48 +3835,69 @@
     qfline_T	*qfp;
     int		i;
     int		bufnum;
+    int		j;
 
     if (wp != NULL)
+	qi = GET_LOC_LIST(wp);
+
+    if (qi == NULL || qi->qf_curlist >= qi->qf_listcount
+	    || (list_all == NULL && qi->qf_lists[qi->qf_curlist].qf_count == 0))
+	return FAIL;
+
+    j = (list_all != NULL ? 0 : qi->qf_curlist);
+
+    for (; j < LISTCOUNT; j++)
     {
-	qi = GET_LOC_LIST(wp);
-	if (qi == NULL)
-	    return FAIL;
+	listitem_T *li = listitem_alloc();
+
+	qfp = qi->qf_lists[j].qf_start;
+	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 (list_all == NULL)
+	    break;
+	else if (qi != NULL && qi->qf_lists[j].qf_count)
+	{
+	    if (list != NULL)
+	    {
+		list_append(list_all, li);
+		li->li_tv.v_type = VAR_LIST;
+		li->li_tv.v_lock = 0;
+		li->li_tv.vval.v_list = list;
+
+		if ((list = list_alloc()) == NULL)
+		    return FAIL;
+	    }
+	}
     }
-
-    if (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)
-    {
-	/* 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 (list_all != NULL)
+	list_free(list, TRUE);
     return OK;
 }
 
@@ -3807,6 +3935,7 @@
     if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
 	qf_new_list(qi, title);
+
     else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
 	/* Adding to existing list, find last entry. */
 	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
@@ -3815,6 +3944,12 @@
     else if (action == 'r')
 	qf_free(qi, qi->qf_curlist);
 
+    if (title != NULL && action != ' ')
+    {
+	vim_free(qi->qf_lists[qi->qf_curlist].qf_title);
+	qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(title);
+    }
+
     for (li = list->lv_first; li != NULL; li = li->li_next)
     {
 	if (li->li_tv.v_type != VAR_DICT)
@@ -4026,6 +4161,7 @@
 #ifdef FEAT_AUTOCMD
     char_u	*au_name =  NULL;
 #endif
+    char_u	title[130] = ":";
 
 #ifdef FEAT_MULTI_LANG
     /* Check for a specified language */
@@ -4088,7 +4224,7 @@
 #endif
 
 	/* create a new quickfix list */
-	qf_new_list(qi, *eap->cmdlinep);
+	qf_new_list(qi, (char_u*)STRNCAT(title, *eap->cmdlinep, (size_t) 128));
 
 	/* Go through all directories in 'runtimepath' */
 	p = p_rtp;

Raspunde prin e-mail lui