mirror of
https://github.com/vim/vim.git
synced 2025-10-07 05:54:16 -04:00
patch 8.2.0959: using 'quickfixtextfunc' is a bit slow
Problem: Using 'quickfixtextfunc' is a bit slow. Solution: Process a list of entries. (Yegappan Lakshmanan, closes #6234)
This commit is contained in:
@@ -4415,49 +4415,17 @@ qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
|
||||
*/
|
||||
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 qf_winid)
|
||||
char_u *qftf_str)
|
||||
{
|
||||
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 the 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, "winid", (long)qf_winid);
|
||||
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);
|
||||
}
|
||||
if (qftf_str != NULL)
|
||||
vim_strncpy(IObuff, qftf_str, IOSIZE - 1);
|
||||
else
|
||||
{
|
||||
if (qfp->qf_module != NULL)
|
||||
@@ -4533,6 +4501,41 @@ qf_buf_add_line(
|
||||
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];
|
||||
dict_T *d;
|
||||
|
||||
// create the dict argument
|
||||
if ((d = dict_alloc_lock(VAR_FIXED)) == NULL)
|
||||
return NULL;
|
||||
dict_add_number(d, "quickfix", (long)IS_QF_LIST(qfl));
|
||||
dict_add_number(d, "winid", (long)qf_winid);
|
||||
dict_add_number(d, "id", (long)qfl->qf_id);
|
||||
dict_add_number(d, "start_idx", start_idx);
|
||||
dict_add_number(d, "end_idx", end_idx);
|
||||
++d->dv_refcount;
|
||||
args[0].v_type = VAR_DICT;
|
||||
args[0].vval.v_dict = d;
|
||||
|
||||
qftf_list = call_func_retlist(qftf, 1, args);
|
||||
--d->dv_refcount;
|
||||
}
|
||||
|
||||
return qftf_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill current buffer with quickfix errors, replacing any previous contents.
|
||||
* curbuf must be the quickfix buffer!
|
||||
@@ -4546,6 +4549,8 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
|
||||
linenr_T lnum;
|
||||
qfline_T *qfp;
|
||||
int old_KeyTyped = KeyTyped;
|
||||
list_T *qftf_list = NULL;
|
||||
listitem_T *qftf_li = NULL;
|
||||
|
||||
if (old_last == NULL)
|
||||
{
|
||||
@@ -4578,15 +4583,30 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
|
||||
qfp = old_last->qf_next;
|
||||
lnum = buf->b_ml.ml_line_count;
|
||||
}
|
||||
|
||||
qftf_list = call_qftf_func(qfl, qf_winid, (long)(lnum + 1),
|
||||
(long)qfl->qf_count);
|
||||
if (qftf_list != NULL)
|
||||
qftf_li = qftf_list->lv_first;
|
||||
|
||||
while (lnum < qfl->qf_count)
|
||||
{
|
||||
if (qf_buf_add_line(qfl, buf, lnum, qfp, dirname, qf_winid) == FAIL)
|
||||
char_u *qftf_str = NULL;
|
||||
|
||||
if (qftf_li != NULL)
|
||||
// Use the text supplied by the user defined function
|
||||
qftf_str = tv_get_string_chk(&qftf_li->li_tv);
|
||||
|
||||
if (qf_buf_add_line(buf, lnum, qfp, dirname, qftf_str) == FAIL)
|
||||
break;
|
||||
|
||||
++lnum;
|
||||
qfp = qfp->qf_next;
|
||||
if (qfp == NULL)
|
||||
break;
|
||||
|
||||
if (qftf_li != NULL)
|
||||
qftf_li = qftf_li->li_next;
|
||||
}
|
||||
|
||||
if (old_last == NULL)
|
||||
|
@@ -4818,24 +4818,26 @@ 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
|
||||
let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
|
||||
else
|
||||
let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'idx' : a:info.idx,
|
||||
\ 'items' : 1}).items
|
||||
let qfl = getloclist(a:info.winid, {'id' : a:info.id, '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
|
||||
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 s
|
||||
return l
|
||||
endfunc
|
||||
|
||||
func Xtest_qftextfunc(cchar)
|
||||
@@ -4859,16 +4861,18 @@ func Xtest_qftextfunc(cchar)
|
||||
" 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
|
||||
let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
|
||||
else
|
||||
let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'idx' : a:info.idx,
|
||||
\ 'items' : 1}).items
|
||||
let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
|
||||
endif
|
||||
if empty(qfl)
|
||||
return ''
|
||||
return []
|
||||
endif
|
||||
return 'Line ' .. qfl[0].lnum .. ', Col ' .. qfl[0].col
|
||||
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"})
|
||||
@@ -4908,8 +4912,21 @@ func Xtest_qftextfunc(cchar)
|
||||
call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
|
||||
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:')
|
||||
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()
|
||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
959,
|
||||
/**/
|
||||
958,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user