Hi, On Mon, Apr 13, 2015 at 5:04 AM, <hermi...@free.fr> wrote: > Hello, > > I did not expect that many reactions. This is nice. > Thank you all for your interest in the matter. > >> > Ah, but as long as you are OK with that information showing up in >> > the title, if you can set w:quickfix_title to an arbitrary string, >> > then you *can* store arbitrary data associated with a given >> > quickfix list. >> >> Being able to save "ancillary" data in quickfix lists / loclists >> as the OP suggests would be quite useful too. Then w:quickfix_title >> could be saved there, and that would be easier to implement than >> keeping track of updates to w:quickfix_title. > > Indeed, having "ancillary" data would be much more easier to use. Storing > several variables in the w:quickfix_title wouldn't very practical. Actually, > I want to export several buffer-local variables to the quickfix buffer. I use > some of them to conceal part of the generated error messages, other like > &l:tags are required to be able to jump on definition/declaration from > identifiers found in the error messages, &l:makeprg will be needed in order > to have :make compile the same thing, others variables (like project and > compilation mode) will be displayed in the status(air)line, etc. > > Moreover, I've experienced some odd behaviours regarding the w:quickfix_title > -- as it's automatically set to things like "setqflist()". > > [I can't really comment on the other internal ways of handling quickfix data] > > Thus, I take notice so far that there is no neat way to store variables along > with a quickfix list. An optional data field would do the trick. I guess it > would be more expensive than what I need, but it would do the trick. > > Thank you all anyway. > > I'll try to override the meaning of "nr" field for my needs. >
I am attaching a patch to add the following functions to store and retrieve a context from a location/quickfix list: setqflistctx() getqflistctx() setloclistctx() getloclistctx() The context can be any Vim variable type. The patch also adds the following functions to set/get the title string: setqflisttitle() getqflisttitle() setloclisttitle() getloclisttitle() Let me know if you have any comments/suggestions on these functions. I will add the tests for these functions later. - Yegappan -- -- 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/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 24903f3..069eda9 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2057,10 +2057,14 @@ getftype({fname}) String description of type of file {fname} 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 +getloclistctx({nr}) any location list context +getloclisttitle({nr}) String location list title string 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 +getqflistctx() any quickfix list context +getqflisttitle() String quickfix list title string getreg([{regname} [, 1 [, {list}]]]) String or List contents of register getregtype([{regname}]) String type of register @@ -2217,9 +2221,13 @@ setfperm({fname}, {mode}) Number set {fname} file permissions to {mode} setline({lnum}, {line}) Number set line {lnum} to {line} setloclist({nr}, {list}[, {action}]) Number modify location list using {list} +setloclistctx({nr}, {val}) Number set location list context to {val} +setloclisttitle({nr}, {string}) Number set location list title 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} +setqflistctx({val}) Number set quickfix list context to {val} +setqflisttitle({string}) Number set quickfix list title setreg({n}, {v}[, {opt}]) Number set register to value and type settabvar({nr}, {varname}, {val}) none set {varname} in tab page {nr} to {val} settabwinvar({tabnr}, {winnr}, {varname}, {val}) @@ -4252,6 +4260,18 @@ getloclist({nr}) *getloclist()* returned. For an invalid window number {nr}, an empty list is returned. Otherwise, same as |getqflist()|. +getloclistctx({nr}) *getloclistctx()* + Returns the location list context for window {nr}. For the use + of {nr}, see |getloclist()| above. The location list context is + set using |setloclistctx()|. Returns 0 if the context is not + set or the location list is not present. + +getloclisttitle({nr}) *getloclisttitle()* + Returns the location list title string for window {nr}. For + the use of {nr}, see |getloclist()| above. The location list + title is set using |setloclisttitle()|. Returns an empty string + if the title is not set or the location list is not present. + getmatches() *getmatches()* Returns a |List| with all matches previously defined by |matchadd()| and the |:match| commands. |getmatches()| is @@ -4328,6 +4348,15 @@ getqflist() *getqflist()* : echo bufname(d.bufnr) ':' d.lnum '=' d.text :endfor +getqflistctx() *getqflistctx()* + Returns the quickfix list context. The quickfix list context is + set using |setqflistctx()|. Returns 0 if the context is not + set. + +getqflisttitle() *getqflisttitle()* + Returns the quickfix list title string. The quickfix list title + is set using |setqflisttitle()|. Returns an empty string if the + title is not set. getreg([{regname} [, 1 [, {list}]]]) *getreg()* The result is a String, which is the contents of register @@ -6474,6 +6503,20 @@ setloclist({nr}, {list} [, {action}]) *setloclist()* Otherwise, same as |setqflist()|. Also see |location-list|. +setloclistctx({nr}, {val}) *setloclistctx()* + Sets the location list context for window {nr} to {val}. {val} + can be any Vim variable type (Number, String, List, Dict, etc.) + Returns 0 on success and -1 if the window {nr} is not present. + If the location list is not present for window {nr}, then it + will be created. + +setloclisttitle({nr}, {string}) *setloclisttitle()* + Sets the location list title for window {nr} to {string}. By + default, the title is set to the command that created the + location list. Returns 0 on success and -1 if the window {nr} + is not present. If the location list is not present for window + {nr}, then it will be created. + setmatches({list}) *setmatches()* Restores a list of matches saved by |getmatches()|. Returns 0 if successful, otherwise -1. All current matches are cleared @@ -6578,6 +6621,15 @@ setqflist({list} [, {action}]) *setqflist()* independent of the 'errorformat' setting. Use a command like ":cc 1" to jump to the first position. +setqflistctx({val}) *setqflistctx()* + Sets the quickfix list context to {val}. {val} can be any Vim + variable type (Number, String, List, Dict, etc.). Returns 0 on + success and -1 on error. + +setqflisttitle({string}) *setqflisttitle()* + Sets the quickfix list title to {string}. By default, the title + is set to the command that created the quickfix list. Returns 0 + on success and -1 on error. *setreg()* setreg({regname}, {value} [, {options}]) diff --git a/src/evalfunc.c b/src/evalfunc.c index 07c7575..7a296ee 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -174,6 +174,8 @@ static void f_getpid(typval_T *argvars, typval_T *rettv); static void f_getcurpos(typval_T *argvars, typval_T *rettv); static void f_getpos(typval_T *argvars, typval_T *rettv); static void f_getqflist(typval_T *argvars, typval_T *rettv); +static void f_getqflistctx(typval_T *argvars, typval_T *rettv); +static void f_getqflisttitle(typval_T *argvars, typval_T *rettv); static void f_getreg(typval_T *argvars, typval_T *rettv); static void f_getregtype(typval_T *argvars, typval_T *rettv); static void f_gettabvar(typval_T *argvars, typval_T *rettv); @@ -318,8 +320,12 @@ static void f_setcmdpos(typval_T *argvars, typval_T *rettv); static void f_setfperm(typval_T *argvars, typval_T *rettv); static void f_setline(typval_T *argvars, typval_T *rettv); static void f_setloclist(typval_T *argvars, typval_T *rettv); +static void f_setloclistctx(typval_T *argvars, typval_T *rettv); +static void f_setloclisttitle(typval_T *argvars, typval_T *rettv); static void f_setmatches(typval_T *argvars, typval_T *rettv); static void f_setpos(typval_T *argvars, typval_T *rettv); +static void f_setqflistctx(typval_T *argvars, typval_T *rettv); +static void f_setqflisttitle(typval_T *argvars, typval_T *rettv); static void f_setqflist(typval_T *argvars, typval_T *rettv); static void f_setreg(typval_T *argvars, typval_T *rettv); static void f_settabvar(typval_T *argvars, typval_T *rettv); @@ -585,10 +591,14 @@ static struct fst {"getftype", 1, 1, f_getftype}, {"getline", 1, 2, f_getline}, {"getloclist", 1, 1, f_getqflist}, + {"getloclistctx", 1, 1, f_getqflistctx}, + {"getloclisttitle", 1, 1, f_getqflisttitle}, {"getmatches", 0, 0, f_getmatches}, {"getpid", 0, 0, f_getpid}, {"getpos", 1, 1, f_getpos}, {"getqflist", 0, 0, f_getqflist}, + {"getqflistctx", 0, 0, f_getqflistctx}, + {"getqflisttitle", 0, 0, f_getqflisttitle}, {"getreg", 0, 3, f_getreg}, {"getregtype", 0, 1, f_getregtype}, {"gettabvar", 2, 3, f_gettabvar}, @@ -735,9 +745,13 @@ static struct fst {"setfperm", 2, 2, f_setfperm}, {"setline", 2, 2, f_setline}, {"setloclist", 2, 3, f_setloclist}, + {"setloclistctx", 2, 2, f_setloclistctx}, + {"setloclisttitle", 2, 2, f_setloclisttitle}, {"setmatches", 1, 1, f_setmatches}, {"setpos", 2, 2, f_setpos}, {"setqflist", 1, 2, f_setqflist}, + {"setqflistctx", 1, 1, f_setqflistctx}, + {"setqflisttitle", 1, 1, f_setqflisttitle}, {"setreg", 2, 3, f_setreg}, {"settabvar", 3, 3, f_settabvar}, {"settabwinvar", 4, 4, f_settabwinvar}, @@ -4611,6 +4625,59 @@ f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) } /* + * "getqflistctx()" and "getloclistctx()" functions + */ + static void +f_getqflistctx(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ +#ifdef FEAT_QUICKFIX + win_T *wp = NULL; + typval_T *ctx; +#endif + +#ifdef FEAT_QUICKFIX + if (argvars[0].v_type != VAR_UNKNOWN) /* getloclistctx() */ + { + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + } + + ctx = get_errorlist_ctx(wp); + if (ctx != NULL) + copy_tv(ctx, rettv); +#endif +} + +/* + * "getqflisttitle()" and "getloclisttitle()" functions + */ + static void +f_getqflisttitle(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ +#ifdef FEAT_QUICKFIX + win_T *wp = NULL; + char_u *s; +#endif + +#ifdef FEAT_QUICKFIX + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + if (argvars[0].v_type != VAR_UNKNOWN) /* getloclisttitle() */ + { + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + } + + s = qf_get_title(wp); + if (s != NULL) + rettv->vval.v_string = vim_strsave(s); +#endif +} + +/* * "getreg()" function */ static void @@ -9508,6 +9575,58 @@ f_setloclist(typval_T *argvars, typval_T *rettv) } /* + * "setloclistctx()" function + */ + static void +f_setloclistctx(typval_T *argvars, typval_T *rettv) +{ + win_T *win; + + rettv->vval.v_number = -1; + + win = find_win_by_nr(&argvars[0], NULL); + if (win != NULL) + if (set_errorlist_ctx(win, &argvars[1]) == OK) + rettv->vval.v_number = 0; +} + + static void +set_qf_ll_title( + win_T *wp UNUSED, + typval_T *title_arg UNUSED, + typval_T *rettv) +{ + char_u *s; + + rettv->vval.v_number = -1; + if (title_arg->v_type != VAR_STRING) + { + EMSG(_(e_stringreq)); + return; + } + s = get_tv_string_chk(title_arg); + if (s == NULL) + return; + + if (set_errorlist_title(wp, s) == OK) + rettv->vval.v_number = 0; +} + +/* + * "setloclisttitle()" function + */ + static void +f_setloclisttitle(typval_T *argvars, typval_T *rettv) +{ + win_T *win; + + rettv->vval.v_number = -1; + win = find_win_by_nr(&argvars[0], NULL); + if (win != NULL) + set_qf_ll_title(win, &argvars[1], rettv); +} + +/* * "setmatches()" function */ static void @@ -9674,6 +9793,26 @@ f_setqflist(typval_T *argvars, typval_T *rettv) } /* + * "setqflistctx()" function + */ + static void +f_setqflistctx(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = -1; + if (set_errorlist_ctx(NULL, &argvars[0]) == OK) + rettv->vval.v_number = 0; +} + +/* + * "setqflisttitle()" function + */ + static void +f_setqflisttitle(typval_T *argvars, typval_T *rettv) +{ + set_qf_ll_title(NULL, &argvars[0], rettv); +} + +/* * "setreg()" function */ static void diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro index 02c2d98..a6914d4 100644 --- a/src/proto/quickfix.pro +++ b/src/proto/quickfix.pro @@ -1,5 +1,6 @@ /* quickfix.c */ int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title); +char_u *qf_get_title(win_T *wp); void qf_free_all(win_T *wp); void copy_loclist(win_T *from, win_T *to); void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit); @@ -28,7 +29,10 @@ void ex_cfile(exarg_T *eap); void ex_vimgrep(exarg_T *eap); char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags); int get_errorlist(win_T *wp, list_T *list); +typval_T *get_errorlist_ctx(win_T *wp); int set_errorlist(win_T *wp, list_T *list, int action, char_u *title); +int set_errorlist_ctx(win_T *wp, typval_T *ctx); +int set_errorlist_title(win_T *wp, char_u *title); void ex_cbuffer(exarg_T *eap); void ex_cexpr(exarg_T *eap); void ex_helpgrep(exarg_T *eap); diff --git a/src/quickfix.c b/src/quickfix.c index 3794e6a..4be29df 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -57,6 +57,7 @@ typedef struct qf_list_S int qf_nonevalid; /* TRUE if not a single valid entry found */ char_u *qf_title; /* title derived from the command that created * the error list */ + typval_T *qf_ctx; /* context set by setqflistctx() */ } qf_list_T; struct qf_info_S @@ -1303,6 +1304,22 @@ qf_store_title(qf_info_T *qi, char_u *title) } } +/* Return the quickfix/location list title */ + char_u * +qf_get_title(win_T *wp) +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + { + qi = GET_LOC_LIST(wp); + if (qi == NULL) + return NULL; + } + + return qi->qf_lists[qi->qf_curlist].qf_title; +} + /* * Prepare for adding a new quickfix list. */ @@ -1554,6 +1571,14 @@ copy_loclist(win_T *from, win_T *to) to_qfl->qf_title = vim_strsave(from_qfl->qf_title); else to_qfl->qf_title = NULL; + if (from_qfl->qf_ctx != NULL) + { + to_qfl->qf_ctx = alloc_tv(); + if (to_qfl->qf_ctx != NULL) + copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx); + } + else + to_qfl->qf_ctx = NULL; if (from_qfl->qf_count) { @@ -2701,6 +2726,8 @@ qf_free(qf_info_T *qi, int idx) } vim_free(qi->qf_lists[idx].qf_title); qi->qf_lists[idx].qf_title = NULL; + free_tv(qi->qf_lists[idx].qf_ctx); + qi->qf_lists[idx].qf_ctx = NULL; qi->qf_lists[idx].qf_index = 0; qf_clean_dir_stack(&qi->qf_dir_stack); @@ -4591,6 +4618,22 @@ get_errorlist(win_T *wp, list_T *list) return OK; } +/* Return the quickfix/location list context */ + typval_T * +get_errorlist_ctx(win_T *wp) +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + { + qi = GET_LOC_LIST(wp); + if (qi == NULL) + return NULL; + } + + return qi->qf_lists[qi->qf_curlist].qf_ctx; +} + /* * Populate the quickfix list with the items supplied in the list * of dictionaries. "title" will be copied to w:quickfix_title. @@ -4721,6 +4764,46 @@ set_errorlist( return retval; } + +/* Set quickfix/location list context */ + int +set_errorlist_ctx(win_T *wp, typval_T *ctx) +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + { + qi = ll_get_or_alloc_list(wp); + if (qi == NULL) + return FAIL; + } + + free_tv(qi->qf_lists[qi->qf_curlist].qf_ctx); + qi->qf_lists[qi->qf_curlist].qf_ctx = alloc_tv(); + if (qi->qf_lists[qi->qf_curlist].qf_ctx != NULL) + copy_tv(ctx, qi->qf_lists[qi->qf_curlist].qf_ctx); + + return OK; +} + +/* Set quickfix/location list title */ + int +set_errorlist_title(win_T *wp, char_u *title) +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + { + qi = ll_get_or_alloc_list(wp); + if (qi == NULL) + return FAIL; + } + + vim_free(qi->qf_lists[qi->qf_curlist].qf_title); + qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(title); + + return OK; +} #endif /*