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;