comparison 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
comparison
equal deleted inserted replaced
20813:a7c491ba7e3f 20814:f23c6543a54d
4413 /* 4413 /*
4414 * Add an error line to the quickfix buffer. 4414 * Add an error line to the quickfix buffer.
4415 */ 4415 */
4416 static int 4416 static int
4417 qf_buf_add_line( 4417 qf_buf_add_line(
4418 qf_list_T *qfl, // quickfix list
4419 buf_T *buf, // quickfix window buffer 4418 buf_T *buf, // quickfix window buffer
4420 linenr_T lnum, 4419 linenr_T lnum,
4421 qfline_T *qfp, 4420 qfline_T *qfp,
4422 char_u *dirname, 4421 char_u *dirname,
4423 int qf_winid) 4422 char_u *qftf_str)
4424 { 4423 {
4425 int len; 4424 int len;
4426 buf_T *errbuf; 4425 buf_T *errbuf;
4427 char_u *qftf; 4426
4428 4427 if (qftf_str != NULL)
4429 // If 'quickfixtextfunc' is set, then use the user-supplied function to get 4428 vim_strncpy(IObuff, qftf_str, IOSIZE - 1);
4430 // the text to display
4431 qftf = p_qftf;
4432 // Use the local value of 'quickfixtextfunc' if it is set.
4433 if (qfl->qf_qftf != NULL)
4434 qftf = qfl->qf_qftf;
4435 if (qftf != NULL && *qftf != NUL)
4436 {
4437 char_u *qfbuf_text;
4438 typval_T args[1];
4439 dict_T *d;
4440
4441 // create the dict argument
4442 if ((d = dict_alloc_lock(VAR_FIXED)) == NULL)
4443 return FAIL;
4444 dict_add_number(d, "quickfix", (long)IS_QF_LIST(qfl));
4445 dict_add_number(d, "winid", (long)qf_winid);
4446 dict_add_number(d, "id", (long)qfl->qf_id);
4447 dict_add_number(d, "idx", (long)(lnum + 1));
4448 ++d->dv_refcount;
4449 args[0].v_type = VAR_DICT;
4450 args[0].vval.v_dict = d;
4451
4452 qfbuf_text = call_func_retstr(qftf, 1, args);
4453 --d->dv_refcount;
4454
4455 if (qfbuf_text == NULL)
4456 return FAIL;
4457
4458 vim_strncpy(IObuff, qfbuf_text, IOSIZE - 1);
4459 vim_free(qfbuf_text);
4460 }
4461 else 4429 else
4462 { 4430 {
4463 if (qfp->qf_module != NULL) 4431 if (qfp->qf_module != NULL)
4464 { 4432 {
4465 vim_strncpy(IObuff, qfp->qf_module, IOSIZE - 1); 4433 vim_strncpy(IObuff, qfp->qf_module, IOSIZE - 1);
4531 return FAIL; 4499 return FAIL;
4532 4500
4533 return OK; 4501 return OK;
4534 } 4502 }
4535 4503
4504 static list_T *
4505 call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx)
4506 {
4507 char_u *qftf = p_qftf;
4508 list_T *qftf_list = NULL;
4509
4510 // If 'quickfixtextfunc' is set, then use the user-supplied function to get
4511 // the text to display. Use the local value of 'quickfixtextfunc' if it is
4512 // set.
4513 if (qfl->qf_qftf != NULL)
4514 qftf = qfl->qf_qftf;
4515 if (qftf != NULL && *qftf != NUL)
4516 {
4517 typval_T args[1];
4518 dict_T *d;
4519
4520 // create the dict argument
4521 if ((d = dict_alloc_lock(VAR_FIXED)) == NULL)
4522 return NULL;
4523 dict_add_number(d, "quickfix", (long)IS_QF_LIST(qfl));
4524 dict_add_number(d, "winid", (long)qf_winid);
4525 dict_add_number(d, "id", (long)qfl->qf_id);
4526 dict_add_number(d, "start_idx", start_idx);
4527 dict_add_number(d, "end_idx", end_idx);
4528 ++d->dv_refcount;
4529 args[0].v_type = VAR_DICT;
4530 args[0].vval.v_dict = d;
4531
4532 qftf_list = call_func_retlist(qftf, 1, args);
4533 --d->dv_refcount;
4534 }
4535
4536 return qftf_list;
4537 }
4538
4536 /* 4539 /*
4537 * Fill current buffer with quickfix errors, replacing any previous contents. 4540 * Fill current buffer with quickfix errors, replacing any previous contents.
4538 * curbuf must be the quickfix buffer! 4541 * curbuf must be the quickfix buffer!
4539 * If "old_last" is not NULL append the items after this one. 4542 * If "old_last" is not NULL append the items after this one.
4540 * When "old_last" is NULL then "buf" must equal "curbuf"! Because 4543 * When "old_last" is NULL then "buf" must equal "curbuf"! Because
4544 qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid) 4547 qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
4545 { 4548 {
4546 linenr_T lnum; 4549 linenr_T lnum;
4547 qfline_T *qfp; 4550 qfline_T *qfp;
4548 int old_KeyTyped = KeyTyped; 4551 int old_KeyTyped = KeyTyped;
4552 list_T *qftf_list = NULL;
4553 listitem_T *qftf_li = NULL;
4549 4554
4550 if (old_last == NULL) 4555 if (old_last == NULL)
4551 { 4556 {
4552 if (buf != curbuf) 4557 if (buf != curbuf)
4553 { 4558 {
4576 else 4581 else
4577 { 4582 {
4578 qfp = old_last->qf_next; 4583 qfp = old_last->qf_next;
4579 lnum = buf->b_ml.ml_line_count; 4584 lnum = buf->b_ml.ml_line_count;
4580 } 4585 }
4586
4587 qftf_list = call_qftf_func(qfl, qf_winid, (long)(lnum + 1),
4588 (long)qfl->qf_count);
4589 if (qftf_list != NULL)
4590 qftf_li = qftf_list->lv_first;
4591
4581 while (lnum < qfl->qf_count) 4592 while (lnum < qfl->qf_count)
4582 { 4593 {
4583 if (qf_buf_add_line(qfl, buf, lnum, qfp, dirname, qf_winid) == FAIL) 4594 char_u *qftf_str = NULL;
4595
4596 if (qftf_li != NULL)
4597 // Use the text supplied by the user defined function
4598 qftf_str = tv_get_string_chk(&qftf_li->li_tv);
4599
4600 if (qf_buf_add_line(buf, lnum, qfp, dirname, qftf_str) == FAIL)
4584 break; 4601 break;
4585 4602
4586 ++lnum; 4603 ++lnum;
4587 qfp = qfp->qf_next; 4604 qfp = qfp->qf_next;
4588 if (qfp == NULL) 4605 if (qfp == NULL)
4589 break; 4606 break;
4607
4608 if (qftf_li != NULL)
4609 qftf_li = qftf_li->li_next;
4590 } 4610 }
4591 4611
4592 if (old_last == NULL) 4612 if (old_last == NULL)
4593 // Delete the empty line which is now at the end 4613 // Delete the empty line which is now at the end
4594 (void)ml_delete(lnum + 1); 4614 (void)ml_delete(lnum + 1);