Mercurial > vim
comparison src/quickfix.c @ 13521:15c856a1617b v8.0.1634
patch 8.0.1634: the ex_vimgrep() function is too long
commit https://github.com/vim/vim/commit/75b0a888e41bcda4163072f41bb7b5471fef7651
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 24 14:01:56 2018 +0100
patch 8.0.1634: the ex_vimgrep() function is too long
Problem: The ex_vimgrep() function is too long.
Solution: Split it in smaller functions. (Yegappan Lakshmanan)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 24 Mar 2018 14:15:07 +0100 |
parents | 23ae1853abbb |
children | 4d55eb79178b |
comparison
equal
deleted
inserted
replaced
13520:649cf8867fec | 13521:15c856a1617b |
---|---|
131 }; | 131 }; |
132 | 132 |
133 static efm_T *fmt_start = NULL; /* cached across qf_parse_line() calls */ | 133 static efm_T *fmt_start = NULL; /* cached across qf_parse_line() calls */ |
134 | 134 |
135 static int qf_init_ext(qf_info_T *qi, int qf_idx, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title, char_u *enc); | 135 static int qf_init_ext(qf_info_T *qi, int qf_idx, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title, char_u *enc); |
136 static void qf_store_title(qf_info_T *qi, int qf_idx, char_u *title); | |
137 static void qf_new_list(qf_info_T *qi, char_u *qf_title); | 136 static void qf_new_list(qf_info_T *qi, char_u *qf_title); |
138 static void ll_free_all(qf_info_T **pqi); | |
139 static int qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); | 137 static int qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); |
140 static qf_info_T *ll_new_list(void); | |
141 static void qf_free(qf_info_T *qi, int idx); | 138 static void qf_free(qf_info_T *qi, int idx); |
142 static char_u *qf_types(int, int); | 139 static char_u *qf_types(int, int); |
143 static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *); | 140 static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *); |
144 static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack); | 141 static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack); |
145 static char_u *qf_pop_dir(struct dir_stack_T **); | 142 static char_u *qf_pop_dir(struct dir_stack_T **); |
146 static char_u *qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *); | 143 static char_u *qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *); |
147 static int qflist_valid(win_T *wp, int_u qf_id); | |
148 static void qf_fmt_text(char_u *text, char_u *buf, int bufsize); | 144 static void qf_fmt_text(char_u *text, char_u *buf, int bufsize); |
149 static void qf_clean_dir_stack(struct dir_stack_T **); | |
150 static int qf_win_pos_update(qf_info_T *qi, int old_qf_index); | 145 static int qf_win_pos_update(qf_info_T *qi, int old_qf_index); |
151 static int is_qf_win(win_T *win, qf_info_T *qi); | |
152 static win_T *qf_find_win(qf_info_T *qi); | 146 static win_T *qf_find_win(qf_info_T *qi); |
153 static buf_T *qf_find_buf(qf_info_T *qi); | 147 static buf_T *qf_find_buf(qf_info_T *qi); |
154 static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last); | 148 static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last); |
155 static void qf_set_title_var(qf_info_T *qi); | 149 static void qf_set_title_var(qf_info_T *qi); |
156 static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last); | 150 static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last); |
157 static char_u *get_mef_name(void); | 151 static char_u *get_mef_name(void); |
158 static void restore_start_dir(char_u *dirname_start); | |
159 static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir); | 152 static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir); |
160 static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start); | 153 static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start); |
161 static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start); | 154 static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start); |
162 static qf_info_T *ll_get_or_alloc_list(win_T *); | 155 static qf_info_T *ll_get_or_alloc_list(win_T *); |
163 | 156 |
4165 if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile)) | 4158 if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile)) |
4166 qf_jump(qi, 0, 0, eap->forceit); /* display first error */ | 4159 qf_jump(qi, 0, 0, eap->forceit); /* display first error */ |
4167 } | 4160 } |
4168 | 4161 |
4169 /* | 4162 /* |
4163 * Return the vimgrep autocmd name. | |
4164 */ | |
4165 static char_u * | |
4166 vgr_get_auname(cmdidx_T cmdidx) | |
4167 { | |
4168 switch (cmdidx) | |
4169 { | |
4170 case CMD_vimgrep: return (char_u *)"vimgrep"; | |
4171 case CMD_lvimgrep: return (char_u *)"lvimgrep"; | |
4172 case CMD_vimgrepadd: return (char_u *)"vimgrepadd"; | |
4173 case CMD_lvimgrepadd: return (char_u *)"lvimgrepadd"; | |
4174 case CMD_grep: return (char_u *)"grep"; | |
4175 case CMD_lgrep: return (char_u *)"lgrep"; | |
4176 case CMD_grepadd: return (char_u *)"grepadd"; | |
4177 case CMD_lgrepadd: return (char_u *)"lgrepadd"; | |
4178 default: return NULL; | |
4179 } | |
4180 } | |
4181 | |
4182 /* | |
4183 * Initialize the regmatch used by vimgrep for pattern "s". | |
4184 */ | |
4185 static void | |
4186 vgr_init_regmatch(regmmatch_T *regmatch, char_u *s) | |
4187 { | |
4188 /* Get the search pattern: either white-separated or enclosed in // */ | |
4189 regmatch->regprog = NULL; | |
4190 | |
4191 if (s == NULL || *s == NUL) | |
4192 { | |
4193 /* Pattern is empty, use last search pattern. */ | |
4194 if (last_search_pat() == NULL) | |
4195 { | |
4196 EMSG(_(e_noprevre)); | |
4197 return; | |
4198 } | |
4199 regmatch->regprog = vim_regcomp(last_search_pat(), RE_MAGIC); | |
4200 } | |
4201 else | |
4202 regmatch->regprog = vim_regcomp(s, RE_MAGIC); | |
4203 | |
4204 regmatch->rmm_ic = p_ic; | |
4205 regmatch->rmm_maxcol = 0; | |
4206 } | |
4207 | |
4208 /* | |
4209 * Display a file name when vimgrep is running. | |
4210 */ | |
4211 static void | |
4212 vgr_display_fname(char_u *fname) | |
4213 { | |
4214 char_u *p; | |
4215 | |
4216 msg_start(); | |
4217 p = msg_strtrunc(fname, TRUE); | |
4218 if (p == NULL) | |
4219 msg_outtrans(fname); | |
4220 else | |
4221 { | |
4222 msg_outtrans(p); | |
4223 vim_free(p); | |
4224 } | |
4225 msg_clr_eos(); | |
4226 msg_didout = FALSE; /* overwrite this message */ | |
4227 msg_nowait = TRUE; /* don't wait for this message */ | |
4228 msg_col = 0; | |
4229 out_flush(); | |
4230 } | |
4231 | |
4232 /* | |
4233 * Load a dummy buffer to search for a pattern using vimgrep. | |
4234 */ | |
4235 static buf_T * | |
4236 vgr_load_dummy_buf( | |
4237 char_u *fname, | |
4238 char_u *dirname_start, | |
4239 char_u *dirname_now) | |
4240 { | |
4241 int save_mls; | |
4242 #if defined(FEAT_SYN_HL) | |
4243 char_u *save_ei = NULL; | |
4244 #endif | |
4245 buf_T *buf; | |
4246 | |
4247 #if defined(FEAT_SYN_HL) | |
4248 /* Don't do Filetype autocommands to avoid loading syntax and | |
4249 * indent scripts, a great speed improvement. */ | |
4250 save_ei = au_event_disable(",Filetype"); | |
4251 #endif | |
4252 /* Don't use modelines here, it's useless. */ | |
4253 save_mls = p_mls; | |
4254 p_mls = 0; | |
4255 | |
4256 /* Load file into a buffer, so that 'fileencoding' is detected, | |
4257 * autocommands applied, etc. */ | |
4258 buf = load_dummy_buffer(fname, dirname_start, dirname_now); | |
4259 | |
4260 p_mls = save_mls; | |
4261 #if defined(FEAT_SYN_HL) | |
4262 au_event_restore(save_ei); | |
4263 #endif | |
4264 | |
4265 return buf; | |
4266 } | |
4267 | |
4268 /* | |
4269 * Check whether a quickfix/location list valid. Autocmds may remove or change | |
4270 * a quickfix list when vimgrep is running. If the list is not found, create a | |
4271 * new list. | |
4272 */ | |
4273 static int | |
4274 vgr_qflist_valid( | |
4275 qf_info_T *qi, | |
4276 int_u save_qfid, | |
4277 qfline_T *cur_qf_start, | |
4278 int loclist_cmd, | |
4279 char_u *title) | |
4280 { | |
4281 if (loclist_cmd) | |
4282 { | |
4283 /* | |
4284 * Verify that the location list is still valid. An autocmd might | |
4285 * have freed the location list. | |
4286 */ | |
4287 if (!qflist_valid(curwin, save_qfid)) | |
4288 { | |
4289 EMSG(_(e_loc_list_changed)); | |
4290 return FALSE; | |
4291 } | |
4292 } | |
4293 if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start) | |
4294 { | |
4295 int idx; | |
4296 | |
4297 /* Autocommands changed the quickfix list. Find the one we were | |
4298 * using and restore it. */ | |
4299 for (idx = 0; idx < LISTCOUNT; ++idx) | |
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 | |
4310 return TRUE; | |
4311 } | |
4312 | |
4313 /* | |
4314 * Search for a pattern in all the lines in a buffer and add the matching lines | |
4315 * to a quickfix list. | |
4316 */ | |
4317 static int | |
4318 vgr_match_buflines( | |
4319 qf_info_T *qi, | |
4320 char_u *fname, | |
4321 buf_T *buf, | |
4322 regmmatch_T *regmatch, | |
4323 long tomatch, | |
4324 int duplicate_name, | |
4325 int flags) | |
4326 { | |
4327 int found_match = FALSE; | |
4328 long lnum; | |
4329 colnr_T col; | |
4330 | |
4331 for (lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0; ++lnum) | |
4332 { | |
4333 col = 0; | |
4334 while (vim_regexec_multi(regmatch, curwin, buf, lnum, | |
4335 col, NULL, NULL) > 0) | |
4336 { | |
4337 /* Pass the buffer number so that it gets used even for a | |
4338 * dummy buffer, unless duplicate_name is set, then the | |
4339 * buffer will be wiped out below. */ | |
4340 if (qf_add_entry(qi, | |
4341 qi->qf_curlist, | |
4342 NULL, /* dir */ | |
4343 fname, | |
4344 duplicate_name ? 0 : buf->b_fnum, | |
4345 ml_get_buf(buf, | |
4346 regmatch->startpos[0].lnum + lnum, FALSE), | |
4347 regmatch->startpos[0].lnum + lnum, | |
4348 regmatch->startpos[0].col + 1, | |
4349 FALSE, /* vis_col */ | |
4350 NULL, /* search pattern */ | |
4351 0, /* nr */ | |
4352 0, /* type */ | |
4353 TRUE /* valid */ | |
4354 ) == FAIL) | |
4355 { | |
4356 got_int = TRUE; | |
4357 break; | |
4358 } | |
4359 found_match = TRUE; | |
4360 if (--tomatch == 0) | |
4361 break; | |
4362 if ((flags & VGR_GLOBAL) == 0 | |
4363 || regmatch->endpos[0].lnum > 0) | |
4364 break; | |
4365 col = regmatch->endpos[0].col | |
4366 + (col == regmatch->endpos[0].col); | |
4367 if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE))) | |
4368 break; | |
4369 } | |
4370 line_breakcheck(); | |
4371 if (got_int) | |
4372 break; | |
4373 } | |
4374 | |
4375 return found_match; | |
4376 } | |
4377 | |
4378 /* | |
4379 * Jump to the first match and update the directory. | |
4380 */ | |
4381 static void | |
4382 vgr_jump_to_match( | |
4383 qf_info_T *qi, | |
4384 int forceit, | |
4385 int *redraw_for_dummy, | |
4386 buf_T *first_match_buf, | |
4387 char_u *target_dir) | |
4388 { | |
4389 buf_T *buf; | |
4390 | |
4391 buf = curbuf; | |
4392 qf_jump(qi, 0, 0, forceit); | |
4393 if (buf != curbuf) | |
4394 /* If we jumped to another buffer redrawing will already be | |
4395 * taken care of. */ | |
4396 *redraw_for_dummy = FALSE; | |
4397 | |
4398 /* Jump to the directory used after loading the buffer. */ | |
4399 if (curbuf == first_match_buf && target_dir != NULL) | |
4400 { | |
4401 exarg_T ea; | |
4402 | |
4403 ea.arg = target_dir; | |
4404 ea.cmdidx = CMD_lcd; | |
4405 ex_cd(&ea); | |
4406 } | |
4407 } | |
4408 | |
4409 /* | |
4170 * ":vimgrep {pattern} file(s)" | 4410 * ":vimgrep {pattern} file(s)" |
4171 * ":vimgrepadd {pattern} file(s)" | 4411 * ":vimgrepadd {pattern} file(s)" |
4172 * ":lvimgrep {pattern} file(s)" | 4412 * ":lvimgrep {pattern} file(s)" |
4173 * ":lvimgrepadd {pattern} file(s)" | 4413 * ":lvimgrepadd {pattern} file(s)" |
4174 */ | 4414 */ |
4186 qf_info_T *qi = &ql_info; | 4426 qf_info_T *qi = &ql_info; |
4187 int loclist_cmd = FALSE; | 4427 int loclist_cmd = FALSE; |
4188 int_u save_qfid; | 4428 int_u save_qfid; |
4189 qfline_T *cur_qf_start; | 4429 qfline_T *cur_qf_start; |
4190 win_T *wp; | 4430 win_T *wp; |
4191 long lnum; | |
4192 buf_T *buf; | 4431 buf_T *buf; |
4193 int duplicate_name = FALSE; | 4432 int duplicate_name = FALSE; |
4194 int using_dummy; | 4433 int using_dummy; |
4195 int redraw_for_dummy = FALSE; | 4434 int redraw_for_dummy = FALSE; |
4196 int found_match; | 4435 int found_match; |
4197 buf_T *first_match_buf = NULL; | 4436 buf_T *first_match_buf = NULL; |
4198 time_t seconds = 0; | 4437 time_t seconds = 0; |
4199 int save_mls; | |
4200 #if defined(FEAT_SYN_HL) | |
4201 char_u *save_ei = NULL; | |
4202 #endif | |
4203 aco_save_T aco; | 4438 aco_save_T aco; |
4204 int flags = 0; | 4439 int flags = 0; |
4205 colnr_T col; | |
4206 long tomatch; | 4440 long tomatch; |
4207 char_u *dirname_start = NULL; | 4441 char_u *dirname_start = NULL; |
4208 char_u *dirname_now = NULL; | 4442 char_u *dirname_now = NULL; |
4209 char_u *target_dir = NULL; | 4443 char_u *target_dir = NULL; |
4210 char_u *au_name = NULL; | 4444 char_u *au_name = NULL; |
4211 | 4445 |
4212 switch (eap->cmdidx) | 4446 au_name = vgr_get_auname(eap->cmdidx); |
4213 { | |
4214 case CMD_vimgrep: au_name = (char_u *)"vimgrep"; break; | |
4215 case CMD_lvimgrep: au_name = (char_u *)"lvimgrep"; break; | |
4216 case CMD_vimgrepadd: au_name = (char_u *)"vimgrepadd"; break; | |
4217 case CMD_lvimgrepadd: au_name = (char_u *)"lvimgrepadd"; break; | |
4218 case CMD_grep: au_name = (char_u *)"grep"; break; | |
4219 case CMD_lgrep: au_name = (char_u *)"lgrep"; break; | |
4220 case CMD_grepadd: au_name = (char_u *)"grepadd"; break; | |
4221 case CMD_lgrepadd: au_name = (char_u *)"lgrepadd"; break; | |
4222 default: break; | |
4223 } | |
4224 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, | 4447 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, |
4225 curbuf->b_fname, TRUE, curbuf)) | 4448 curbuf->b_fname, TRUE, curbuf)) |
4226 { | 4449 { |
4227 #ifdef FEAT_EVAL | 4450 #ifdef FEAT_EVAL |
4228 if (aborting()) | 4451 if (aborting()) |
4254 { | 4477 { |
4255 EMSG(_(e_invalpat)); | 4478 EMSG(_(e_invalpat)); |
4256 goto theend; | 4479 goto theend; |
4257 } | 4480 } |
4258 | 4481 |
4259 if (s == NULL || *s == NUL) | 4482 vgr_init_regmatch(®match, s); |
4260 { | |
4261 /* Pattern is empty, use last search pattern. */ | |
4262 if (last_search_pat() == NULL) | |
4263 { | |
4264 EMSG(_(e_noprevre)); | |
4265 goto theend; | |
4266 } | |
4267 regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC); | |
4268 } | |
4269 else | |
4270 regmatch.regprog = vim_regcomp(s, RE_MAGIC); | |
4271 | |
4272 if (regmatch.regprog == NULL) | 4483 if (regmatch.regprog == NULL) |
4273 goto theend; | 4484 goto theend; |
4274 regmatch.rmm_ic = p_ic; | |
4275 regmatch.rmm_maxcol = 0; | |
4276 | 4485 |
4277 p = skipwhite(p); | 4486 p = skipwhite(p); |
4278 if (*p == NUL) | 4487 if (*p == NUL) |
4279 { | 4488 { |
4280 EMSG(_("E683: File name missing or invalid pattern")); | 4489 EMSG(_("E683: File name missing or invalid pattern")); |
4281 goto theend; | 4490 goto theend; |
4282 } | 4491 } |
4283 | 4492 |
4284 if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd | 4493 if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd |
4285 && eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd) | 4494 && eap->cmdidx != CMD_vimgrepadd |
4495 && eap->cmdidx != CMD_lvimgrepadd) | |
4286 || qi->qf_curlist == qi->qf_listcount) | 4496 || qi->qf_curlist == qi->qf_listcount) |
4287 /* make place for a new list */ | 4497 /* make place for a new list */ |
4288 qf_new_list(qi, title != NULL ? title : *eap->cmdlinep); | 4498 qf_new_list(qi, title != NULL ? title : *eap->cmdlinep); |
4289 | 4499 |
4290 /* parse the list of arguments */ | 4500 /* parse the list of arguments */ |
4320 if (time(NULL) > seconds) | 4530 if (time(NULL) > seconds) |
4321 { | 4531 { |
4322 /* Display the file name every second or so, show the user we are | 4532 /* Display the file name every second or so, show the user we are |
4323 * working on it. */ | 4533 * working on it. */ |
4324 seconds = time(NULL); | 4534 seconds = time(NULL); |
4325 msg_start(); | 4535 vgr_display_fname(fname); |
4326 p = msg_strtrunc(fname, TRUE); | |
4327 if (p == NULL) | |
4328 msg_outtrans(fname); | |
4329 else | |
4330 { | |
4331 msg_outtrans(p); | |
4332 vim_free(p); | |
4333 } | |
4334 msg_clr_eos(); | |
4335 msg_didout = FALSE; /* overwrite this message */ | |
4336 msg_nowait = TRUE; /* don't wait for this message */ | |
4337 msg_col = 0; | |
4338 out_flush(); | |
4339 } | 4536 } |
4340 | 4537 |
4341 buf = buflist_findname_exp(fnames[fi]); | 4538 buf = buflist_findname_exp(fnames[fi]); |
4342 if (buf == NULL || buf->b_ml.ml_mfp == NULL) | 4539 if (buf == NULL || buf->b_ml.ml_mfp == NULL) |
4343 { | 4540 { |
4344 /* Remember that a buffer with this name already exists. */ | 4541 /* Remember that a buffer with this name already exists. */ |
4345 duplicate_name = (buf != NULL); | 4542 duplicate_name = (buf != NULL); |
4346 using_dummy = TRUE; | 4543 using_dummy = TRUE; |
4347 redraw_for_dummy = TRUE; | 4544 redraw_for_dummy = TRUE; |
4348 | 4545 |
4349 #if defined(FEAT_SYN_HL) | 4546 buf = vgr_load_dummy_buf(fname, dirname_start, dirname_now); |
4350 /* Don't do Filetype autocommands to avoid loading syntax and | |
4351 * indent scripts, a great speed improvement. */ | |
4352 save_ei = au_event_disable(",Filetype"); | |
4353 #endif | |
4354 /* Don't use modelines here, it's useless. */ | |
4355 save_mls = p_mls; | |
4356 p_mls = 0; | |
4357 | |
4358 /* Load file into a buffer, so that 'fileencoding' is detected, | |
4359 * autocommands applied, etc. */ | |
4360 buf = load_dummy_buffer(fname, dirname_start, dirname_now); | |
4361 | |
4362 p_mls = save_mls; | |
4363 #if defined(FEAT_SYN_HL) | |
4364 au_event_restore(save_ei); | |
4365 #endif | |
4366 } | 4547 } |
4367 else | 4548 else |
4368 /* Use existing, loaded buffer. */ | 4549 /* Use existing, loaded buffer. */ |
4369 using_dummy = FALSE; | 4550 using_dummy = FALSE; |
4370 | 4551 |
4371 if (loclist_cmd) | 4552 /* Check whether the quickfix list is still valid */ |
4372 { | 4553 if (!vgr_qflist_valid(qi, save_qfid, cur_qf_start, loclist_cmd, |
4373 /* | 4554 *eap->cmdlinep)) |
4374 * Verify that the location list is still valid. An autocmd might | 4555 goto theend; |
4375 * have freed the location list. | 4556 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start; |
4376 */ | |
4377 if (!qflist_valid(curwin, save_qfid)) | |
4378 { | |
4379 EMSG(_(e_loc_list_changed)); | |
4380 goto theend; | |
4381 } | |
4382 } | |
4383 if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start) | |
4384 { | |
4385 int idx; | |
4386 | |
4387 /* Autocommands changed the quickfix list. Find the one we were | |
4388 * using and restore it. */ | |
4389 for (idx = 0; idx < LISTCOUNT; ++idx) | |
4390 if (cur_qf_start == qi->qf_lists[idx].qf_start) | |
4391 { | |
4392 qi->qf_curlist = idx; | |
4393 break; | |
4394 } | |
4395 if (idx == LISTCOUNT) | |
4396 { | |
4397 /* List cannot be found, create a new one. */ | |
4398 qf_new_list(qi, *eap->cmdlinep); | |
4399 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start; | |
4400 } | |
4401 } | |
4402 | 4557 |
4403 if (buf == NULL) | 4558 if (buf == NULL) |
4404 { | 4559 { |
4405 if (!got_int) | 4560 if (!got_int) |
4406 smsg((char_u *)_("Cannot open file \"%s\""), fname); | 4561 smsg((char_u *)_("Cannot open file \"%s\""), fname); |
4407 } | 4562 } |
4408 else | 4563 else |
4409 { | 4564 { |
4410 /* Try for a match in all lines of the buffer. | 4565 /* Try for a match in all lines of the buffer. |
4411 * For ":1vimgrep" look for first match only. */ | 4566 * For ":1vimgrep" look for first match only. */ |
4412 found_match = FALSE; | 4567 found_match = vgr_match_buflines(qi, fname, buf, ®match, |
4413 for (lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0; | 4568 tomatch, duplicate_name, flags); |
4414 ++lnum) | 4569 |
4415 { | |
4416 col = 0; | |
4417 while (vim_regexec_multi(®match, curwin, buf, lnum, | |
4418 col, NULL, NULL) > 0) | |
4419 { | |
4420 /* Pass the buffer number so that it gets used even for a | |
4421 * dummy buffer, unless duplicate_name is set, then the | |
4422 * buffer will be wiped out below. */ | |
4423 if (qf_add_entry(qi, | |
4424 qi->qf_curlist, | |
4425 NULL, /* dir */ | |
4426 fname, | |
4427 duplicate_name ? 0 : buf->b_fnum, | |
4428 ml_get_buf(buf, | |
4429 regmatch.startpos[0].lnum + lnum, FALSE), | |
4430 regmatch.startpos[0].lnum + lnum, | |
4431 regmatch.startpos[0].col + 1, | |
4432 FALSE, /* vis_col */ | |
4433 NULL, /* search pattern */ | |
4434 0, /* nr */ | |
4435 0, /* type */ | |
4436 TRUE /* valid */ | |
4437 ) == FAIL) | |
4438 { | |
4439 got_int = TRUE; | |
4440 break; | |
4441 } | |
4442 found_match = TRUE; | |
4443 if (--tomatch == 0) | |
4444 break; | |
4445 if ((flags & VGR_GLOBAL) == 0 | |
4446 || regmatch.endpos[0].lnum > 0) | |
4447 break; | |
4448 col = regmatch.endpos[0].col | |
4449 + (col == regmatch.endpos[0].col); | |
4450 if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE))) | |
4451 break; | |
4452 } | |
4453 line_breakcheck(); | |
4454 if (got_int) | |
4455 break; | |
4456 } | |
4457 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start; | 4570 cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start; |
4458 | 4571 |
4459 if (using_dummy) | 4572 if (using_dummy) |
4460 { | 4573 { |
4461 if (found_match && first_match_buf == NULL) | 4574 if (found_match && first_match_buf == NULL) |
4542 | 4655 |
4543 /* Jump to first match. */ | 4656 /* Jump to first match. */ |
4544 if (qi->qf_lists[qi->qf_curlist].qf_count > 0) | 4657 if (qi->qf_lists[qi->qf_curlist].qf_count > 0) |
4545 { | 4658 { |
4546 if ((flags & VGR_NOJUMP) == 0) | 4659 if ((flags & VGR_NOJUMP) == 0) |
4547 { | 4660 vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, |
4548 buf = curbuf; | 4661 first_match_buf, target_dir); |
4549 qf_jump(qi, 0, 0, eap->forceit); | |
4550 if (buf != curbuf) | |
4551 /* If we jumped to another buffer redrawing will already be | |
4552 * taken care of. */ | |
4553 redraw_for_dummy = FALSE; | |
4554 | |
4555 /* Jump to the directory used after loading the buffer. */ | |
4556 if (curbuf == first_match_buf && target_dir != NULL) | |
4557 { | |
4558 exarg_T ea; | |
4559 | |
4560 ea.arg = target_dir; | |
4561 ea.cmdidx = CMD_lcd; | |
4562 ex_cd(&ea); | |
4563 } | |
4564 } | |
4565 } | 4662 } |
4566 else | 4663 else |
4567 EMSG2(_(e_nomatch2), s); | 4664 EMSG2(_(e_nomatch2), s); |
4568 | 4665 |
4569 /* If we loaded a dummy buffer into the current window, the autocommands | 4666 /* If we loaded a dummy buffer into the current window, the autocommands |