On 21-Jul-2010 Bram Moolenaar <b...@moolenaar.net> wrote:
> 
> It would be possible to add a statusline item for this, like %h.
[...]
> Note that I'm including less changes now, and nothing that looks
> "dangerous" or needs to be discussed first.

I followed your excellent advice with a window variable. This made the
whole thing much simpler (the patch is almost 50% smaller than the
previous one).

Since you disliked the repeated code calling buf_spname(), I reverted
buf_spname() to the original shape, which means that no more memory
allocations are needed.

The only thing that is being done now is that the command which produces
a list of errors is remembered along with the quickfix list and when
a quickfix window is opened, the command name is copied to the
w:quickfix_title variable.

Since I also added a flag for the 'statusline' variable, I added a file
ftplugin/qf.vim, which sets 'statusline' for quickfix windows so that
the value of w:quickfix_title is displayed.

The patch is against changeset 878562053b.

-- 
Cheers,
Lech

-- 
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
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 297939f..3ab472d 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -6499,6 +6499,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 	y F   Type of file in the buffer, e.g., "[vim]".  See 'filetype'.
 	Y F   Type of file in the buffer, e.g., ",VIM".  See 'filetype'.
 	      {not available when compiled without |+autocmd| feature}
+	q S   "[Quickfix List]", "[Location List]" or empty.
 	k S   Value of "b:keymap_name" or 'keymap' when |:lmap| mappings are
 	      being used: "<keymap>"
 	n N   Buffer number.
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index d710e97..972ebd8 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -301,7 +301,7 @@ use this code: >
 =============================================================================
 2. The error window					*quickfix-window*
 
-							*:cope* *:copen*
+					    *:cope* *:copen* *w:quickfix_title*
 :cope[n] [height]	Open a window to show the current list of errors.
 			When [height] is given, the window becomes that high
 			(if there is room).  Otherwise the window is made ten
@@ -310,7 +310,11 @@ use this code: >
 			'buftype' equal to "quickfix".  Don't change this!
 			If there already is a quickfix window, it will be made
 			the current window.  It is not possible to open a
-			second quickfix window.
+			second quickfix window. The window will have the
+			w:quickfix_title variable set which will indicate the
+			command that produced the quickfix list. This can be
+			used to compose a custom status line if the value of
+			'statusline' is adjusted properly.
 
 							*:lop* *:lopen*
 :lop[en] [height]	Open a window to show the location list for the
diff --git a/runtime/doc/tags b/runtime/doc/tags
index e36c6a4..1c870b5 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -8280,6 +8280,7 @@ vt100-function-keys	term.txt	/*vt100-function-keys*
 w	motion.txt	/*w*
 w32-clientserver	remote.txt	/*w32-clientserver*
 w:current_syntax	syntax.txt	/*w:current_syntax*
+w:quickfix_title	quickfix.txt	/*w:quickfix_title*
 w:var	eval.txt	/*w:var*
 warningmsg-variable	eval.txt	/*warningmsg-variable*
 white-space	pattern.txt	/*white-space*
diff --git a/runtime/ftplugin/qf.vim b/runtime/ftplugin/qf.vim
new file mode 100644
index 0000000..f1d0922
--- /dev/null
+++ b/runtime/ftplugin/qf.vim
@@ -0,0 +1,16 @@
+" Vim filetype plugin file
+" Language:     Vim's quickfix window
+" Maintainer:   Lech Lorens <lech.lor...@gmail.com>
+" Last Changed: 22 Jul 2010
+
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl stl<"
+
+" Display the command that produced the list in the quickfix window:
+setlocal stl=%q%{exists('w:quickfix_title')?\ '\ '.w:quickfix_title\ :\ ''}
diff --git a/src/buffer.c b/src/buffer.c
index a8808d3..191e2dd 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3869,6 +3869,13 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
 		str = (char_u *)((opt == STL_PREVIEWFLAG_ALT) ? ",PRV"
 							    : _("[Preview]"));
 	    break;
+
+	case STL_QUICKFIX:
+	    if (bt_quickfix(wp->w_buffer))
+		str = (char_u *)wp->w_llist_ref
+			    ? _("[Location List]")
+			    : _("[Quickfix List]");
+	    break;
 #endif
 
 	case STL_MODIFIED:
diff --git a/src/eval.c b/src/eval.c
index a819373..226705e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -395,7 +395,6 @@ static void list_vim_vars __ARGS((int *first));
 static void list_script_vars __ARGS((int *first));
 static void list_func_vars __ARGS((int *first));
 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
-static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
 static int check_changedtick __ARGS((char_u *arg));
 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
 static void clear_lval __ARGS((lval_T *lp));
@@ -2285,7 +2284,7 @@ list_arg_vars(eap, arg, first)
  * Returns a pointer to the char just after the var name.
  * Returns NULL if there is an error.
  */
-    static char_u *
+    char_u *
 ex_let_one(arg, tv, copy, endchars, op)
     char_u	*arg;		/* points to variable name */
     typval_T	*tv;		/* value to assign to variable */
diff --git a/src/if_cscope.c b/src/if_cscope.c
index 8eaa037..8b686cc 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -44,7 +44,7 @@ static void	    cs_file_results __ARGS((FILE *, int *));
 static void	    cs_fill_results __ARGS((char *, int , int *, char ***,
 			char ***, int *));
 static int	    cs_find __ARGS((exarg_T *eap));
-static int	    cs_find_common __ARGS((char *opt, char *pat, int, int, int));
+static int	    cs_find_common __ARGS((char *opt, char *pat, int, int, int, char *cmdline));
 static int	    cs_help __ARGS((exarg_T *eap));
 static void	    clear_csinfo __ARGS((int i));
 static int	    cs_insert_filelist __ARGS((char *, char *, char *,
@@ -294,7 +294,8 @@ do_cstag(eap)
 	if (cs_check_for_connections())
 	{
 	    ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE,
-				 FALSE);
+				 FALSE,
+				 (char *)*eap->cmdlinep);
 	    if (ret == FALSE)
 	    {
 		cs_free_tags();
@@ -322,7 +323,8 @@ do_cstag(eap)
 		if (cs_check_for_connections())
 		{
 		    ret = cs_find_common("g", (char *)(eap->arg), eap->forceit,
-					 FALSE, FALSE);
+					 FALSE, FALSE,
+					 (char *)*eap->cmdlinep);
 		    if (ret == FALSE)
 			cs_free_tags();
 		}
@@ -331,7 +333,8 @@ do_cstag(eap)
 	else if (cs_check_for_connections())
 	{
 	    ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE,
-				 FALSE);
+				 FALSE,
+				 (char *)*eap->cmdlinep);
 	    if (ret == FALSE)
 		cs_free_tags();
 	}
@@ -1068,6 +1071,7 @@ cs_find(eap)
     exarg_T *eap;
 {
     char *opt, *pat;
+    int i;
 
     if (cs_check_for_connections() == FALSE)
     {
@@ -1088,8 +1092,17 @@ cs_find(eap)
 	return FALSE;
     }
 
+    /*
+     * Let's replace the NULs written by strtok() with spaces - we need the
+     * spaces to correctly display the quickfix/location list window's title.
+     */
+    for (i = 0; i < eap_arg_len; ++i)
+	if ('\0' == eap->arg[i])
+	    eap->arg[i] = ' ';
+
     return cs_find_common(opt, pat, eap->forceit, TRUE,
-			  eap->cmdidx == CMD_lcscope);
+			  eap->cmdidx == CMD_lcscope,
+			  (char *)*eap->cmdlinep);
 } /* cs_find */
 
 
@@ -1099,12 +1112,13 @@ cs_find(eap)
  * common code for cscope find, shared by cs_find() and do_cstag()
  */
     static int
-cs_find_common(opt, pat, forceit, verbose, use_ll)
+cs_find_common(opt, pat, forceit, verbose, use_ll, cmdline)
     char *opt;
     char *pat;
     int forceit;
     int verbose;
     int	use_ll;
+    char *cmdline;
 {
     int i;
     char *cmd;
@@ -1257,7 +1271,7 @@ cs_find_common(opt, pat, forceit, verbose, use_ll)
 		wp = curwin;
 	    /* '-' starts a new error list */
 	    if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
-							   *qfpos == '-') > 0)
+							   *qfpos == '-', cmdline) > 0)
 	    {
 # ifdef FEAT_WINDOWS
 		if (postponed_split != 0)
diff --git a/src/main.c b/src/main.c
index 029b64c..bb586a9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -670,7 +670,8 @@ main
 	if (params.use_ef != NULL)
 	    set_string_option_direct((char_u *)"ef", -1,
 					   params.use_ef, OPT_FREE, SID_CARG);
-	if (qf_init(NULL, p_ef, p_efm, TRUE) < 0)
+	vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
+	if (qf_init(NULL, p_ef, p_efm, TRUE, (char *)IObuff) < 0)
 	{
 	    out_char('\n');
 	    mch_exit(3);
diff --git a/src/option.h b/src/option.h
index 817e337..070c023 100644
--- a/src/option.h
+++ b/src/option.h
@@ -271,6 +271,7 @@
 #define STL_PREVIEWFLAG_ALT 'W'		/* - other display */
 #define STL_MODIFIED	'm'		/* modified flag */
 #define STL_MODIFIED_ALT 'M'		/* - other display */
+#define STL_QUICKFIX	'q'		/* quickfix window description */
 #define STL_PERCENTAGE	'p'		/* percentage through file */
 #define STL_ALTPERCENT	'P'		/* percentage as TOP BOT ALL or NN% */
 #define STL_ARGLISTSTAT	'a'		/* argument list status as (x of y) */
@@ -282,7 +283,7 @@
 #define STL_HIGHLIGHT	'#'		/* highlight name */
 #define STL_TABPAGENR	'T'		/* tab page label nr */
 #define STL_TABCLOSENR	'X'		/* tab page close nr */
-#define STL_ALL		((char_u *) "fFtcvVlLknoObBrRhHmYyWwMpPaN{#")
+#define STL_ALL		((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#")
 
 /* flags used for parsed 'wildmode' */
 #define WIM_FULL	1
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 5a85e46..ef20b3f 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -72,6 +72,7 @@ void set_vcount __ARGS((long count, long count1, int set_prevcount));
 void set_vim_var_string __ARGS((int idx, char_u *val, int len));
 void set_vim_var_list __ARGS((int idx, list_T *val));
 void set_reg_var __ARGS((int c));
+char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
 char_u *v_exception __ARGS((char_u *oldval));
 char_u *v_throwpoint __ARGS((char_u *oldval));
 char_u *set_cmdarg __ARGS((exarg_T *eap, char_u *oldarg));
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
index 408bf6d..b2c6219 100644
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -1,5 +1,5 @@
 /* quickfix.c */
-int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist));
+int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist, char *qf_title));
 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));
diff --git a/src/quickfix.c b/src/quickfix.c
index c2543a1..bdd1102 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -56,6 +56,8 @@ typedef struct qf_list_S
     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	*qf_title;	/* title derived from the command that created
+				 * the error list */
 } qf_list_T;
 
 struct qf_info_S
@@ -104,8 +106,8 @@ struct efm_S
     int		    conthere;	/* %> used */
 };
 
-static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
-static void	qf_new_list __ARGS((qf_info_T *qi));
+static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char *qf_title));
+static void	qf_new_list __ARGS((qf_info_T *qi, char *qf_title));
 static void	ll_free_all __ARGS((qf_info_T **pqi));
 static int	qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
 static qf_info_T *ll_new_list __ARGS((void));
@@ -144,15 +146,16 @@ static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *));
 
 /*
  * Read the errorfile "efile" into memory, line by line, building the error
- * list.
+ * list. Set the error list's title to qf_title.
  * Return -1 for error, number of errors for success.
  */
     int
-qf_init(wp, efile, errorformat, newlist)
+qf_init(wp, efile, errorformat, newlist, qf_title)
     win_T	    *wp;
     char_u	    *efile;
     char_u	    *errorformat;
     int		    newlist;		/* TRUE: start a new error list */
+    char	    *qf_title;
 {
     qf_info_T	    *qi = &ql_info;
 
@@ -167,7 +170,8 @@ qf_init(wp, efile, errorformat, newlist)
     }
 
     return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
-						    (linenr_T)0, (linenr_T)0);
+						    (linenr_T)0, (linenr_T)0,
+						    qf_title);
 }
 
 /*
@@ -176,10 +180,11 @@ qf_init(wp, efile, errorformat, newlist)
  * Alternative: when "efile" is null read errors from buffer "buf".
  * Always use 'errorformat' from "buf" if there is a local value.
  * Then lnumfirst and lnumlast specify the range of lines to use.
+ * Set the title of the list to qf_title.
  * Return -1 for error, number of errors for success.
  */
     static int
-qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
+qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast, qf_title)
     qf_info_T	    *qi;
     char_u	    *efile;
     buf_T	    *buf;
@@ -188,6 +193,7 @@ qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
     int		    newlist;		/* TRUE: start a new error list */
     linenr_T	    lnumfirst;		/* first line number to use */
     linenr_T	    lnumlast;		/* last line number to use */
+    char	    *qf_title;
 {
     char_u	    *namebuf;
     char_u	    *errmsg;
@@ -257,12 +263,13 @@ qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
 
     if (newlist || qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list(qi);
+	qf_new_list(qi, qf_title);
     else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
 	/* Adding to existing list, find last entry. */
 	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
-			    qfprev->qf_next != qfprev; qfprev = qfprev->qf_next)
-	    ;
+	     qfprev->qf_next != qfprev;
+	     qfprev = qfprev->qf_next)
+	{ /* do nothing */ }
 
 /*
  * Each part of the format string is copied and modified from errorformat to
@@ -860,8 +867,9 @@ qf_init_end:
  * Prepare for adding a new quickfix list.
  */
     static void
-qf_new_list(qi)
+qf_new_list(qi, qf_title)
     qf_info_T	*qi;
+    char	*qf_title;
 {
     int		i;
 
@@ -888,6 +896,13 @@ qf_new_list(qi)
 	qi->qf_curlist = qi->qf_listcount++;
     qi->qf_lists[qi->qf_curlist].qf_index = 0;
     qi->qf_lists[qi->qf_curlist].qf_count = 0;
+    if (qf_title)
+    {
+	if ((qi->qf_lists[qi->qf_curlist].qf_title = (char *)alloc(STRLEN(qf_title) + 2)))
+	    sprintf(qi->qf_lists[qi->qf_curlist].qf_title, ":%s", qf_title);
+    }
+    else
+	qi->qf_lists[qi->qf_curlist].qf_title = NULL;
 }
 
 /*
@@ -1100,6 +1115,10 @@ copy_loclist(from, to)
 	to_qfl->qf_index = 0;
 	to_qfl->qf_start = NULL;
 	to_qfl->qf_ptr = NULL;
+	if (from_qfl->qf_title)
+	    to_qfl->qf_title = (char *)vim_strsave((char_u *)from_qfl->qf_title);
+	else
+	    to_qfl->qf_title = NULL;
 
 	if (from_qfl->qf_count)
 	{
@@ -2102,6 +2121,7 @@ qf_free(qi, idx)
 	qi->qf_lists[idx].qf_start = qfp;
 	--qi->qf_lists[idx].qf_count;
     }
+    vim_free(qi->qf_lists[idx].qf_title);
 }
 
 /*
@@ -2366,6 +2386,17 @@ ex_copen(eap)
      */
     qf_fill_buffer(qi);
 
+    if (qi->qf_lists[qi->qf_curlist].qf_title)
+    {
+	typval_T rettv;
+	char var_name[] = "w:quickfix_title";
+
+	rettv.v_type = VAR_STRING;
+	rettv.vval.v_string = qi->qf_lists[qi->qf_curlist].qf_title;
+	rettv.v_lock = 0;
+	ex_let_one((char_u *)var_name, &rettv, TRUE, NULL, NULL);
+    }
+
     curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index;
     curwin->w_cursor.col = 0;
     check_cursor();
@@ -2790,7 +2821,8 @@ ex_make(eap)
     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->cmdidx != CMD_lgrepadd),
+					   (char *)*eap->cmdlinep);
 #ifdef FEAT_AUTOCMD
     if (au_name != NULL)
 	apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
@@ -2977,7 +3009,8 @@ ex_cfile(eap)
      * quickfix list then a new list is created.
      */
     if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
-				  && eap->cmdidx != CMD_laddfile)) > 0
+				  && eap->cmdidx != CMD_laddfile),
+		(char *)*eap->cmdlinep) > 0
 				  && (eap->cmdidx == CMD_cfile
 					     || eap->cmdidx == CMD_lfile))
     {
@@ -3085,7 +3118,7 @@ ex_vimgrep(eap)
 	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
 					|| qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list(qi);
+	qf_new_list(qi, (char *)*eap->cmdlinep);
     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;
@@ -3594,7 +3627,7 @@ set_errorlist(wp, list, action)
 
     if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list(qi);
+	qf_new_list(qi, NULL);
     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;
@@ -3725,10 +3758,19 @@ ex_cbuffer(eap)
 	    EMSG(_(e_invrange));
 	else
 	{
+	    char *qf_title = (char *)*eap->cmdlinep;
+	    if (buf->b_sfname)
+	    {
+		vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)", qf_title,
+						  (char *)buf->b_sfname);
+		qf_title = (char *)IObuff;
+	    }
+
 	    if (qf_init_ext(qi, NULL, buf, NULL, p_efm,
 			    (eap->cmdidx != CMD_caddbuffer
 			     && eap->cmdidx != CMD_laddbuffer),
-						   eap->line1, eap->line2) > 0
+						   eap->line1, eap->line2,
+						   qf_title) > 0
 		    && (eap->cmdidx == CMD_cbuffer
 			|| eap->cmdidx == CMD_lbuffer))
 		qf_jump(qi, 0, 0, eap->forceit);  /* display first error */
@@ -3767,7 +3809,8 @@ ex_cexpr(eap)
 	    if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
 			    (eap->cmdidx != CMD_caddexpr
 			     && eap->cmdidx != CMD_laddexpr),
-						 (linenr_T)0, (linenr_T)0) > 0
+						 (linenr_T)0, (linenr_T)0,
+			    (char *)*eap->cmdlinep) > 0
 		    && (eap->cmdidx == CMD_cexpr
 			|| eap->cmdidx == CMD_lexpr))
 		qf_jump(qi, 0, 0, eap->forceit);  /* display first error */
@@ -3837,7 +3880,7 @@ ex_helpgrep(eap)
     if (regmatch.regprog != NULL)
     {
 	/* create a new quickfix list */
-	qf_new_list(qi);
+	qf_new_list(qi, (char *)*eap->cmdlinep);
 
 	/* Go through all directories in 'runtimepath' */
 	p = p_rtp;

Raspunde prin e-mail lui