Merge pull request #14490 from kevinhwang91/qftf

vim-patch: 8.2.{0869,0933,0959} - port quickfixtextfunc
This commit is contained in:
Jan Edmund Lazo 2021-05-20 17:54:52 -04:00 committed by GitHub
commit 713eaaed06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 423 additions and 77 deletions

View File

@ -4773,8 +4773,9 @@ getqflist([{what}]) *getqflist()*
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'.
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
@ -4807,7 +4808,7 @@ getqflist([{what}]) *getqflist()*
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
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.
@ -7874,6 +7875,11 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
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

View File

@ -4600,6 +4600,19 @@ A jump table for the options with a short description can be found at |Q_op|.
'pyxversion' has no effect. The pyx* functions and commands are
always the same as the installed version.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'quickfixtextfunc'* *'qftf'*
'quickfixtextfunc' 'qftf' string (default "")
global
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.

View File

@ -1889,5 +1889,67 @@ be used. See the description further above how to make such a filter known
by Vim.
=============================================================================
10. Customizing the quickfix window *quickfix-window-function*
The default format for the lines displayed in the quickfix window and location
list window is:
<filename>|<lnum> col <col>|<text>
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 and
should return a List of strings to be displayed in the quickfix or location
list window. 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.
winid for a location list, set to the id of the window with the
location list. For a quickfix list, set to 0. Can be used in
getloclist() to get the location list entry.
id quickfix or location list identifier
start_idx index of the first entry for which text should be returned
end_idx index of the last entry for which text should be returned
The function should return a single line of text to display in the quickfix
window for each entry from start_idx to end_idx. The function can obtain
information about the entries using the |getqflist()| function and specifying
the quickfix list identifier "id". For a location list, getloclist() function
can be used with the 'winid' argument.
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 a range of quickfix entries
let items = getqflist({'id' : a:info.id, 'items' : 1}).items
let l = []
for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
" use the simplified file name
call add(l, fnamemodify(bufname(items[idx].bufnr), ':p:.'))
endfor
return l
endfunc
<
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -6326,7 +6326,7 @@ void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg,
if (what_arg->v_type == VAR_UNKNOWN) {
tv_list_alloc_ret(rettv, kListLenMayKnow);
if (is_qf || wp != NULL) {
(void)get_errorlist(NULL, wp, -1, rettv->vval.v_list);
(void)get_errorlist(NULL, wp, -1, 0, rettv->vval.v_list);
}
} else {
tv_dict_alloc_ret(rettv);

View File

@ -559,6 +559,7 @@ EXTERN int p_ri; // 'revins'
EXTERN int p_ru; // 'ruler'
EXTERN char_u *p_ruf; // 'rulerformat'
EXTERN char_u *p_pp; // 'packpath'
EXTERN char_u *p_qftf; // 'quickfixtextfunc'
EXTERN char_u *p_rtp; // 'runtimepath'
EXTERN long p_scbk; // 'scrollback'
EXTERN long p_sj; // 'scrolljump'

View File

@ -2073,6 +2073,14 @@ return {
varname='p_pyx',
defaults={if_true={vi=0}}
},
{
full_name='quickfixtextfunc', abbreviation='qftf',
short_desc=N_("customize the quickfix window"),
type='string', scope={'global'},
vi_def=true,
varname='p_qftf',
defaults={if_true={vi=""}}
},
{
full_name='quoteescape', abbreviation='qe',
short_desc=N_("escape characters used in a string"),

View File

@ -100,6 +100,7 @@ typedef struct qf_list_S {
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;
@ -1999,6 +2000,11 @@ static int copy_loclist(const qf_list_T *from_qfl, qf_list_T *to_qfl)
} 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) {
@ -3382,6 +3388,7 @@ static void qf_free(qf_list_T *qfl)
XFREE_CLEAR(qfl->qf_title);
tv_free(qfl->qf_ctx);
qfl->qf_ctx = NULL;
XFREE_CLEAR(qfl->qf_qftf);
qfl->qf_id = 0;
qfl->qf_changedtick = 0L;
}
@ -3721,7 +3728,7 @@ void ex_copen(exarg_T *eap)
lnum = qfl->qf_index;
// Fill the buffer with the quickfix list.
qf_fill_buffer(qfl, curbuf, NULL);
qf_fill_buffer(qfl, curbuf, NULL, curwin->handle);
decr_quickfix_busy();
@ -3884,6 +3891,11 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
buf = qf_find_buf(qi);
if (buf != NULL) {
linenr_T old_line_count = buf->b_ml.ml_line_count;
int qf_winid = 0;
if (IS_LL_STACK(qi)) {
qf_winid = curwin->handle;
}
if (old_last == NULL) {
// set curwin/curbuf to buf and save a few things
@ -3892,7 +3904,7 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
qf_update_win_titlevar(qi);
qf_fill_buffer(qf_get_curlist(qi), buf, old_last);
qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
buf_inc_changedtick(buf);
if (old_last == NULL) {
@ -3911,13 +3923,17 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
}
// Add an error line to the quickfix buffer.
static int qf_buf_add_line(buf_T *buf, linenr_T lnum, const qfline_T *qfp,
char_u *dirname, bool first_bufline)
FUNC_ATTR_NONNULL_ALL
static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
const qfline_T *qfp, char_u *dirname,
char_u *qftf_str, bool first_bufline)
FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5)
{
int len;
buf_T *errbuf;
if (qftf_str != NULL) {
STRLCPY(IObuff, qftf_str, IOSIZE);
} else {
if (qfp->qf_module != NULL) {
STRLCPY(IObuff, qfp->qf_module, IOSIZE);
len = (int)STRLEN(IObuff);
@ -3975,6 +3991,7 @@ static int qf_buf_add_line(buf_T *buf, linenr_T lnum, const qfline_T *qfp,
// 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) {
@ -3983,17 +4000,56 @@ static int qf_buf_add_line(buf_T *buf, linenr_T lnum, const qfline_T *qfp,
return OK;
}
static list_T *call_qftf_func(qf_list_T *qfl,
int qf_winid,
long start_idx,
long end_idx)
{
char_u *qftf = p_qftf;
list_T *qftf_list = NULL;
// If 'quickfixtextfunc' is set, then use the user-supplied function to get
// the text to display. Use the local value of 'quickfixtextfunc' if it is
// set.
if (qfl->qf_qftf != NULL) {
qftf = qfl->qf_qftf;
}
if (qftf != NULL && *qftf != NUL) {
typval_T args[1];
// create the dict argument
dict_T *const dict = tv_dict_alloc_lock(VAR_FIXED);
tv_dict_add_nr(dict, S_LEN("quickfix"), IS_QF_LIST(qfl));
tv_dict_add_nr(dict, S_LEN("winid"), qf_winid);
tv_dict_add_nr(dict, S_LEN("id"), qfl->qf_id);
tv_dict_add_nr(dict, S_LEN("start_idx"), start_idx);
tv_dict_add_nr(dict, S_LEN("end_idx"), end_idx);
dict->dv_refcount++;
args[0].v_type = VAR_DICT;
args[0].vval.v_dict = dict;
qftf_list = call_func_retlist(qftf, 1, args);
dict->dv_refcount--;
}
return qftf_list;
}
/// Fill current buffer with quickfix errors, replacing any previous contents.
/// curbuf must be the quickfix buffer!
/// If "old_last" is not NULL append the items after this one.
/// When "old_last" is NULL then "buf" must equal "curbuf"! Because ml_delete()
/// is used and autocommands will be triggered.
static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last)
static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
int qf_winid)
FUNC_ATTR_NONNULL_ARG(2)
{
linenr_T lnum;
qfline_T *qfp;
const bool old_KeyTyped = KeyTyped;
list_T *qftf_list = NULL;
listitem_T *qftf_li = NULL;
if (old_last == NULL) {
if (buf != curbuf) {
@ -4026,8 +4082,19 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last)
}
lnum = buf->b_ml.ml_line_count;
}
qftf_list = call_qftf_func(qfl, qf_winid, lnum + 1, (long)qfl->qf_count);
qftf_li = tv_list_first(qftf_list);
while (lnum < qfl->qf_count) {
if (qf_buf_add_line(buf, lnum, qfp, dirname,
char_u *qftf_str = NULL;
if (qftf_li != NULL) {
// Use the text supplied by the user defined function
qftf_str = (char_u *)tv_get_string_chk(TV_LIST_ITEM_TV(qftf_li));
}
if (qf_buf_add_line(qfl, buf, lnum, qfp, dirname, qftf_str,
prev_bufnr != qfp->qf_fnum) == FAIL) {
break;
}
@ -4037,6 +4104,10 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last)
if (qfp == NULL) {
break;
}
if (qftf_li != NULL) {
qftf_li = TV_LIST_ITEM_NEXT(qftf_list, qftf_li);
}
}
if (old_last == NULL) {
// Delete the empty line which is now at the end
@ -5665,7 +5736,10 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
/// Add each quickfix error to list "list" as a dictionary.
/// If qf_idx is -1, use the current list. Otherwise, use the specified list.
int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list)
/// If eidx is not 0, then return only the specified entry. Otherwise return
/// all the entries.
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;
@ -5682,6 +5756,10 @@ int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list)
}
}
if (eidx < 0) {
return OK;
}
if (qf_idx == INVALID_QFIDX) {
qf_idx = qi->qf_curlist;
}
@ -5696,7 +5774,13 @@ int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list)
}
FOR_ALL_QFL_ITEMS(qfl, qfp, i) {
get_qfline_items(qfp, list);
if (eidx > 0) {
if (eidx == i) {
return get_qfline_items(qfp, list);
}
} else if (get_qfline_items(qfp, list) == FAIL) {
return FAIL;
}
}
return OK;
@ -5743,7 +5827,7 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
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);
(void)get_errorlist(qi, NULL, 0, 0, l);
qf_free(&qi->qf_lists[0]);
}
xfree(qi);
@ -5934,11 +6018,13 @@ static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi,
return tv_dict_add_nr(retdict, S_LEN("filewinid"), winid);
}
/// 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)
/// 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)
{
list_T *l = tv_list_alloc(kListLenMayKnow);
get_errorlist(qi, NULL, qf_idx, l);
get_errorlist(qi, NULL, qf_idx, eidx, l);
tv_dict_add_list(retdict, S_LEN("items"), l);
return OK;
@ -5963,15 +6049,18 @@ static int qf_getprop_ctx(qf_list_T *qfl, dict_T *retdict)
return status;
}
/// Return the current quickfix list index as 'idx' in retdict
static int qf_getprop_idx(qf_list_T *qfl, dict_T *retdict)
/// 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)
{
int curidx = qfl->qf_index;
if (eidx == 0) {
eidx = qfl->qf_index;
if (qf_list_empty(qfl)) {
// For empty lists, current index is set to 0
curidx = 0;
eidx = 0;
}
return tv_dict_add_nr(retdict, S_LEN("idx"), curidx);
}
return tv_dict_add_nr(retdict, S_LEN("idx"), eidx);
}
/// Return quickfix/location list details (title) as a dictionary.
@ -5984,6 +6073,7 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
dictitem_T *di = NULL;
int status = OK;
int qf_idx = INVALID_QFIDX;
int eidx = 0;
if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) {
return qf_get_list_from_lines(what, di, retdict);
@ -6006,6 +6096,14 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
qfl = qf_get_list(qi, qf_idx);
// If an entry index is specified, use that
if ((di = tv_dict_find(what, S_LEN("idx"))) != NULL) {
if (di->di_tv.v_type != VAR_NUMBER) {
return FAIL;
}
eidx = (int)di->di_tv.vval.v_number;
}
if (flags & QF_GETLIST_TITLE) {
status = qf_getprop_title(qfl, retdict);
}
@ -6016,7 +6114,7 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
status = tv_dict_add_nr(retdict, S_LEN("winid"), qf_winid(qi));
}
if ((status == OK) && (flags & QF_GETLIST_ITEMS)) {
status = qf_getprop_items(qi, qf_idx, retdict);
status = qf_getprop_items(qi, qf_idx, eidx, retdict);
}
if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) {
status = qf_getprop_ctx(qfl, retdict);
@ -6025,7 +6123,7 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
status = tv_dict_add_nr(retdict, S_LEN("id"), qfl->qf_id);
}
if ((status == OK) && (flags & QF_GETLIST_IDX)) {
status = qf_getprop_idx(qfl, retdict);
status = qf_getprop_idx(qfl, eidx, retdict);
}
if ((status == OK) && (flags & QF_GETLIST_SIZE)) {
status = tv_dict_add_nr(retdict, S_LEN("size"),
@ -6042,6 +6140,17 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
return status;
}
/// Set the current index in the specified quickfix list
static int qf_setprop_qftf(qf_info_T *qi, qf_list_T *qfl,
dictitem_T *di)
{
XFREE_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;
}
/// Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the
/// items in the dict 'd'. If it is a valid error entry, then set 'valid_entry'
/// to true.
@ -6407,6 +6516,9 @@ static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action,
if ((di = tv_dict_find(what, S_LEN("idx"))) != NULL) {
retval = qf_setprop_curidx(qi, qfl, di);
}
if ((di = tv_dict_find(what, S_LEN("quickfixtextfunc"))) != NULL) {
retval = qf_setprop_qftf(qi, qfl, di);
}
if (newlist || retval == OK) {
qf_list_changed(qfl);

View File

@ -4786,4 +4786,148 @@ func Test_qfbuf_update()
call Xqfbuf_update('l')
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, 'items' : 1}).items
else
let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
endif
let l = []
for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
let e = qfl[idx]
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
call add(l, s)
endfor
return l
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, 'items' : 1}).items
else
let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
endif
if empty(qfl)
return []
endif
let l = []
for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
endfor
return l
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
" Add entries to the list when the quickfix buffer is hidden
Xaddexpr ['F1:30:6:red']
Xwindow
call assert_equal('Line 30, Col 6', getline(3))
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:')
Xexpr ['F1:10:2:green', 'F1:20:4:blue']"
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:')
Xexpr ['F1:10:2:green', 'F1:20:4:blue']"
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:')
Xexpr ['F1:10:2:green', 'F1:20:4:blue']"
call assert_fails("Xwindow", 'E119:')
Xclose
" set option to a function that returns a list with non-strings
func Xqftext2(d)
return ['one', [], 'two']
endfunc
set quickfixtextfunc=Xqftext2
" call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
" \ 'E730:')
Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']
call assert_fails('Xwindow', 'E730:')
call assert_equal(['one', 'F1|20 col 4| blue', 'two'], getline(1, '$'))
Xclose
set quickfixtextfunc&
delfunc Xqftext
delfunc Xqftext2
endfunc
func Test_qftextfunc()
call Xtest_qftextfunc('c')
call Xtest_qftextfunc('l')
endfunc
" vim: shiftwidth=2 sts=2 expandtab