diff src/quickfix.c @ 20814:f23c6543a54d v8.2.0959

patch 8.2.0959: using 'quickfixtextfunc' is a bit slow Commit: https://github.com/vim/vim/commit/00e260bb6cc33ff5dbba15ac87ca7fd465aa49c0 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jun 11 19:35:52 2020 +0200 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 https://github.com/vim/vim/issues/6234)
author Bram Moolenaar <Bram@vim.org>
date Thu, 11 Jun 2020 19:45:03 +0200
parents 3c61d8ec36af
children 3af71cbcfdbe
line wrap: on
line diff
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4415,49 +4415,17 @@ qf_update_buffer(qf_info_T *qi, qfline_T
  */
     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 *bu
     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 *bu
 	    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)