comparison src/quickfix.c @ 13594:4d55eb79178b v8.0.1669

patch 8.0.1669: :vimgrep may add entries to the wrong quickfix list commit https://github.com/vim/vim/commit/e1bb879f49665bb828197135b80aaf72cc190073 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Apr 6 22:58:23 2018 +0200 patch 8.0.1669: :vimgrep may add entries to the wrong quickfix list Problem: :vimgrep may add entries to the wrong quickfix list. Solution: Use the list identifier. (Yegappan Lakshmanan)
author Christian Brabandt <cb@256bit.org>
date Fri, 06 Apr 2018 23:00:08 +0200
parents 15c856a1617b
children 89223f5d5d12
comparison
equal deleted inserted replaced
13593:1e1e371e8a4c 13594:4d55eb79178b
4158 if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile)) 4158 if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile))
4159 qf_jump(qi, 0, 0, eap->forceit); /* display first error */ 4159 qf_jump(qi, 0, 0, eap->forceit); /* display first error */
4160 } 4160 }
4161 4161
4162 /* 4162 /*
4163 * Return the quickfix/location list number with the given identifier.
4164 * Returns -1 if list is not found.
4165 */
4166 static int
4167 qf_id2nr(qf_info_T *qi, int_u qfid)
4168 {
4169 int qf_idx;
4170
4171 for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
4172 if (qi->qf_lists[qf_idx].qf_id == qfid)
4173 return qf_idx;
4174 return -1;
4175 }
4176
4177 /*
4163 * Return the vimgrep autocmd name. 4178 * Return the vimgrep autocmd name.
4164 */ 4179 */
4165 static char_u * 4180 static char_u *
4166 vgr_get_auname(cmdidx_T cmdidx) 4181 vgr_get_auname(cmdidx_T cmdidx)
4167 { 4182 {
4270 * a quickfix list when vimgrep is running. If the list is not found, create a 4285 * a quickfix list when vimgrep is running. If the list is not found, create a
4271 * new list. 4286 * new list.
4272 */ 4287 */
4273 static int 4288 static int
4274 vgr_qflist_valid( 4289 vgr_qflist_valid(
4290 win_T *wp,
4275 qf_info_T *qi, 4291 qf_info_T *qi,
4276 int_u save_qfid, 4292 int_u qfid,
4277 qfline_T *cur_qf_start,
4278 int loclist_cmd,
4279 char_u *title) 4293 char_u *title)
4280 { 4294 {
4281 if (loclist_cmd) 4295 /* Verify that the quickfix/location list was not freed by an autocmd */
4282 { 4296 if (!qflist_valid(wp, qfid))
4283 /* 4297 {
4284 * Verify that the location list is still valid. An autocmd might 4298 if (wp != NULL)
4285 * have freed the location list. 4299 {
4286 */ 4300 /* An autocmd has freed the location list. */
4287 if (!qflist_valid(curwin, save_qfid))
4288 {
4289 EMSG(_(e_loc_list_changed)); 4301 EMSG(_(e_loc_list_changed));
4290 return FALSE; 4302 return FALSE;
4291 } 4303 }
4292 } 4304 else
4293 if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start) 4305 {
4294 { 4306 /* Quickfix list is not found, create a new one. */
4295 int idx; 4307 qf_new_list(qi, title);
4296 4308 return TRUE;
4309 }
4310 }
4311
4312 if (qi->qf_lists[qi->qf_curlist].qf_id != qfid)
4297 /* Autocommands changed the quickfix list. Find the one we were 4313 /* Autocommands changed the quickfix list. Find the one we were
4298 * using and restore it. */ 4314 * using and restore it. */
4299 for (idx = 0; idx < LISTCOUNT; ++idx) 4315 qi->qf_curlist = qf_id2nr(qi, qfid);
4300 if (cur_qf_start == qi->qf_lists[idx].qf_start)
4301 {
4302 qi->qf_curlist = idx;
4303 break;
4304 }
4305 if (idx == LISTCOUNT)
4306 /* List cannot be found, create a new one. */
4307 qf_new_list(qi, title);
4308 }
4309 4316
4310 return TRUE; 4317 return TRUE;
4311 } 4318 }
4312 4319
4313 /* 4320 /*
4422 char_u *title; 4429 char_u *title;
4423 char_u *s; 4430 char_u *s;
4424 char_u *p; 4431 char_u *p;
4425 int fi; 4432 int fi;
4426 qf_info_T *qi = &ql_info; 4433 qf_info_T *qi = &ql_info;
4427 int loclist_cmd = FALSE;
4428 int_u save_qfid; 4434 int_u save_qfid;
4429 qfline_T *cur_qf_start; 4435 win_T *wp = NULL;
4430 win_T *wp;
4431 buf_T *buf; 4436 buf_T *buf;
4432 int duplicate_name = FALSE; 4437 int duplicate_name = FALSE;
4433 int using_dummy; 4438 int using_dummy;
4434 int redraw_for_dummy = FALSE; 4439 int redraw_for_dummy = FALSE;
4435 int found_match; 4440 int found_match;
4459 || eap->cmdidx == CMD_lvimgrepadd) 4464 || eap->cmdidx == CMD_lvimgrepadd)
4460 { 4465 {
4461 qi = ll_get_or_alloc_list(curwin); 4466 qi = ll_get_or_alloc_list(curwin);
4462 if (qi == NULL) 4467 if (qi == NULL)
4463 return; 4468 return;
4464 loclist_cmd = TRUE; 4469 wp = curwin;
4465 } 4470 }
4466 4471
4467 if (eap->addr_count > 0) 4472 if (eap->addr_count > 0)
4468 tomatch = eap->line2; 4473 tomatch = eap->line2;
4469 else 4474 else
4516 4521
4517 /* Remember the current directory, because a BufRead autocommand that does 4522 /* Remember the current directory, because a BufRead autocommand that does
4518 * ":lcd %:p:h" changes the meaning of short path names. */ 4523 * ":lcd %:p:h" changes the meaning of short path names. */
4519 mch_dirname(dirname_start, MAXPATHL); 4524 mch_dirname(dirname_start, MAXPATHL);
4520 4525
4521 /* Remember the current values of the quickfix list and qf_start, so that 4526 /* Remember the current quickfix list identifier, so that we can check for
4522 * we can check for autocommands changing the current quickfix list. */ 4527 * autocommands changing the current quickfix list. */
4523 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 4528 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id;
4524 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
4525 4529
4526 seconds = (time_t)0; 4530 seconds = (time_t)0;
4527 for (fi = 0; fi < fcount && !got_int && tomatch > 0; ++fi) 4531 for (fi = 0; fi < fcount && !got_int && tomatch > 0; ++fi)
4528 { 4532 {
4529 fname = shorten_fname1(fnames[fi]); 4533 fname = shorten_fname1(fnames[fi]);
4547 } 4551 }
4548 else 4552 else
4549 /* Use existing, loaded buffer. */ 4553 /* Use existing, loaded buffer. */
4550 using_dummy = FALSE; 4554 using_dummy = FALSE;
4551 4555
4552 /* Check whether the quickfix list is still valid */ 4556 /* Check whether the quickfix list is still valid. When loading a
4553 if (!vgr_qflist_valid(qi, save_qfid, cur_qf_start, loclist_cmd, 4557 * buffer above, autocommands might have changed the quickfix list. */
4554 *eap->cmdlinep)) 4558 if (!vgr_qflist_valid(wp, qi, save_qfid, *eap->cmdlinep))
4555 goto theend; 4559 goto theend;
4556 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start; 4560 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id;
4557 4561
4558 if (buf == NULL) 4562 if (buf == NULL)
4559 { 4563 {
4560 if (!got_int) 4564 if (!got_int)
4561 smsg((char_u *)_("Cannot open file \"%s\""), fname); 4565 smsg((char_u *)_("Cannot open file \"%s\""), fname);
4564 { 4568 {
4565 /* Try for a match in all lines of the buffer. 4569 /* Try for a match in all lines of the buffer.
4566 * For ":1vimgrep" look for first match only. */ 4570 * For ":1vimgrep" look for first match only. */
4567 found_match = vgr_match_buflines(qi, fname, buf, &regmatch, 4571 found_match = vgr_match_buflines(qi, fname, buf, &regmatch,
4568 tomatch, duplicate_name, flags); 4572 tomatch, duplicate_name, flags);
4569
4570 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
4571 4573
4572 if (using_dummy) 4574 if (using_dummy)
4573 { 4575 {
4574 if (found_match && first_match_buf == NULL) 4576 if (found_match && first_match_buf == NULL)
4575 first_match_buf = buf; 4577 first_match_buf = buf;
4647 curbuf->b_fname, TRUE, curbuf); 4649 curbuf->b_fname, TRUE, curbuf);
4648 /* 4650 /*
4649 * The QuickFixCmdPost autocmd may free the quickfix list. Check the list 4651 * The QuickFixCmdPost autocmd may free the quickfix list. Check the list
4650 * is still valid. 4652 * is still valid.
4651 */ 4653 */
4652 wp = loclist_cmd ? curwin : NULL;
4653 if (!qflist_valid(wp, save_qfid)) 4654 if (!qflist_valid(wp, save_qfid))
4654 goto theend; 4655 goto theend;
4655 4656
4656 /* Jump to first match. */ 4657 /* Jump to first match. */
4657 if (qi->qf_lists[qi->qf_curlist].qf_count > 0) 4658 if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
4990 dict_add_list(retdict, "items", l); 4991 dict_add_list(retdict, "items", l);
4991 status = OK; 4992 status = OK;
4992 } 4993 }
4993 4994
4994 return status; 4995 return status;
4995 }
4996
4997 /*
4998 * Return the quickfix/location list number with the given identifier.
4999 * Returns -1 if list is not found.
5000 */
5001 static int
5002 qf_id2nr(qf_info_T *qi, int_u qfid)
5003 {
5004 int qf_idx;
5005
5006 for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
5007 if (qi->qf_lists[qf_idx].qf_id == qfid)
5008 return qf_idx;
5009 return -1;
5010 } 4996 }
5011 4997
5012 /* 4998 /*
5013 * Return the quickfix/location list window identifier in the current tabpage. 4999 * Return the quickfix/location list window identifier in the current tabpage.
5014 */ 5000 */