To: vim_dev@googlegroups.com Subject: Patch 8.2.0869 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0869 Problem: It is not possible to customize the quickfix window contents. Solution: Add 'quickfixtextfunc'. (Yegappan Lakshmanan, closes #5465) Files: runtime/doc/eval.txt, runtime/doc/options.txt, runtime/doc/quickfix.txt, src/option.h, src/optiondefs.h, src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.2.0868/runtime/doc/eval.txt 2020-05-31 22:19:52.894638049 +0200 --- runtime/doc/eval.txt 2020-05-31 22:57:50.937143392 +0200 *************** *** 5498,5505 **** id get information for the quickfix list with |quickfix-ID|; zero means the id for the current list or the list specified by "nr" ! idx index of the current entry in the quickfix ! list specified by 'id' or 'nr'. See |quickfix-index| items quickfix list entries lines parse a list of lines using 'efm' and return --- 5508,5516 ---- id get information for the quickfix list with |quickfix-ID|; zero means the id for the current list or the list specified by "nr" ! idx get information for the quickfix entry at this ! index in the list specified by 'id' or 'nr'. ! If set to zero, then uses the current entry. See |quickfix-index| items quickfix list entries lines parse a list of lines using 'efm' and return *************** *** 5535,5541 **** If not present, set to "". id quickfix list ID |quickfix-ID|. If not present, set to 0. ! idx index of the current entry in the list. If not present, set to 0. items quickfix list entries. If not present, set to an empty list. --- 5546,5552 ---- If not present, set to "". id quickfix list ID |quickfix-ID|. If not present, set to 0. ! idx index of the quickfix entry in the list. If not present, set to 0. items quickfix list entries. If not present, set to an empty list. *************** *** 8745,8751 **** setqflist({list} [, {action} [, {what}]]) *setqflist()* Create or replace or add to the quickfix list. ! When {what} is not present, use the items in {list}. Each item must be a dictionary. Non-dictionary items in {list} are ignored. Each dictionary item can contain the following entries: --- 8762,8773 ---- setqflist({list} [, {action} [, {what}]]) *setqflist()* Create or replace or add to the quickfix list. ! If the optional {what} dictionary argument is supplied, then ! only the items listed in {what} are set. The first {list} ! argument is ignored. See below for the supported items in ! {what}. ! ! When {what} is not present, the items in {list} or used. Each item must be a dictionary. Non-dictionary items in {list} are ignored. Each dictionary item can contain the following entries: *************** *** 8800,8809 **** freed. To add a new quickfix list at the end of the stack, set "nr" in {what} to "$". ! If the optional {what} dictionary argument is supplied, then ! only the items listed in {what} are set. The first {list} ! argument is ignored. The following items can be specified in ! {what}: context quickfix list context. See |quickfix-context| efm errorformat to use when parsing text from "lines". If this is not present, then the --- 8822,8828 ---- freed. To add a new quickfix list at the end of the stack, set "nr" in {what} to "$". ! The following items can be specified in dictionary {what}: context quickfix list context. See |quickfix-context| efm errorformat to use when parsing text from "lines". If this is not present, then the *************** *** 8823,8828 **** --- 8842,8852 ---- nr list number in the quickfix stack; zero means the current quickfix list and "$" means the last quickfix list. + quickfixtextfunc + function to get the text to display in the + quickfix window. Refer to + |quickfix-window-function| for an explanation + of how to write the function and an example. title quickfix list title text. See |quickfix-title| Unsupported keys in {what} are ignored. If the "nr" item is not present, then the current quickfix list *** ../vim-8.2.0868/runtime/doc/options.txt 2020-05-31 15:08:55.118721233 +0200 --- runtime/doc/options.txt 2020-05-31 22:59:34.412839507 +0200 *************** *** 5900,5905 **** --- 5901,5921 ---- This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. + *'quickfixtextfunc'* *'qftf'* + 'quickfixtextfunc' 'qftf' string (default "") + global + {only available when compiled with the |+quickfix| + feature} + This option specifies a function to be used to get the text to display + in the quickfix and location list windows. This can be used to + customize the information displayed in the quickfix or location window + for each entry in the corresponding quickfix or location list. See + |quickfix-window-function| for an explanation of how to write the + function and an example. + + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. + *'quoteescape'* *'qe'* 'quoteescape' 'qe' string (default "\") local to buffer *** ../vim-8.2.0868/runtime/doc/quickfix.txt 2020-01-06 21:47:17.040023214 +0100 --- runtime/doc/quickfix.txt 2020-05-31 23:01:47.928423150 +0200 *************** *** 15,20 **** --- 15,21 ---- 7. The error format |error-file-format| 8. The directory stack |quickfix-directory-stack| 9. Specific error file formats |errorformats| + 10. Customizing the quickfix window |quickfix-window-function| The quickfix commands are not available when the |+quickfix| feature was disabled at compile time. *************** *** 1922,1927 **** --- 1922,1980 ---- start of the file about how to use it. (This script is deprecated, see |compiler-perl|.) + ============================================================================= + 10. Customizing the quickfix window *quickfix-window-function* + + The default format for the lines displayed in the quickfix window and location + list window is: + | col | + + The values displayed in each line correspond to the "bufnr", "lnum", "col" and + "text" fields returned by the |getqflist()| function. + + For some quickfix/location lists, the displayed text need to be customized. + For example, if only the filename is present for a quickfix entry, then the + two "|" field separator characters after the filename are not needed. Another + use case is to customize the path displayed for a filename. By default, the + complete path (which may be too long) is displayed for files which are not + under the current directory tree. The file path may need to be simplified to a + common parent directory. + + The displayed text can be customized by setting the 'quickfixtextfunc' option + to a Vim function. This function will be called with a dict argument for + every entry in a quickfix or a location list. The dict argument will have the + following fields: + + quickfix set to 1 when called for a quickfix list and 0 when called for + a location list. + id quickfix or location list identifier + idx index of the entry in the quickfix or location list + + The function should return a single line of text to display in the quickfix + window for the entry identified by idx. The function can obtain information + about the current entry using the |getqflist()| function and specifying the + quickfix list identifier "id" and the entry index "idx". + + If a quickfix or location list specific customization is needed, then the + 'quickfixtextfunc' attribute of the list can be set using the |setqflist()| or + |setloclist()| function. This overrides the global 'quickfixtextfunc' option. + + The example below displays the list of old files (|v:oldfiles|) in a quickfix + window. As there is no line, column number and error text information + associated with each entry, the 'quickfixtextfunc' function returns only the + filename. + Example: > + " create a quickfix list from v:oldfiles + call setqflist([], ' ', {'lines' : v:oldfiles, 'efm' : '%f', + \ 'quickfixtextfunc' : 'QfOldFiles'}) + func QfOldFiles(info) + " get information about the specific quickfix entry + let e = getqflist({'id' : a:info.id, 'idx' : a:info.idx, + \ 'items' : 1}).items[0] + " return the simplified file name + return fnamemodify(bufname(e.bufnr), ':p:.') + endfunc + < vim:tw=78:ts=8:noet:ft=help:norl: *** ../vim-8.2.0868/src/option.h 2020-04-17 19:41:16.100078313 +0200 --- src/option.h 2020-05-31 22:57:50.937143392 +0200 *************** *** 820,825 **** --- 820,826 ---- EXTERN char_u *p_ruf; // 'rulerformat' #endif EXTERN char_u *p_pp; // 'packpath' + EXTERN char_u *p_qftf; // 'quickfixtextfunc' EXTERN char_u *p_rtp; // 'runtimepath' EXTERN long p_sj; // 'scrolljump' #if defined(MSWIN) && defined(FEAT_GUI) *** ../vim-8.2.0868/src/optiondefs.h 2020-05-31 16:41:04.646603340 +0200 --- src/optiondefs.h 2020-05-31 22:57:50.937143392 +0200 *************** *** 2045,2050 **** --- 2045,2059 ---- #endif {(char_u *)DEFAULT_PYTHON_VER, (char_u *)0L} SCTX_INIT}, + {"quickfixtextfunc", "qftf", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_SECURE, + #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) + (char_u *)&p_qftf, PV_NONE, + {(char_u *)"", (char_u *)0L} + #else + (char_u *)NULL, PV_NONE, + {(char_u *)NULL, (char_u *)NULL} + #endif + SCTX_INIT}, {"quoteescape", "qe", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_TEXTOBJ (char_u *)&p_qe, PV_QE, *** ../vim-8.2.0868/src/quickfix.c 2020-05-30 20:30:42.896816552 +0200 --- src/quickfix.c 2020-05-31 22:57:50.941143383 +0200 *************** *** 82,87 **** --- 82,88 ---- char_u *qf_title; // title derived from the command that created // the error list or set by setqflist typval_T *qf_ctx; // context set by setqflist/setloclist + char_u *qf_qftf; // 'quickfixtextfunc' setting for this list struct dir_stack_T *qf_dir_stack; char_u *qf_directory; *************** *** 2277,2282 **** --- 2278,2287 ---- } else to_qfl->qf_ctx = NULL; + if (from_qfl->qf_qftf != NULL) + to_qfl->qf_qftf = vim_strsave(from_qfl->qf_qftf); + else + to_qfl->qf_qftf = NULL; if (from_qfl->qf_count) if (copy_loclist_entries(from_qfl, to_qfl) == FAIL) *************** *** 3812,3817 **** --- 3817,3823 ---- VIM_CLEAR(qfl->qf_title); free_tv(qfl->qf_ctx); qfl->qf_ctx = NULL; + VIM_CLEAR(qfl->qf_qftf); qfl->qf_id = 0; qfl->qf_changedtick = 0L; } *************** *** 4399,4473 **** * Add an error line to the quickfix buffer. */ static int ! qf_buf_add_line(buf_T *buf, linenr_T lnum, qfline_T *qfp, char_u *dirname) { int len; buf_T *errbuf; ! if (qfp->qf_module != NULL) ! { ! vim_strncpy(IObuff, qfp->qf_module, IOSIZE - 1); ! len = (int)STRLEN(IObuff); } ! else if (qfp->qf_fnum != 0 ! && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL ! && errbuf->b_fname != NULL) { ! if (qfp->qf_type == 1) // :helpgrep ! vim_strncpy(IObuff, gettail(errbuf->b_fname), IOSIZE - 1); ! else { ! // shorten the file name if not done already ! if (errbuf->b_sfname == NULL ! || mch_isFullName(errbuf->b_sfname)) { ! if (*dirname == NUL) ! mch_dirname(dirname, MAXPATHL); ! shorten_buf_fname(errbuf, dirname, FALSE); } ! vim_strncpy(IObuff, errbuf->b_fname, IOSIZE - 1); } ! len = (int)STRLEN(IObuff); ! } ! else ! len = 0; ! if (len < IOSIZE - 1) ! IObuff[len++] = '|'; ! if (qfp->qf_lnum > 0) ! { ! vim_snprintf((char *)IObuff + len, IOSIZE - len, "%ld", qfp->qf_lnum); ! len += (int)STRLEN(IObuff + len); ! if (qfp->qf_col > 0) { ! vim_snprintf((char *)IObuff + len, IOSIZE - len, ! " col %d", qfp->qf_col); len += (int)STRLEN(IObuff + len); } ! vim_snprintf((char *)IObuff + len, IOSIZE - len, "%s", ! (char *)qf_types(qfp->qf_type, qfp->qf_nr)); ! len += (int)STRLEN(IObuff + len); ! } ! else if (qfp->qf_pattern != NULL) ! { ! qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); ! len += (int)STRLEN(IObuff + len); ! } ! if (len < IOSIZE - 2) ! { ! IObuff[len++] = '|'; ! IObuff[len++] = ' '; } - // Remove newlines and leading whitespace from the text. - // For an unrecognized line keep the indent, the compiler may - // mark a word with ^^^^. - qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, - IObuff + len, IOSIZE - len); - if (ml_append_buf(buf, lnum, IObuff, (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) return FAIL; --- 4405,4520 ---- * Add an error line to the quickfix buffer. */ static int ! qf_buf_add_line( ! qf_list_T *qfl, // quickfix list ! buf_T *buf, // quickfix window buffer ! linenr_T lnum, ! qfline_T *qfp, ! char_u *dirname) { int len; buf_T *errbuf; + char_u *qftf; ! // If 'quickfixtextfunc' is set, then use the user-supplied function to get ! // the text to display ! qftf = p_qftf; ! // Use the local value of 'quickfixtextfunc' if it is set. ! if (qfl->qf_qftf != NULL) ! qftf = qfl->qf_qftf; ! if (qftf != NULL && *qftf != NUL) ! { ! char_u *qfbuf_text; ! typval_T args[1]; ! dict_T *d; ! ! // create 'info' dict argument ! if ((d = dict_alloc_lock(VAR_FIXED)) == NULL) ! return FAIL; ! dict_add_number(d, "quickfix", (long)IS_QF_LIST(qfl)); ! dict_add_number(d, "id", (long)qfl->qf_id); ! dict_add_number(d, "idx", (long)(lnum + 1)); ! ++d->dv_refcount; ! args[0].v_type = VAR_DICT; ! args[0].vval.v_dict = d; ! ! qfbuf_text = call_func_retstr(qftf, 1, args); ! --d->dv_refcount; ! ! if (qfbuf_text == NULL) ! return FAIL; ! ! vim_strncpy(IObuff, qfbuf_text, IOSIZE - 1); ! vim_free(qfbuf_text); } ! else { ! if (qfp->qf_module != NULL) { ! vim_strncpy(IObuff, qfp->qf_module, IOSIZE - 1); ! len = (int)STRLEN(IObuff); ! } ! else if (qfp->qf_fnum != 0 ! && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL ! && errbuf->b_fname != NULL) ! { ! if (qfp->qf_type == 1) // :helpgrep ! vim_strncpy(IObuff, gettail(errbuf->b_fname), IOSIZE - 1); ! else { ! // shorten the file name if not done already ! if (errbuf->b_sfname == NULL ! || mch_isFullName(errbuf->b_sfname)) ! { ! if (*dirname == NUL) ! mch_dirname(dirname, MAXPATHL); ! shorten_buf_fname(errbuf, dirname, FALSE); ! } ! vim_strncpy(IObuff, errbuf->b_fname, IOSIZE - 1); } ! len = (int)STRLEN(IObuff); } ! else ! len = 0; ! if (len < IOSIZE - 1) ! IObuff[len++] = '|'; ! if (qfp->qf_lnum > 0) ! { ! vim_snprintf((char *)IObuff + len, IOSIZE - len, "%ld", ! qfp->qf_lnum); ! len += (int)STRLEN(IObuff + len); ! if (qfp->qf_col > 0) ! { ! vim_snprintf((char *)IObuff + len, IOSIZE - len, ! " col %d", qfp->qf_col); ! len += (int)STRLEN(IObuff + len); ! } ! ! vim_snprintf((char *)IObuff + len, IOSIZE - len, "%s", ! (char *)qf_types(qfp->qf_type, qfp->qf_nr)); ! len += (int)STRLEN(IObuff + len); ! } ! else if (qfp->qf_pattern != NULL) { ! qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); len += (int)STRLEN(IObuff + len); } + if (len < IOSIZE - 2) + { + IObuff[len++] = '|'; + IObuff[len++] = ' '; + } ! // Remove newlines and leading whitespace from the text. ! // For an unrecognized line keep the indent, the compiler may ! // mark a word with ^^^^. ! qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, ! IObuff + len, IOSIZE - len); } if (ml_append_buf(buf, lnum, IObuff, (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) return FAIL; *************** *** 4522,4528 **** } while (lnum < qfl->qf_count) { ! if (qf_buf_add_line(buf, lnum, qfp, dirname) == FAIL) break; ++lnum; --- 4569,4575 ---- } while (lnum < qfl->qf_count) { ! if (qf_buf_add_line(qfl, buf, lnum, qfp, dirname) == FAIL) break; ++lnum; *************** *** 6369,6377 **** /* * Add each quickfix error to list "list" as a dictionary. * If qf_idx is -1, use the current list. Otherwise, use the specified list. */ static int ! get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) { qf_info_T *qi = qi_arg; qf_list_T *qfl; --- 6416,6431 ---- /* * Add each quickfix error to list "list" as a dictionary. * If qf_idx is -1, use the current list. Otherwise, use the specified list. + * If eidx is not 0, then return only the specified entry. Otherwise return + * all the entries. */ static int ! get_errorlist( ! qf_info_T *qi_arg, ! win_T *wp, ! int qf_idx, ! int eidx, ! list_T *list) { qf_info_T *qi = qi_arg; qf_list_T *qfl; *************** *** 6389,6394 **** --- 6443,6451 ---- } } + if (eidx < 0) + return OK; + if (qf_idx == INVALID_QFIDX) qf_idx = qi->qf_curlist; *************** *** 6401,6407 **** FOR_ALL_QFL_ITEMS(qfl, qfp, i) { ! if (get_qfline_items(qfp, list) == FAIL) return FAIL; } --- 6458,6469 ---- FOR_ALL_QFL_ITEMS(qfl, qfp, i) { ! if (eidx > 0) ! { ! if (eidx == i) ! return get_qfline_items(qfp, list); ! } ! else if (get_qfline_items(qfp, list) == FAIL) return FAIL; } *************** *** 6461,6467 **** if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, TRUE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { ! (void)get_errorlist(qi, NULL, 0, l); qf_free(&qi->qf_lists[0]); } free(qi); --- 6523,6529 ---- if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, TRUE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { ! (void)get_errorlist(qi, NULL, 0, 0, l); qf_free(&qi->qf_lists[0]); } free(qi); *************** *** 6679,6694 **** } /* ! * Return the quickfix list items/entries as 'items' in retdict */ static int ! qf_getprop_items(qf_info_T *qi, int qf_idx, dict_T *retdict) { int status = OK; list_T *l = list_alloc(); if (l != NULL) { ! (void)get_errorlist(qi, NULL, qf_idx, l); dict_add_list(retdict, "items", l); } else --- 6741,6757 ---- } /* ! * Return the quickfix list items/entries as 'items' in retdict. ! * If eidx is not 0, then return the item at the specified index. */ static int ! qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx, dict_T *retdict) { int status = OK; list_T *l = list_alloc(); if (l != NULL) { ! (void)get_errorlist(qi, NULL, qf_idx, eidx, l); dict_add_list(retdict, "items", l); } else *************** *** 6726,6741 **** } /* ! * Return the current quickfix list index as 'idx' in retdict */ static int ! qf_getprop_idx(qf_list_T *qfl, dict_T *retdict) { ! int curidx = qfl->qf_index; ! if (qf_list_empty(qfl)) ! // For empty lists, current index is set to 0 ! curidx = 0; ! return dict_add_number(retdict, "idx", curidx); } /* --- 6789,6808 ---- } /* ! * Return the current quickfix list index as 'idx' in retdict. ! * If a specific entry index (eidx) is supplied, then use that. */ static int ! qf_getprop_idx(qf_list_T *qfl, int eidx, dict_T *retdict) { ! if (eidx == 0) ! { ! eidx = qfl->qf_index; ! if (qf_list_empty(qfl)) ! // For empty lists, current index is set to 0 ! eidx = 0; ! } ! return dict_add_number(retdict, "idx", eidx); } /* *************** *** 6750,6755 **** --- 6817,6823 ---- qf_list_T *qfl; int status = OK; int qf_idx = INVALID_QFIDX; + int eidx = 0; dictitem_T *di; int flags = QF_GETLIST_NONE; *************** *** 6770,6775 **** --- 6838,6851 ---- qfl = qf_get_list(qi, qf_idx); + // If an entry index is specified, use that + if ((di = dict_find(what, (char_u *)"idx", -1)) != NULL) + { + if (di->di_tv.v_type != VAR_NUMBER) + return FAIL; + eidx = di->di_tv.vval.v_number; + } + if (flags & QF_GETLIST_TITLE) status = qf_getprop_title(qfl, retdict); if ((status == OK) && (flags & QF_GETLIST_NR)) *************** *** 6777,6789 **** if ((status == OK) && (flags & QF_GETLIST_WINID)) status = dict_add_number(retdict, "winid", qf_winid(qi)); if ((status == OK) && (flags & QF_GETLIST_ITEMS)) ! status = qf_getprop_items(qi, qf_idx, retdict); if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) status = qf_getprop_ctx(qfl, retdict); if ((status == OK) && (flags & QF_GETLIST_ID)) status = dict_add_number(retdict, "id", qfl->qf_id); if ((status == OK) && (flags & QF_GETLIST_IDX)) ! status = qf_getprop_idx(qfl, retdict); if ((status == OK) && (flags & QF_GETLIST_SIZE)) status = dict_add_number(retdict, "size", qfl->qf_count); if ((status == OK) && (flags & QF_GETLIST_TICK)) --- 6853,6865 ---- if ((status == OK) && (flags & QF_GETLIST_WINID)) status = dict_add_number(retdict, "winid", qf_winid(qi)); if ((status == OK) && (flags & QF_GETLIST_ITEMS)) ! status = qf_getprop_items(qi, qf_idx, eidx, retdict); if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) status = qf_getprop_ctx(qfl, retdict); if ((status == OK) && (flags & QF_GETLIST_ID)) status = dict_add_number(retdict, "id", qfl->qf_id); if ((status == OK) && (flags & QF_GETLIST_IDX)) ! status = qf_getprop_idx(qfl, eidx, retdict); if ((status == OK) && (flags & QF_GETLIST_SIZE)) status = dict_add_number(retdict, "size", qfl->qf_count); if ((status == OK) && (flags & QF_GETLIST_TICK)) *************** *** 7148,7153 **** --- 7224,7243 ---- } /* + * Set the current index in the specified quickfix list + */ + static int + qf_setprop_qftf(qf_info_T *qi UNUSED, qf_list_T *qfl, dictitem_T *di) + { + VIM_CLEAR(qfl->qf_qftf); + if (di->di_tv.v_type == VAR_STRING + && di->di_tv.vval.v_string != NULL) + qfl->qf_qftf = vim_strsave(di->di_tv.vval.v_string); + + return OK; + } + + /* * Set quickfix/location list properties (title, items, context). * Also used to add items from parsing a list of lines. * Used by the setqflist() and setloclist() Vim script functions. *************** *** 7186,7191 **** --- 7276,7283 ---- retval = qf_setprop_context(qfl, di); if ((di = dict_find(what, (char_u *)"idx", -1)) != NULL) retval = qf_setprop_curidx(qi, qfl, di); + if ((di = dict_find(what, (char_u *)"quickfixtextfunc", -1)) != NULL) + retval = qf_setprop_qftf(qi, qfl, di); if (retval == OK) qf_list_changed(qfl); *************** *** 7900,7906 **** { if (rettv_list_alloc(rettv) == OK) if (is_qf || wp != NULL) ! (void)get_errorlist(NULL, wp, -1, rettv->vval.v_list); } else { --- 7992,7998 ---- { if (rettv_list_alloc(rettv) == OK) if (is_qf || wp != NULL) ! (void)get_errorlist(NULL, wp, -1, 0, rettv->vval.v_list); } else { *** ../vim-8.2.0868/src/testdir/test_quickfix.vim 2020-05-03 16:29:46.891538441 +0200 --- src/testdir/test_quickfix.vim 2020-05-31 22:57:50.941143383 +0200 *************** *** 4766,4769 **** --- 4766,4886 ---- call assert_fails('-3cquit', 'E16:') endfunc + " Test for getting a specific item from a quickfix list + func Xtest_getqflist_by_idx(cchar) + call s:setup_commands(a:cchar) + " Empty list + call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items) + Xexpr ['F1:10:L10', 'F1:20:L20'] + let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items + call assert_equal(bufnr('F1'), l[0].bufnr) + call assert_equal(20, l[0].lnum) + call assert_equal('L20', l[0].text) + call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items) + call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items) + %bwipe! + endfunc + + func Test_getqflist_by_idx() + call Xtest_getqflist_by_idx('c') + call Xtest_getqflist_by_idx('l') + endfunc + + " Test for the 'quickfixtextfunc' setting + func Tqfexpr(info) + if a:info.quickfix + let qfl = getqflist({'id' : a:info.id, 'idx' : a:info.idx, + \ 'items' : 1}).items + else + let qfl = getloclist(0, {'id' : a:info.id, 'idx' : a:info.idx, + \ 'items' : 1}).items + endif + + let e = qfl[0] + let s = '' + if e.bufnr != 0 + let bname = bufname(e.bufnr) + let s ..= fnamemodify(bname, ':.') + endif + let s ..= '-' + let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-' + let s ..= e.text + + return s + endfunc + + func Xtest_qftextfunc(cchar) + call s:setup_commands(a:cchar) + + set efm=%f:%l:%c:%m + set quickfixtextfunc=Tqfexpr + Xexpr ['F1:10:2:green', 'F1:20:4:blue'] + Xwindow + call assert_equal('F1-L10C2-green', getline(1)) + call assert_equal('F1-L20C4-blue', getline(2)) + Xclose + set quickfixtextfunc&vim + Xwindow + call assert_equal('F1|10 col 2| green', getline(1)) + call assert_equal('F1|20 col 4| blue', getline(2)) + Xclose + set efm& + set quickfixtextfunc& + + " Test for per list 'quickfixtextfunc' setting + func PerQfText(info) + if a:info.quickfix + let qfl = getqflist({'id' : a:info.id, 'idx' : a:info.idx, + \ 'items' : 1}).items + else + let qfl = getloclist(0, {'id' : a:info.id, 'idx' : a:info.idx, + \ 'items' : 1}).items + endif + if empty(qfl) + return '' + endif + return 'Line ' .. qfl[0].lnum .. ', Col ' .. qfl[0].col + endfunc + set quickfixtextfunc=Tqfexpr + call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"}) + Xaddexpr ['F1:10:2:green', 'F1:20:4:blue'] + Xwindow + call assert_equal('Line 10, Col 2', getline(1)) + call assert_equal('Line 20, Col 4', getline(2)) + Xclose + call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''}) + set quickfixtextfunc& + delfunc PerQfText + + " Non-existing function + set quickfixtextfunc=Tabc + call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:') + call assert_fails("Xwindow", 'E117:') + Xclose + set quickfixtextfunc& + + " set option to a non-function + set quickfixtextfunc=[10,\ 20] + call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:') + call assert_fails("Xwindow", 'E117:') + Xclose + set quickfixtextfunc& + + " set option to a function with different set of arguments + func Xqftext(a, b, c) + return a:a .. a:b .. a:c + endfunc + set quickfixtextfunc=Xqftext + call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:') + call assert_fails("Xwindow", 'E119:') + Xclose + set quickfixtextfunc& + delfunc Xqftext + endfunc + + func Test_qftextfunc() + call Xtest_qftextfunc('c') + call Xtest_qftextfunc('l') + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0868/src/version.c 2020-05-31 22:19:52.898638027 +0200 --- src/version.c 2020-05-31 22:58:28.513035100 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 869, /**/ -- hundred-and-one symptoms of being an internet addict: 237. You tattoo your email address on your forehead. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///