On 21-Jul-2010 Bram Moolenaar <[email protected]> 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 <[email protected]>
+" 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;