Hi LCD! On Mi, 22 Mai 2013, LCD 47 wrote: > On 22 May 2013, LCD 47 <lcd...@gmail.com> wrote: > [...] > > Excellent, thank you! I'll play with it for a while, then post my > > conclusions. > > There seems to be a bug in getlocstack(), it misses the first entry. > Example: after a single run of syntastic check: > > :echo len(getlocstack(0)) > 3 > > :echo len(getloctitle(0)) > 4 > Here getloctitle() seems to work correctly.
I don't see this. How did you make this? (I only checked by calling :setloclist(0, [...]) several times and not sure how to make syntastic do this. > Also getlocstackptr() should probably return -1 rather than 0 if the > stack is empty (calling getlocstack() to find out is expensive in > terms of memory). Ok. Updated the patch. > I haven't looked at setlocstack() and getqf*() / setqf*(). > > There are a few mistakes and omissions in the manual: > > (1) getlocstackptr() and getloctitle() take an argument, while > getqfstack() doesn't; > (2) the arguments for the new functions are not described; > (3) it's not clear if the stack pointers are 0- or 1-based. Ok, seems I mixed up the documentation yesterday. I have updated it now. > > From the point of view of design, I still claim it would have been > cleaner to assign handle IDs to loclists, the same way it's done for > buffers, windows, tabs, and basically everything else. It would have > allowed to solve the last piece of the puzzle, namely converting between > the current window, the associated loclist, and the associated loclist > window: these might all have been attributes of the loclists. > > Without handle IDs, you basically have to use the stack to point > functions to the relevant loclist. This works, but it's a rather ugly > hack, and it doesn't extend easily to finding, say, the loclist window > associated to the current window. I have still no idea how to approach this yet. regards, Christian -- -- -- 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/groups/opt_out.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1793,10 +1793,16 @@ 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 +getlocstack( {nr}) List stack of location lists +getlocstackptr( {nr}) Number Returns index of current location list in stack +getloctitle( {nr}) Lists Returns list of titles for location list stack 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 +getqfstack() List stack of quickfix lists +getqfstackptr() Number Returns index of current quickfix list in stack +getqftitle() Lists Returns list of titles for quickfix list stack getreg( [{regname} [, 1]]) String contents of register getregtype( [{regname}]) String type of register gettabvar( {nr}, {varname} [, {def}]) @@ -1924,11 +1930,18 @@ setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val} setcmdpos( {pos}) Number set cursor position in command-line setline( {lnum}, {line}) Number set line {lnum} to {line} -setloclist( {nr}, {list}[, {action}]) +setloclist( {nr}, {list}[, {action}[, {title}]]) Number modify location list using {list} +setloctitle( {nr}, {string}) Number set the |w:quickfix_title| for the + current location list. +setlocstackptr( {nr}, {nr}) Number moves within the location list stack. 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} +setqflist( {list}[, {action}[, {title}]]) + Number modify quickfix list using {list} +setqfstackptr( {nr}) Number moves within the quickfix stack. +setqftitle( {string}) Number set the |w:quickfix_title| for the + current quickfix list. setreg( {n}, {v}[, {opt}]) Number set register to value and type settabvar( {nr}, {varname}, {val}) set {varname} in tab page {nr} to {val} settabwinvar( {tabnr}, {winnr}, {varname}, {val}) set {varname} in window @@ -3365,6 +3378,28 @@ returned. For an invalid window number {nr}, an empty list is returned. Otherwise, same as |getqflist()|. + +getlocstack({nr}) *getlocstack()* + Returns a list with the stack of the location lists for window + {nr}. When {nr} is zero the current window is used. The + location list can currently handle 10 different error list, + which can be traversed by using |:lolder| and |:lnewer|. The + getlocstack() function returns the complete stack of those + quickfix lists. + +getlocstackptr({nr}) *getlocstackptr()* + Returns the index within the stack of the location lists for window + {nr}. When {nr} is zero the current window is used. The + index can be used with the |getlocstack()| function to access the current + active list. Index is in the range 0 - 9 + On error, or for an empty stack, -1 is returned. + +getloctitle({nr}) *getloctitle()* + Returns a list containing the title for each of the location + lists in window {nr} in the stack. When {nr} is zero, the + current window is used. The title will also available in the + |w:quickfix_title| variable of the location list. + getmatches() *getmatches()* Returns a |List| with all matches previously defined by |matchadd()| and the |:match| commands. |getmatches()| is @@ -3387,7 +3422,7 @@ :unlet m < -getqflist() *getqflist()* +getqflist() *getqflist()* Returns a list with all the current quickfix errors. Each list item is a dictionary with these entries: bufnr number of buffer that has the file name, use @@ -3413,6 +3448,25 @@ : echo bufname(d.bufnr) ':' d.lnum '=' d.text :endfor +getqfstack() *getqfstack()* + Returns a list with the stack of the quickfix lists. The + quickfix list can currently handle 10 different error list, + which can be traversed by using |:colder| and |:cnewer|. The + getqfstack() function returns the complete stack of those + quickfix lists. + +getqfstackptr() *getqfstackptr()* + Returns the index of the quickfix stack, that can be used with + the |getqfstack()| function to access the current active list. + The index goes from 0 for the oldes entry up to a + maximum of 9 since the stack can currently hold up to 10 + items. + On error, or for an empty stack, -1 is returned. + +getqftitle() *getqftitle()* + Returns a list containing the title for each of the quickfix + lists in the stack. The title is also available in the + |w:quickfix_title| variable of the quickfix window. getreg([{regname} [, 1]]) *getreg()* The result is a String, which is the contents of register @@ -5186,14 +5240,26 @@ :endfor < Note: The '[ and '] marks are not set. -setloclist({nr}, {list} [, {action}]) *setloclist()* +setloclist({nr}, {list} [, {action}[, {title}]]) *setloclist()* Create or replace or add to the location list for window {nr}. When {nr} is zero the current window is used. For a location list window, the displayed location list is modified. For an - invalid window number {nr}, -1 is returned. + invalid window number {nr}, -1 is returned. If {title} is + given, it will be stored in the variable |w:quickfix_title|. Otherwise, same as |setqflist()|. Also see |location-list|. +setlocstackptr({nr}, {index}) *setlocstackptr()* + Sets the current item in the location list stack to {index}. + Returns -1 for invalid index item. + That is the same as using |:lolder| or |:lnewer| + +setloctitle({nr}, {string}) *setloctitle()* + Set {string} as title for the current item in the location + list stack for window {nr}. If {nr} is zero, the current + window will be used. The title will then be available as + |w:quickfix_title| variable. Also see |location-list|. + setmatches({list}) *setmatches()* Restores a list of matches saved by |getmatches()|. Returns 0 if successful, otherwise -1. All current matches are cleared @@ -5233,7 +5299,7 @@ vertically. See |winrestview()| for that. -setqflist({list} [, {action}]) *setqflist()* +setqflist({list} [, {action}[, {title}]]) *setqflist()* Create or replace or add to the quickfix list using the items in {list}. Each item in {list} is a dictionary. Non-dictionary items in {list} are ignored. Each dictionary @@ -5270,7 +5336,8 @@ list, then a new list is created. If {action} is set to 'r', then the items from the current quickfix list are replaced with the items from {list}. If {action} is not present or is - set to ' ', then a new list is created. + set to ' ', then a new list is created. If {title} is + given, it will be stored in the variable |w:quickfix_title|. Returns zero for success, -1 for failure. @@ -5278,6 +5345,15 @@ independent of the 'errorformat' setting. Use a command like ":cc 1" to jump to the first position. +setqfstackptr({index}) *setqfstackptr()* + Sets the current item in the quickfix list stack to {index}. + Returns -1 for invalid index item. + That is the same as using |:colder| or |:cnewer| + +setqftitle({string}) *setqftitle()* + Set {string} as title for the current item in the quickfix + list stack. The title will then be available as + |w:quickfix_title| variable. *setreg()* setreg({regname}, {value} [,{options}]) diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -779,9 +779,19 @@ Quickfix and location lists: *quickfix-functions* getqflist() list of quickfix errors + getqfstack() stack of quickfix lists + getqfstackptr() index in stack of quickfix lists + getqftitle() list of titles of quickfix list stack setqflist() modify a quickfix list + setqftitle() sets the title for the quickfix list + setqfstackptr() moves within the quickfix stack getloclist() list of location list items + getlocstack() stack of location lists + getlocstackptr() index in stack of location lists + getloctitle() list of titles of location list stack setloclist() modify a location list + setloctitle() sets the title for the location list + setlocstackptr() moves within the location list stack Insert mode completion: *completion-functions* complete() set found matches diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -553,6 +553,9 @@ static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv)); static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getqfstack __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getqfstackptr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getqftitle __ARGS((typval_T *argvars, typval_T *rettv)); static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv)); @@ -669,6 +672,10 @@ static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setloctitle __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setlocstackptr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setqfstackptr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setqftitle __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); @@ -7932,10 +7939,16 @@ {"getftype", 1, 1, f_getftype}, {"getline", 1, 2, f_getline}, {"getloclist", 1, 1, f_getqflist}, + {"getlocstack", 1, 1, f_getqfstack}, + {"getlocstackptr", 1, 1, f_getqfstackptr}, + {"getloctitle", 1, 1, f_getqftitle}, {"getmatches", 0, 0, f_getmatches}, {"getpid", 0, 0, f_getpid}, {"getpos", 1, 1, f_getpos}, {"getqflist", 0, 0, f_getqflist}, + {"getqfstack", 0, 0, f_getqfstack}, + {"getqfstackptr", 0, 0, f_getqfstackptr}, + {"getqftitle", 0, 0, f_getqftitle}, {"getreg", 0, 2, f_getreg}, {"getregtype", 0, 1, f_getregtype}, {"gettabvar", 2, 3, f_gettabvar}, @@ -8053,10 +8066,14 @@ {"setbufvar", 3, 3, f_setbufvar}, {"setcmdpos", 1, 1, f_setcmdpos}, {"setline", 2, 2, f_setline}, - {"setloclist", 2, 3, f_setloclist}, + {"setloclist", 2, 4, f_setloclist}, + {"setlocstackptr", 2, 2, f_setlocstackptr}, + {"setloctitle", 2, 2, f_setloctitle}, {"setmatches", 1, 1, f_setmatches}, {"setpos", 2, 2, f_setpos}, - {"setqflist", 1, 2, f_setqflist}, + {"setqflist", 1, 3, f_setqflist}, + {"setqfstackptr", 1, 1, f_setqfstackptr}, + {"setqftitle", 1, 1, f_setqftitle}, {"setreg", 2, 3, f_setreg}, {"settabvar", 3, 3, f_settabvar}, {"settabwinvar", 4, 4, f_settabwinvar}, @@ -11670,7 +11687,91 @@ return; } - (void)get_errorlist(wp, rettv->vval.v_list); + (void)get_errorlist(wp, rettv->vval.v_list, NULL); + } +#endif +} + +/* + * "getqfstackptr()" and "getlocstackptr()" functions + */ + static void +f_getqfstackptr(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ +#ifdef FEAT_QUICKFIX + win_T *wp; +#endif + +#ifdef FEAT_QUICKFIX + rettv->vval.v_number = -1; + wp = NULL; + if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ + { + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + } + + rettv->vval.v_number = qf_get_curitem(wp); +#endif +} + +/* + * "getqfstack()" functions + */ + static void +f_getqfstack(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ +#ifdef FEAT_QUICKFIX + win_T *wp; + list_T *l = list_alloc(); +#endif + +#ifdef FEAT_QUICKFIX + if (rettv_list_alloc(rettv) == OK && l != NULL) + { + wp = NULL; + ++l->lv_refcount; + if (argvars[0].v_type != VAR_UNKNOWN) /* getlocstack() */ + { + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + } + + (void)get_errorlist(wp, l, rettv->vval.v_list); + } +#endif +} + +/* + * "getqftitle()" functions + */ + static void +f_getqftitle(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ +#ifdef FEAT_QUICKFIX + win_T *wp; +#endif + +#ifdef FEAT_QUICKFIX + if (rettv_list_alloc(rettv) == OK) + { + wp = NULL; + if (argvars[0].v_type != VAR_UNKNOWN) /* getloctitle() */ + { + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + } + + (void)get_errortitle(wp, rettv->vval.v_list); } #endif } @@ -16331,21 +16432,23 @@ appended_lines_mark(lcount, added); } -static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)); +static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *title_arg, typval_T *rettv)); /* * Used by "setqflist()" and "setloclist()" functions */ static void -set_qf_ll_list(wp, list_arg, action_arg, rettv) +set_qf_ll_list(wp, list_arg, action_arg, title_arg, rettv) win_T *wp UNUSED; typval_T *list_arg UNUSED; typval_T *action_arg UNUSED; + typval_T *title_arg UNUSED; typval_T *rettv; { #ifdef FEAT_QUICKFIX char_u *act; int action = ' '; + char_u *title = NULL; #endif rettv->vval.v_number = -1; @@ -16365,9 +16468,16 @@ if (*act == 'a' || *act == 'r') action = *act; } - - if (l != NULL && set_errorlist(wp, l, action, - (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK) + if (title_arg->v_type == VAR_STRING) + { + title = get_tv_string_chk(title_arg); + if (title == NULL) + return; /* type error; errmsg already given */ + } + if (title == NULL) + title = (char_u*)(wp == NULL ? "setqflist()" : "setloclist()"); + + if (l != NULL && set_errorlist(wp, l, action, title) == OK) rettv->vval.v_number = 0; } #endif @@ -16387,8 +16497,9 @@ win = find_win_by_nr(&argvars[0], NULL); if (win != NULL) - set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); -} + set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv); +} + /* * "setmatches()" function @@ -16502,7 +16613,95 @@ typval_T *argvars; typval_T *rettv; { - set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); + set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv); +} + +/* + * "setqftitle()" functions + */ + static void +f_setqftitle(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ + char_u *varname; + varname = get_tv_string_chk(&argvars[0]); + +#ifdef FEAT_QUICKFIX + if (varname != NULL) + (void)win_set_qf_title(NULL, varname ); +#endif +} + +/* + * "setlocstackptr()" functions + */ + static void +f_setlocstackptr(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ +#ifdef FEAT_QUICKFIX + int number; + win_T *wp; + + rettv->vval.v_number = -1; + wp = NULL; + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + number = (int)get_tv_number_chk(&argvars[1], NULL); + if (number == -1) + return; + else + rettv->vval.v_number = qf_set_curitem(wp, number); +#endif +} + +/* + * "setloctitle()" functions + */ + static void +f_setloctitle(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ +#ifdef FEAT_QUICKFIX + char_u *varname; + win_T *wp; + + wp = NULL; + if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ + { + wp = find_win_by_nr(&argvars[0], NULL); + if (wp == NULL) + return; + } + varname = get_tv_string_chk(&argvars[1]); + + if (varname != NULL) + (void)win_set_qf_title(wp, varname ); +#endif +} + +/* + * "setqfstackptr()" functions + */ + static void +f_setqfstackptr(argvars, rettv) + typval_T *argvars UNUSED; + typval_T *rettv UNUSED; +{ +#ifdef FEAT_QUICKFIX + int number; + + rettv->vval.v_number = -1; + number = (int)get_tv_number_chk(&argvars[0], NULL); + if (number == -1) + return; + else + rettv->vval.v_number = qf_set_curitem(NULL, number); +#endif } /* @@ -16698,6 +16897,15 @@ STRCPY(winvarname, "w:"); STRCPY(winvarname + 2, varname); set_var(winvarname, varp, TRUE); + if (STRCMP(varname, "quickfix_title") == 0) + { + dictitem_T *v; + + v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE); + if (v != NULL) + win_set_qf_title(curwin, (&v->di_tv)->vval.v_string); + } + vim_free(winvarname); } } diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro --- a/src/proto/quickfix.pro +++ b/src/proto/quickfix.pro @@ -1,10 +1,14 @@ /* quickfix.c */ int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title)); +void qf_reset_listcount __ARGS((win_T *wp)); +int qf_set_curitem __ARGS((win_T *wp, int count)); +int qf_get_curitem __ARGS((win_T *wp)); 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)); void qf_list __ARGS((exarg_T *eap)); void qf_age __ARGS((exarg_T *eap)); +void win_set_qf_title __ARGS((win_T *wp, char_u *title)); void qf_mark_adjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)); void ex_cwindow __ARGS((exarg_T *eap)); void ex_cclose __ARGS((exarg_T *eap)); @@ -22,7 +26,8 @@ void ex_cfile __ARGS((exarg_T *eap)); void ex_vimgrep __ARGS((exarg_T *eap)); char_u *skip_vimgrep_pat __ARGS((char_u *p, char_u **s, int *flags)); -int get_errorlist __ARGS((win_T *wp, list_T *list)); +int get_errortitle __ARGS((win_T *wp, list_T *list)); +int get_errorlist __ARGS((win_T *wp, list_T *list, list_T *list_all)); int set_errorlist __ARGS((win_T *wp, list_T *list, int action, char_u *title)); void ex_cbuffer __ARGS((exarg_T *eap)); void ex_cexpr __ARGS((exarg_T *eap)); diff --git a/src/quickfix.c b/src/quickfix.c --- a/src/quickfix.c +++ b/src/quickfix.c @@ -914,13 +914,7 @@ qi->qf_curlist = qi->qf_listcount++; vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); if (qf_title != NULL) - { - char_u *p = alloc((int)STRLEN(qf_title) + 2); - - qi->qf_lists[qi->qf_curlist].qf_title = p; - if (p != NULL) - sprintf((char *)p, ":%s", (char *)qf_title); - } + qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(qf_title); } /* @@ -949,6 +943,59 @@ } void +qf_reset_listcount(wp) + win_T *wp; +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + qi = (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist); + + qi->qf_listcount = 0; + qi->qf_curlist = 0; +} + +/* set the current item for the quickfix/location list */ + int +qf_set_curitem(wp, count) + win_T *wp; + int count; +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + qi = (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist); + + if (qi == NULL || count >= qi->qf_listcount) + return -1; + else + { + qi->qf_curlist = count; + qf_update_buffer(qi); + return OK; + } +} + +/* get the current item for the quickfix/location list */ + int +qf_get_curitem(wp) + win_T *wp; +{ + qf_info_T *qi = &ql_info; + + if (wp != NULL) + qi = (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist); + + if (qi == NULL) + return -1; + else if ((wp == NULL && qi->qf_lists[qi->qf_curlist].qf_count == 0) + || qi->qf_curlist >= qi->qf_listcount) + return -1; + else + return qi->qf_curlist; +} + + void qf_free_all(wp) win_T *wp; { @@ -2587,6 +2634,31 @@ qi->qf_lists[qi->qf_curlist].qf_title); } + void +win_set_qf_title(wp, title) + win_T *wp; + char_u *title; +{ + qf_info_T *qi; + + if (wp == NULL || IS_QF_WINDOW(wp)) + qi = &ql_info; + else if (IS_LL_WINDOW(wp)) + qi = wp->w_llist_ref; + else + return; + + if (title != NULL) + { + vim_free(qi->qf_lists[qi->qf_curlist].qf_title); + qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(title); + qf_set_title(qi); +#ifdef FEAT_WINDOWS + qf_update_buffer(qi); +#endif + } +} + /* * Fill current buffer with quickfix errors, replacing any previous contents. * curbuf must be the quickfix buffer! @@ -2784,6 +2856,7 @@ int res; #ifdef FEAT_AUTOCMD char_u *au_name = NULL; + char_u title[130] = ":"; /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */ if (grep_internal(eap->cmdidx)) @@ -2856,10 +2929,10 @@ #endif 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->cmdlinep); + && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm, + (eap->cmdidx != CMD_grepadd + && eap->cmdidx != CMD_lgrepadd), + (char_u *)STRNCAT(title, *eap->cmdlinep, (size_t) 128)); if (wp != NULL) qi = GET_LOC_LIST(wp); #ifdef FEAT_AUTOCMD @@ -3022,6 +3095,7 @@ #ifdef FEAT_AUTOCMD char_u *au_name = NULL; #endif + char_u title[130] = ":"; if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile || eap->cmdidx == CMD_laddfile) @@ -3067,10 +3141,10 @@ * quickfix list then a new list is created. */ if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile - && eap->cmdidx != CMD_laddfile), - *eap->cmdlinep) > 0 - && (eap->cmdidx == CMD_cfile - || eap->cmdidx == CMD_lfile)) + && eap->cmdidx != CMD_laddfile), + (char_u*) STRNCAT(title, *eap->cmdlinep, (size_t) 128)) > 0 + && (eap->cmdidx == CMD_cfile + || eap->cmdidx == CMD_lfile)) { #ifdef FEAT_AUTOCMD if (au_name != NULL) @@ -3131,6 +3205,8 @@ char_u *dirname_start = NULL; char_u *dirname_now = NULL; char_u *target_dir = NULL; + char_u title[130] = ":"; + char_u *q = vim_strnsave(*eap->cmdlinep, 128); #ifdef FEAT_AUTOCMD char_u *au_name = NULL; @@ -3208,7 +3284,7 @@ eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd) || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ - qf_new_list(qi, *eap->cmdlinep); + qf_new_list(qi, (char_u *)STRNCAT(title, q, (size_t) 128)); 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; @@ -3310,7 +3386,7 @@ if (idx == LISTCOUNT) { /* List cannot be found, create a new one. */ - qf_new_list(qi, *eap->cmdlinep); + qf_new_list(qi, (char_u *)STRNCAT(title, q, (size_t) 128)); cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start; } } @@ -3488,6 +3564,7 @@ vim_free(dirname_start); vim_free(target_dir); vim_free(regmatch.regprog); + vim_free(q); } /* @@ -3715,12 +3792,42 @@ #if defined(FEAT_EVAL) || defined(PROTO) /* + * Populate the list "list" with all quickfix/location list titles + */ + int +get_errortitle(wp, list) + win_T *wp; + list_T *list; +{ + char_u *title; + qf_info_T *qi = &ql_info; + int j; + + if (wp != NULL) + qi = GET_LOC_LIST(wp); + + if (qi == NULL) + return FAIL; + + for (j = 0; qi != NULL && j < qi->qf_listcount; j++) + { + if (list != NULL) + { + title = qi->qf_lists[j].qf_title; + + list_append_string(list, title == NULL ? (char_u *)"" : title, -1); + } + } + return OK; +} +/* * Add each quickfix error to list "list" as a dictionary. */ int -get_errorlist(wp, list) +get_errorlist(wp, list, list_all) win_T *wp; list_T *list; + list_T *list_all; { qf_info_T *qi = &ql_info; dict_T *dict; @@ -3728,48 +3835,69 @@ qfline_T *qfp; int i; int bufnum; + int j; if (wp != NULL) + qi = GET_LOC_LIST(wp); + + if (qi == NULL || qi->qf_curlist >= qi->qf_listcount + || (list_all == NULL && qi->qf_lists[qi->qf_curlist].qf_count == 0)) + return FAIL; + + j = (list_all != NULL ? 0 : qi->qf_curlist); + + for (; j < LISTCOUNT; j++) { - qi = GET_LOC_LIST(wp); - if (qi == NULL) - return FAIL; + listitem_T *li = listitem_alloc(); + + qfp = qi->qf_lists[j].qf_start; + for (i = 1; !got_int && qi != NULL && i <= qi->qf_lists[j].qf_count; ++i) + { + /* Handle entries with a non-existing buffer number. */ + bufnum = qfp->qf_fnum; + if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) + bufnum = 0; + + if ((dict = dict_alloc()) == NULL) + return FAIL; + if (list_append_dict(list, dict) == FAIL) + return FAIL; + + buf[0] = qfp->qf_type; + buf[1] = NUL; + if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL + || dict_add_nr_str(dict, "lnum", (long)qfp->qf_lnum, NULL) == FAIL + || dict_add_nr_str(dict, "col", (long)qfp->qf_col, NULL) == FAIL + || dict_add_nr_str(dict, "vcol", (long)qfp->qf_viscol, NULL) == FAIL + || dict_add_nr_str(dict, "nr", (long)qfp->qf_nr, NULL) == FAIL + || dict_add_nr_str(dict, "pattern", 0L, + qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL + || dict_add_nr_str(dict, "text", 0L, + qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL + || dict_add_nr_str(dict, "type", 0L, buf) == FAIL + || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL) + return FAIL; + + qfp = qfp->qf_next; + } + if (list_all == NULL) + break; + else if (qi != NULL && qi->qf_lists[j].qf_count) + { + if (list != NULL) + { + list_append(list_all, li); + li->li_tv.v_type = VAR_LIST; + li->li_tv.v_lock = 0; + li->li_tv.vval.v_list = list; + + if ((list = list_alloc()) == NULL) + return FAIL; + } + } } - - if (qi->qf_curlist >= qi->qf_listcount - || qi->qf_lists[qi->qf_curlist].qf_count == 0) - return FAIL; - - qfp = qi->qf_lists[qi->qf_curlist].qf_start; - for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i) - { - /* Handle entries with a non-existing buffer number. */ - bufnum = qfp->qf_fnum; - if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) - bufnum = 0; - - if ((dict = dict_alloc()) == NULL) - return FAIL; - if (list_append_dict(list, dict) == FAIL) - return FAIL; - - buf[0] = qfp->qf_type; - buf[1] = NUL; - if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL - || dict_add_nr_str(dict, "lnum", (long)qfp->qf_lnum, NULL) == FAIL - || dict_add_nr_str(dict, "col", (long)qfp->qf_col, NULL) == FAIL - || dict_add_nr_str(dict, "vcol", (long)qfp->qf_viscol, NULL) == FAIL - || dict_add_nr_str(dict, "nr", (long)qfp->qf_nr, NULL) == FAIL - || dict_add_nr_str(dict, "pattern", 0L, - qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL - || dict_add_nr_str(dict, "text", 0L, - qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL - || dict_add_nr_str(dict, "type", 0L, buf) == FAIL - || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL) - return FAIL; - - qfp = qfp->qf_next; - } + if (list_all != NULL) + list_free(list, TRUE); return OK; } @@ -3807,6 +3935,7 @@ if (action == ' ' || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, title); + 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; @@ -3815,6 +3944,12 @@ else if (action == 'r') qf_free(qi, qi->qf_curlist); + if (title != NULL && action != ' ') + { + vim_free(qi->qf_lists[qi->qf_curlist].qf_title); + qi->qf_lists[qi->qf_curlist].qf_title = vim_strsave(title); + } + for (li = list->lv_first; li != NULL; li = li->li_next) { if (li->li_tv.v_type != VAR_DICT) @@ -4026,6 +4161,7 @@ #ifdef FEAT_AUTOCMD char_u *au_name = NULL; #endif + char_u title[130] = ":"; #ifdef FEAT_MULTI_LANG /* Check for a specified language */ @@ -4088,7 +4224,7 @@ #endif /* create a new quickfix list */ - qf_new_list(qi, *eap->cmdlinep); + qf_new_list(qi, (char_u*)STRNCAT(title, *eap->cmdlinep, (size_t) 128)); /* Go through all directories in 'runtimepath' */ p = p_rtp;