On 11-Apr-2010 Bram Moolenaar <[email protected]> wrote:
> 
> I hope to bring out a first beta version by the end of May.  That gives
> everybody time to send me updated and polished patches and runtime
> files.  I need to have these halfway May, I also need some time to
> integrate everything.

I attached a patch enabling the quickfix window titles which I sent to
vim-dev about a year ago. This is against Vim 7.2.411.

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

Subscription settings: http://groups.google.com/group/vim_dev/subscribe?hl=en
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index c87e61c..15becb7 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -505,6 +505,7 @@ followed by another Vim command:
     :bufdo
     :command
     :cscope
+    :csettitle
     :debug
     :folddoopen
     :folddoclosed
@@ -513,6 +514,7 @@ followed by another Vim command:
     :help
     :helpfind
     :lcscope
+    :lsettitle
     :make
     :normal
     :perl
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index afe1513..6d131ac 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1147,6 +1147,7 @@ The commands are sorted on the non-optional part of their name.
 |:cquit|	:cq[uit]	quit Vim with an error code
 |:crewind|	:cr[ewind]	go to the specified error, default first one
 |:cscope|	:cs[cope]       execute cscope command
+|:csettitle|	:cse[ttitle]	change the title of the quickfix window
 |:cstag|	:cst[ag]	use cscope to jump to a tag
 |:cunmap|	:cu[nmap]	like ":unmap" but for Command-line mode
 |:cunabbrev|	:cuna[bbrev]	like ":unabbrev" but for Command-line mode
@@ -1296,6 +1297,7 @@ The commands are sorted on the non-optional part of their name.
 |:lpfile|	:lpf[ile]	go to last location in previous file
 |:lrewind|	:lr[ewind]	go to the specified location, default first one
 |:ls|		:ls		list all buffers
+|:lsettitle|	:lse[ttitle]	like ":csettitle" but use the location list
 |:ltag|		:lt[ag]		jump to tag and add matching tags to the
 				location list
 |:lunmap|	:lu[nmap]	like ":unmap!" but includes Lang-Arg mode
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 6734170..15f9296 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -310,7 +310,8 @@ 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's title will
+			indicate the command used to get the list of errors.
 
 							*:lop* *:lopen*
 :lop[en] [height]	Open a window to show the location list for the
@@ -335,6 +336,22 @@ use this code: >
 :lw[indow] [height]	Same as ":cwindow", except use the window showing the
 			location list for the current window.
 
+							*:cse* *:csettitle*
+:cse[ttitle] [arguments]
+			Change the title of the quickfix window. If no
+			arguments are provided, the title will be cleared.
+:cse[ttitle]!
+			Reset the quickfix window's title to the default
+			value.
+
+							*:lse* *:lsettitle*
+:lse[ttitle] [arguments]
+			Same as ":csettitle" but acts on the location list
+			window.
+:lse[ttitle]!
+			Reset the location window's title to the default
+			value.
+
 Normally the quickfix window is at the bottom of the screen.  If there are
 vertical splits, it's at the bottom of the rightmost column of windows.  To
 make it always occupy the full width: >
diff --git a/runtime/doc/tags b/runtime/doc/tags
index cf872e7..36d1b82 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -1991,6 +1991,8 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 :crewind	quickfix.txt	/*:crewind*
 :cs	if_cscop.txt	/*:cs*
 :cscope	if_cscop.txt	/*:cscope*
+:cse	quickfix.txt	/*:cse*
+:csettitle	quickfix.txt	/*:csettitle*
 :cstag	if_cscop.txt	/*:cstag*
 :cu	map.txt	/*:cu*
 :cuna	map.txt	/*:cuna*
@@ -2315,6 +2317,8 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 :lr	quickfix.txt	/*:lr*
 :lrewind	quickfix.txt	/*:lrewind*
 :ls	windows.txt	/*:ls*
+:lse	quickfix.txt	/*:lse*
+:lsettitle	quickfix.txt	/*:lsettitle*
 :lt	tagsrch.txt	/*:lt*
 :ltag	tagsrch.txt	/*:ltag*
 :lu	map.txt	/*:lu*
diff --git a/src/buffer.c b/src/buffer.c
index 0569f16..1f0bb72 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2548,6 +2548,7 @@ buflist_list(eap)
     buf_T	*buf;
     int		len;
     int		i;
+    char_u	*bname;
 
     for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next)
     {
@@ -2555,8 +2556,11 @@ buflist_list(eap)
 	if (!buf->b_p_bl && !eap->forceit)
 	    continue;
 	msg_putchar('\n');
-	if (buf_spname(buf) != NULL)
-	    STRCPY(NameBuff, buf_spname(buf));
+	if ((bname = (char_u *)buf_spname(buf)) != NULL)
+	{
+	    vim_strncpy(NameBuff, bname, MAXPATHL - 1);
+	    vim_free(bname);
+	}
 	else
 	    home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
 
@@ -2963,6 +2967,7 @@ fileinfo(fullname, shorthelp, dont_truncate)
     char_u	*p;
     char_u	*buffer;
     size_t	len;
+    char_u	*bname;
 
     buffer = alloc(IOSIZE);
     if (buffer == NULL)
@@ -2977,8 +2982,11 @@ fileinfo(fullname, shorthelp, dont_truncate)
 	p = buffer;
 
     *p++ = '"';
-    if (buf_spname(curbuf) != NULL)
-	STRCPY(p, buf_spname(curbuf));
+    if ((bname = (char_u *)buf_spname(curbuf)) != NULL)
+    {
+	vim_strncpy(p, bname, (size_t)(IOSIZE - (p - buffer) - 1));
+	vim_free(bname);
+    }
     else
     {
 	if (!fullname && curbuf->b_fname != NULL)
@@ -3262,8 +3270,9 @@ maketitle()
 	}
 	else
 	{
-	    if (buf_spname(curbuf) != NULL)
-		i_name = (char_u *)buf_spname(curbuf);
+	    char_u *bname;
+	    if ((bname = (char_u *)buf_spname(curbuf)) != NULL)
+		i_name = bname;
 	    else		    /* use file name only in icon */
 		i_name = gettail(curbuf->b_ffname);
 	    *i_str = NUL;
@@ -3279,6 +3288,7 @@ maketitle()
 		i_name += len;
 	    }
 	    STRCPY(i_str, i_name);
+	    vim_free(bname);
 	    trans_characters(i_str, IOSIZE);
 	}
     }
@@ -3382,6 +3392,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
     int		curitem;
     int		groupitem[STL_MAX_ITEM];
     int		groupdepth;
+    char_u	*bname;
     struct stl_item
     {
 	char_u		*start;
@@ -3663,8 +3674,11 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
 	case STL_FULLPATH:
 	case STL_FILENAME:
 	    fillable = FALSE;	/* don't change ' ' to fillchar */
-	    if (buf_spname(wp->w_buffer) != NULL)
-		STRCPY(NameBuff, buf_spname(wp->w_buffer));
+	    if ((bname = (char_u *)buf_spname(wp->w_buffer)) != NULL)
+	    {
+		vim_strncpy(NameBuff, bname, MAXPATHL - 1);
+		vim_free(bname);
+	    }
 	    else
 	    {
 		t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
@@ -5098,6 +5112,10 @@ buf_spname(buf)
 #if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
     if (bt_quickfix(buf))
     {
+	char	    *qlname;
+	const char  *bt_name;
+	size_t	    len;
+	char	    *ret_ptr;
 	win_T	    *win = NULL;
 	tabpage_T   *tp;
 
@@ -5110,9 +5128,30 @@ buf_spname(buf)
 		goto win_found;
 win_found:
 	if (win != NULL && win->w_llist_ref != NULL)
-	    return _("[Location List]");
+	{
+	    qlname = qf_get_name(win->w_llist_ref);
+	    bt_name = _("[Location List]");
+	}
 	else
-	    return _("[Quickfix List]");
+	{
+	    qlname = qf_get_name(NULL);
+	    bt_name = _("[Quickfix List]");
+	}
+
+	len = STRLEN(bt_name);
+	if (qlname)
+	{
+	    len += STRLEN(qlname);
+	    ret_ptr = (char *)alloc(len + 2);
+	    sprintf(ret_ptr, "%s %s", bt_name,
+				      qlname);
+	}
+	else
+	{
+	    ret_ptr = (char *)alloc(len + 1);
+	    sprintf(ret_ptr, "%s", bt_name);
+	}
+	return ret_ptr;
     }
 #endif
 #ifdef FEAT_QUICKFIX
@@ -5121,12 +5160,12 @@ win_found:
     if (bt_nofile(buf))
     {
 	if (buf->b_sfname != NULL)
-	    return (char *)buf->b_sfname;
-	return _("[Scratch]");
+	    return (char *)vim_strsave(buf->b_sfname);
+	return (char *)vim_strsave((char_u *)_("[Scratch]"));
     }
 #endif
     if (buf->b_fname == NULL)
-	return _("[No Name]");
+	return (char *)vim_strsave((char_u *)_("[No Name]"));
     return NULL;
 }
 
diff --git a/src/edit.c b/src/edit.c
index 33e580f..e2bbb69 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -3901,6 +3901,7 @@ ins_compl_get_exp(ini)
     char_u	*dict = NULL;
     int		dict_f = 0;
     compl_T	*old_match;
+    char    	*bname;
 
     if (!compl_started)
     {
@@ -3960,12 +3961,14 @@ ins_compl_get_exp(ini)
 		    dict = ins_buf->b_fname;
 		    dict_f = DICT_EXACT;
 		}
+		bname = NULL;
 		vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"),
 			ins_buf->b_fname == NULL
-			    ? buf_spname(ins_buf)
+			    ? (bname = buf_spname(ins_buf))
 			    : ins_buf->b_sfname == NULL
 				? (char *)ins_buf->b_fname
 				: (char *)ins_buf->b_sfname);
+		vim_free(bname);
 		(void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
 	    }
 	    else if (*e_cpt == NUL)
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index bf66b40..ee0496b 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -279,6 +279,8 @@ EX(CMD_crewind,		"crewind",	ex_cc,
 			RANGE|NOTADR|COUNT|TRLBAR|BANG),
 EX(CMD_cscope,		"cscope",	do_cscope,
 			EXTRA|NOTRLCOM|XFILE),
+EX(CMD_csettitle,	"csettitle",	ex_csettitle,
+			BANG|EXTRA|SBOXOK|CMDWIN),
 EX(CMD_cstag,		"cstag",	do_cstag,
 			BANG|TRLBAR|WORD1),
 EX(CMD_cunmap,		"cunmap",	ex_unmap,
@@ -581,6 +583,8 @@ EX(CMD_lwindow,		"lwindow",	ex_cwindow,
 			RANGE|NOTADR|COUNT|TRLBAR),
 EX(CMD_ls,		"ls",		buflist_list,
 			BANG|TRLBAR|CMDWIN),
+EX(CMD_lsettitle,	"lsettitle",	ex_csettitle,
+			BANG|EXTRA|SBOXOK|CMDWIN),
 EX(CMD_move,		"move",		ex_copymove,
 			RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
 EX(CMD_mark,		"mark",		ex_mark,
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 92451b5..667aaa8 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1592,6 +1592,7 @@ check_changed_any(hidden)
 #ifdef FEAT_WINDOWS
     win_T	*wp;
 #endif
+    char_u	*bname;
 
     for (;;)
     {
@@ -1632,14 +1633,15 @@ check_changed_any(hidden)
 	    msg_didout = FALSE;
 	}
 	if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
-		    buf_spname(buf) != NULL ? (char_u *)buf_spname(buf) :
-		    buf->b_fname))
+		    (bname = (char_u *)buf_spname(buf)) != NULL ? bname :
+								  buf->b_fname))
 	{
 	    save = no_wait_return;
 	    no_wait_return = FALSE;
 	    wait_return(FALSE);
 	    no_wait_return = save;
 	}
+	vim_free(bname);
     }
 
 #ifdef FEAT_WINDOWS
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index f8795fa..99c4ca4 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -121,6 +121,7 @@ static int	getargopt __ARGS((exarg_T *eap));
 # define ex_cclose		ex_ni
 # define ex_copen		ex_ni
 # define ex_cwindow		ex_ni
+# define ex_csettitle		ex_ni
 #endif
 #if !defined(FEAT_QUICKFIX) || !defined(FEAT_EVAL)
 # define ex_cexpr		ex_ni
@@ -7302,6 +7303,7 @@ ex_tabs(eap)
     tabpage_T	*tp;
     win_T	*wp;
     int		tabcount = 1;
+    char_u	*bname;
 
     msg_start();
     msg_scroll = TRUE;
@@ -7324,8 +7326,11 @@ ex_tabs(eap)
 	    msg_putchar(' ');
 	    msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' ');
 	    msg_putchar(' ');
-	    if (buf_spname(wp->w_buffer) != NULL)
-		STRCPY(IObuff, buf_spname(wp->w_buffer));
+	    if ((bname = (char_u *)buf_spname(wp->w_buffer)) != NULL)
+	    {
+		vim_strncpy(IObuff, bname, IOSIZE - 1);
+		vim_free(bname);
+	    }
 	    else
 		home_replace(wp->w_buffer, wp->w_buffer->b_fname,
 							IObuff, IOSIZE, TRUE);
diff --git a/src/hardcopy.c b/src/hardcopy.c
index 0e7ee4d..83ab74f 100644
--- a/src/hardcopy.c
+++ b/src/hardcopy.c
@@ -567,6 +567,8 @@ ex_hardcopy(eap)
     long_u		bytes_to_print = 0;
     int			page_line;
     int			jobsplit;
+    char_u		*bname = NULL;
+    int			do_return = FALSE;
 
     memset(&settings, 0, sizeof(prt_settings_T));
     settings.has_color = TRUE;
@@ -598,11 +600,15 @@ ex_hardcopy(eap)
      */
     if (mch_print_init(&settings,
 			curbuf->b_fname == NULL
-			    ? (char_u *)buf_spname(curbuf)
+			    ? (bname = (char_u *)buf_spname(curbuf))
 			    : curbuf->b_sfname == NULL
 				? curbuf->b_fname
 				: curbuf->b_sfname,
 			eap->forceit) == FAIL)
+	do_return = TRUE;
+
+    vim_free(bname);
+    if (do_return)
 	return;
 
 #ifdef FEAT_SYN_HL
diff --git a/src/if_cscope.c b/src/if_cscope.c
index b8fef28..1ed9e86 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;
@@ -1209,7 +1223,7 @@ cs_find_common(opt, pat, forceit, verbose, use_ll)
     if (qfpos != NULL)
     {
 	qfpos++;
-	/* next symbol must be + or - */
+	/* next symbol must be +, - or 0 */
 	if (strchr(CSQF_FLAGS, *qfpos) == NULL)
 	{
 	    char *nf = _("E469: invalid cscopequickfix flag %c for %c");
@@ -1245,7 +1259,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 4e027ab..a838bd8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -678,7 +678,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/memline.c b/src/memline.c
index 102b61e..d1d856f 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -587,12 +587,14 @@ ml_open_file(buf)
 
     if (mfp->mf_fname == NULL)		/* Failed! */
     {
+	char_u *bname = (char_u *)buf_spname(buf);
 	need_wait_return = TRUE;	/* call wait_return later */
 	++no_wait_return;
 	(void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
-		    buf_spname(buf) != NULL
-			? (char_u *)buf_spname(buf)
+		    bname
+			? bname
 			: buf->b_fname);
+	vim_free(bname);
 	--no_wait_return;
     }
 
@@ -867,6 +869,7 @@ ml_recover()
     int		serious_error = TRUE;
     long	mtime;
     int		attr;
+    char_u	*bname;
 
     recoverymode = TRUE;
     called_from_main = (curbuf->b_ml.ml_mfp == NULL);
@@ -1070,8 +1073,11 @@ ml_recover()
     home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
     smsg((char_u *)_("Using swap file \"%s\""), NameBuff);
 
-    if (buf_spname(curbuf) != NULL)
-	STRCPY(NameBuff, buf_spname(curbuf));
+    if ((bname = (char_u *)buf_spname(curbuf)) != NULL)
+    {
+	vim_strncpy(NameBuff, bname, MAXPATHL - 1);
+	vim_free(bname);
+    }
     else
 	home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
     smsg((char_u *)_("Original file \"%s\""), NameBuff);
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
index 408bf6d..cca2ee2 100644
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -1,5 +1,7 @@
 /* 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));
+char* qf_get_name __ARGS((qf_info_T *qi));
+void  ex_csettitle __ARGS((exarg_T *eap));
 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 8537a7c..4ffa7bd 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -51,11 +51,20 @@ struct qfline_S
 
 typedef struct qf_list_S
 {
-    qfline_T	*qf_start;	/* pointer to the first 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 */
+    qfline_T	*qf_start;	    /* pointer to the first 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	*qf_title;	    /* title derived from the command that created
+				     * the error list
+				     */
+    char        *qf_user_title;     /* title specified by the :csettitle or
+				     * :lsettitle command
+				     */
+    int		qf_use_user_title;  /* indicates that qf_user_title should
+				     * be used instead of qf_title
+				     */
 } qf_list_T;
 
 struct qf_info_S
@@ -104,8 +113,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 +153,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 +177,86 @@ 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);
+}
+
+/*
+ * Returns the title of the qf_info_T's current qf_list_T.
+ */
+    char*
+qf_get_name(qi)
+    qf_info_T *qi;
+{
+    if (!qi)
+	qi = &ql_info;
+
+    if (qi->qf_lists[qi->qf_curlist].qf_use_user_title)
+	return qi->qf_lists[qi->qf_curlist].qf_user_title;
+
+    return qi->qf_lists[qi->qf_curlist].qf_title;
+}
+
+/*
+ * Sets the title of a quickfix window / location list window.
+ */
+    void
+ex_csettitle(eap)
+    exarg_T	*eap;
+{
+    qf_info_T	*list_ref;
+    win_T	*win;
+    char_u	*err_msg;
+
+    if (eap->cmdidx == CMD_csettitle)
+    {
+	list_ref = &ql_info;
+	err_msg = e_quickfix;
+    }
+    else
+    {
+	list_ref = GET_LOC_LIST(curwin);
+	err_msg = e_loclist;
+    }
+
+    if (!list_ref || !list_ref->qf_listcount)
+    {
+	EMSG(_(err_msg));
+	return;
+    }
+
+    if (eap->forceit)
+    {
+	if (!list_ref->qf_lists[list_ref->qf_curlist].qf_use_user_title)
+	    return;
+
+	/* restore the title derived from the command that created the error list */
+	vim_free(list_ref->qf_lists[list_ref->qf_curlist].qf_user_title);
+	list_ref->qf_lists[list_ref->qf_curlist].qf_user_title = NULL;
+	list_ref->qf_lists[list_ref->qf_curlist].qf_use_user_title = FALSE;
+    }
+    else
+    {
+	/* set the user's title */
+	vim_free(list_ref->qf_lists[list_ref->qf_curlist].qf_user_title);
+
+	if (eap->arg && *eap->arg != NUL)
+	    list_ref->qf_lists[list_ref->qf_curlist].qf_user_title = (char *)vim_strsave(eap->arg);
+	else
+	    list_ref->qf_lists[list_ref->qf_curlist].qf_user_title = NULL;
+
+	list_ref->qf_lists[list_ref->qf_curlist].qf_use_user_title = TRUE;
+    }
+
+    if (eap->cmdidx == CMD_csettitle)
+	list_ref = NULL;
+
+    need_maketitle = TRUE;
+    FOR_ALL_WINDOWS(win)
+    {
+	if (bt_quickfix(win->w_buffer) && list_ref == win->w_llist_ref)
+	    win_redr_status(win);
+    }
 }
 
 /*
@@ -176,10 +265,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 +278,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 +348,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 +952,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 +981,16 @@ 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;
+
+    qi->qf_lists[qi->qf_curlist].qf_user_title = NULL;
+    qi->qf_lists[qi->qf_curlist].qf_use_user_title = FALSE;
 }
 
 /*
@@ -1100,6 +1203,16 @@ 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_user_title)
+	    to_qfl->qf_user_title = (char *)vim_strsave((char_u *)from_qfl->qf_user_title);
+	else
+	    to_qfl->qf_user_title = NULL;
+	to_qfl->qf_use_user_title = from_qfl->qf_use_user_title;
 
 	if (from_qfl->qf_count)
 	{
@@ -2102,6 +2215,8 @@ 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);
+    vim_free(qi->qf_lists[idx].qf_user_title);
 }
 
 /*
@@ -2790,7 +2905,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,
@@ -2965,7 +3081,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))
     {
@@ -3073,7 +3190,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;
@@ -3582,7 +3699,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;
@@ -3709,10 +3826,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 */
@@ -3751,7 +3877,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 */
@@ -3821,7 +3948,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;
diff --git a/src/screen.c b/src/screen.c
index 7f929ac..bfc7fdf 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -9431,8 +9431,12 @@ draw_tabline()
 get_trans_bufname(buf)
     buf_T	*buf;
 {
-    if (buf_spname(buf) != NULL)
-	STRCPY(NameBuff, buf_spname(buf));
+    char_u *bname = (char_u *)buf_spname(buf);
+    if (bname)
+    {
+	vim_strncpy(NameBuff, bname, MAXPATHL - 1);
+	vim_free(bname);
+    }
     else
 	home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
     trans_characters(NameBuff, MAXPATHL);

Raspunde prin e-mail lui