Mercurial > vim
comparison src/quickfix.c @ 42:c75153d791d0
updated for version 7.0026
author | vimboss |
---|---|
date | Wed, 29 Dec 2004 20:58:21 +0000 |
parents | f529edb9bab3 |
children | a2081e6febb8 |
comparison
equal
deleted
inserted
replaced
41:f529edb9bab3 | 42:c75153d791d0 |
---|---|
103 static buf_T *qf_find_buf __ARGS((void)); | 103 static buf_T *qf_find_buf __ARGS((void)); |
104 static void qf_update_buffer __ARGS((void)); | 104 static void qf_update_buffer __ARGS((void)); |
105 static void qf_fill_buffer __ARGS((void)); | 105 static void qf_fill_buffer __ARGS((void)); |
106 #endif | 106 #endif |
107 static char_u *get_mef_name __ARGS((void)); | 107 static char_u *get_mef_name __ARGS((void)); |
108 static buf_T *load_dummy_buffer __ARGS((char_u *fname)); | |
109 static void wipe_dummy_buffer __ARGS((buf_T *buf)); | |
110 static void unload_dummy_buffer __ARGS((buf_T *buf)); | |
108 | 111 |
109 /* | 112 /* |
110 * Read the errorfile "efile" into memory, line by line, building the error | 113 * Read the errorfile "efile" into memory, line by line, building the error |
111 * list. | 114 * list. |
112 * Return -1 for error, number of errors for success. | 115 * Return -1 for error, number of errors for success. |
2061 | 2064 |
2062 /* | 2065 /* |
2063 * Return TRUE when using ":vimgrep" for ":grep". | 2066 * Return TRUE when using ":vimgrep" for ":grep". |
2064 */ | 2067 */ |
2065 int | 2068 int |
2066 grep_internal(eap) | 2069 grep_internal(cmdidx) |
2067 exarg_T *eap; | 2070 cmdidx_T cmdidx; |
2068 { | 2071 { |
2069 return ((eap->cmdidx == CMD_grep || eap->cmdidx == CMD_grepadd) | 2072 return ((cmdidx == CMD_grep || cmdidx == CMD_grepadd) |
2070 && STRCMP("internal", | 2073 && STRCMP("internal", |
2071 *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0); | 2074 *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0); |
2072 } | 2075 } |
2073 | 2076 |
2074 /* | 2077 /* |
2081 char_u *name; | 2084 char_u *name; |
2082 char_u *cmd; | 2085 char_u *cmd; |
2083 unsigned len; | 2086 unsigned len; |
2084 | 2087 |
2085 /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */ | 2088 /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */ |
2086 if (grep_internal(eap)) | 2089 if (grep_internal(eap->cmdidx)) |
2087 { | 2090 { |
2088 ex_vimgrep(eap); | 2091 ex_vimgrep(eap); |
2089 return; | 2092 return; |
2090 } | 2093 } |
2091 | 2094 |
2247 */ | 2250 */ |
2248 void | 2251 void |
2249 ex_vimgrep(eap) | 2252 ex_vimgrep(eap) |
2250 exarg_T *eap; | 2253 exarg_T *eap; |
2251 { | 2254 { |
2252 regmatch_T regmatch; | 2255 regmmatch_T regmatch; |
2253 char_u *save_cpo; | 2256 char_u *save_cpo; |
2254 int fcount; | 2257 int fcount; |
2255 char_u **fnames; | 2258 char_u **fnames; |
2259 char_u *s; | |
2256 char_u *p; | 2260 char_u *p; |
2257 int i; | 2261 int i; |
2258 FILE *fd; | |
2259 int fi; | 2262 int fi; |
2260 struct qf_line *prevp = NULL; | 2263 struct qf_line *prevp = NULL; |
2261 long lnum; | 2264 long lnum; |
2262 garray_T ga; | 2265 garray_T ga; |
2266 buf_T *buf; | |
2267 int duplicate_name = FALSE; | |
2268 int using_dummy; | |
2269 int found_match; | |
2270 int first_match = TRUE; | |
2263 | 2271 |
2264 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ | 2272 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ |
2265 save_cpo = p_cpo; | 2273 save_cpo = p_cpo; |
2266 p_cpo = empty_option; | 2274 p_cpo = empty_option; |
2267 | 2275 |
2268 /* Get the search pattern */ | 2276 /* Get the search pattern: either white-separated or enclosed in // */ |
2269 regmatch.regprog = NULL; | 2277 regmatch.regprog = NULL; |
2270 p = skip_regexp(eap->arg + 1, *eap->arg, TRUE, NULL); | 2278 if (vim_isIDc(*eap->arg)) |
2271 if (*p != *eap->arg) | 2279 { |
2272 { | 2280 s = eap->arg; |
2273 EMSG(_("E682: Invalid search pattern or delimiter")); | 2281 p = skiptowhite(s); |
2274 goto theend; | 2282 } |
2275 } | 2283 else |
2276 *p++ = NUL; | 2284 { |
2277 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); | 2285 s = eap->arg + 1; |
2286 p = skip_regexp(s, *eap->arg, TRUE, NULL); | |
2287 if (*p != *eap->arg) | |
2288 { | |
2289 EMSG(_("E682: Invalid search pattern or delimiter")); | |
2290 goto theend; | |
2291 } | |
2292 } | |
2293 if (*p != NUL) | |
2294 *p++ = NUL; | |
2295 regmatch.regprog = vim_regcomp(s, RE_MAGIC); | |
2278 if (regmatch.regprog == NULL) | 2296 if (regmatch.regprog == NULL) |
2279 goto theend; | 2297 goto theend; |
2280 regmatch.rm_ic = FALSE; | 2298 regmatch.rmm_ic = FALSE; |
2281 | 2299 |
2282 p = skipwhite(p); | 2300 p = skipwhite(p); |
2283 if (*p == NUL) | 2301 if (*p == NUL) |
2284 { | 2302 { |
2285 EMSG(_("E683: File name missing or invalid pattern")); | 2303 EMSG(_("E683: File name missing or invalid pattern")); |
2310 goto theend; | 2328 goto theend; |
2311 } | 2329 } |
2312 | 2330 |
2313 for (fi = 0; fi < fcount && !got_int; ++fi) | 2331 for (fi = 0; fi < fcount && !got_int; ++fi) |
2314 { | 2332 { |
2315 fd = fopen((char *)fnames[fi], "r"); | 2333 buf = buflist_findname_exp(fnames[fi]); |
2316 if (fd == NULL) | 2334 if (buf == NULL || buf->b_ml.ml_mfp == NULL) |
2335 { | |
2336 /* Remember that a buffer with this name already exists. */ | |
2337 duplicate_name = (buf != NULL); | |
2338 | |
2339 /* Load file into a buffer, so that 'fileencoding' is detected, | |
2340 * autocommands applied, etc. */ | |
2341 buf = load_dummy_buffer(fnames[fi]); | |
2342 using_dummy = TRUE; | |
2343 } | |
2344 else | |
2345 /* Use existing, loaded buffer. */ | |
2346 using_dummy = FALSE; | |
2347 if (buf == NULL) | |
2317 smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]); | 2348 smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]); |
2318 else | 2349 else |
2319 { | 2350 { |
2320 lnum = 1; | 2351 found_match = FALSE; |
2321 while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) | 2352 for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum) |
2322 { | 2353 { |
2323 if (vim_regexec(®match, IObuff, (colnr_T)0)) | 2354 if (vim_regexec_multi(®match, curwin, buf, lnum, |
2355 (colnr_T)0) > 0) | |
2324 { | 2356 { |
2325 int l = STRLEN(IObuff); | |
2326 | |
2327 /* remove trailing CR, LF, spaces, etc. */ | |
2328 while (l > 0 && IObuff[l - 1] <= ' ') | |
2329 IObuff[--l] = NUL; | |
2330 | |
2331 if (qf_add_entry(&prevp, | 2357 if (qf_add_entry(&prevp, |
2332 NULL, /* dir */ | 2358 NULL, /* dir */ |
2333 fnames[fi], | 2359 fnames[fi], |
2334 IObuff, | 2360 ml_get_buf(buf, |
2335 lnum, | 2361 regmatch.startpos[0].lnum + lnum, FALSE), |
2336 (int)(regmatch.startp[0] - IObuff) + 1,/* col */ | 2362 regmatch.startpos[0].lnum + lnum, |
2363 regmatch.startpos[0].col + 1, | |
2337 FALSE, /* virt_col */ | 2364 FALSE, /* virt_col */ |
2338 0, /* nr */ | 2365 0, /* nr */ |
2339 0, /* type */ | 2366 0, /* type */ |
2340 TRUE /* valid */ | 2367 TRUE /* valid */ |
2341 ) == FAIL) | 2368 ) == FAIL) |
2342 { | 2369 { |
2343 got_int = TRUE; | 2370 got_int = TRUE; |
2344 break; | 2371 break; |
2345 } | 2372 } |
2373 else | |
2374 found_match = TRUE; | |
2346 } | 2375 } |
2347 ++lnum; | |
2348 line_breakcheck(); | 2376 line_breakcheck(); |
2377 if (got_int) | |
2378 break; | |
2349 } | 2379 } |
2350 fclose(fd); | 2380 |
2381 if (using_dummy) | |
2382 { | |
2383 if (duplicate_name) | |
2384 /* Never keep a dummy buffer if there is another buffer | |
2385 * with the same name. */ | |
2386 wipe_dummy_buffer(buf); | |
2387 else if (!buf_hide(buf)) | |
2388 { | |
2389 /* When not hiding the buffer and no match was found we | |
2390 * don't need to remember the buffer, wipe it out. If | |
2391 * there was a match and it wasn't the first one: only | |
2392 * unload the buffer. */ | |
2393 if (!found_match) | |
2394 wipe_dummy_buffer(buf); | |
2395 else if (!first_match) | |
2396 unload_dummy_buffer(buf); | |
2397 } | |
2398 } | |
2399 if (found_match) | |
2400 first_match = FALSE; | |
2351 } | 2401 } |
2352 } | 2402 } |
2353 | 2403 |
2354 FreeWild(fcount, fnames); | 2404 FreeWild(fcount, fnames); |
2355 | 2405 |
2362 #endif | 2412 #endif |
2363 | 2413 |
2364 /* Jump to first match. */ | 2414 /* Jump to first match. */ |
2365 if (qf_lists[qf_curlist].qf_count > 0) | 2415 if (qf_lists[qf_curlist].qf_count > 0) |
2366 qf_jump(0, 0, FALSE); | 2416 qf_jump(0, 0, FALSE); |
2417 else | |
2418 EMSG2(_(e_nomatch2), s); | |
2367 | 2419 |
2368 theend: | 2420 theend: |
2369 vim_free(regmatch.regprog); | 2421 vim_free(regmatch.regprog); |
2370 | 2422 |
2371 /* Only resture 'cpo' when it wasn't set in the mean time. */ | 2423 /* Only resture 'cpo' when it wasn't set in the mean time. */ |
2372 if (p_cpo == empty_option) | 2424 if (p_cpo == empty_option) |
2373 p_cpo = save_cpo; | 2425 p_cpo = save_cpo; |
2374 else | 2426 else |
2375 free_string_option(save_cpo); | 2427 free_string_option(save_cpo); |
2428 } | |
2429 | |
2430 /* | |
2431 * Load file "fname" into a dummy buffer and return the buffer pointer. | |
2432 * Returns NULL if it fails. | |
2433 * Must call unload_dummy_buffer() or wipe_dummy_buffer() later! | |
2434 */ | |
2435 static buf_T * | |
2436 load_dummy_buffer(fname) | |
2437 char_u *fname; | |
2438 { | |
2439 buf_T *newbuf; | |
2440 int failed = TRUE; | |
2441 #ifdef FEAT_AUTOCMD | |
2442 aco_save_T aco; | |
2443 #else | |
2444 buf_T *old_curbuf = curbuf; | |
2445 #endif | |
2446 | |
2447 /* Allocate a buffer without putting it in the buffer list. */ | |
2448 newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); | |
2449 if (newbuf == NULL) | |
2450 return NULL; | |
2451 | |
2452 #ifdef FEAT_AUTOCMD | |
2453 /* set curwin/curbuf to buf and save a few things */ | |
2454 aucmd_prepbuf(&aco, newbuf); | |
2455 #else | |
2456 curbuf = newbuf; | |
2457 curwin->w_buffer = newbuf; | |
2458 #endif | |
2459 | |
2460 /* Need to set the filename for autocommands. */ | |
2461 (void)setfname(curbuf, fname, NULL, FALSE); | |
2462 | |
2463 if (ml_open() == OK) | |
2464 { | |
2465 /* Create swap file now to avoid the ATTENTION message. */ | |
2466 check_need_swap(TRUE); | |
2467 | |
2468 /* Remove the "dummy" flag, otherwise autocommands may not | |
2469 * work. */ | |
2470 curbuf->b_flags &= ~BF_DUMMY; | |
2471 | |
2472 if (readfile(fname, NULL, | |
2473 (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, | |
2474 NULL, READ_NEW | READ_DUMMY) == OK | |
2475 && !(curbuf->b_flags & BF_NEW)) | |
2476 { | |
2477 failed = FALSE; | |
2478 if (curbuf != newbuf) | |
2479 { | |
2480 /* Bloody autocommands changed the buffer! */ | |
2481 if (buf_valid(newbuf)) | |
2482 wipe_buffer(newbuf, FALSE); | |
2483 newbuf = curbuf; | |
2484 } | |
2485 } | |
2486 } | |
2487 | |
2488 #ifdef FEAT_AUTOCMD | |
2489 /* restore curwin/curbuf and a few other things */ | |
2490 aucmd_restbuf(&aco); | |
2491 #else | |
2492 curbuf = old_curbuf; | |
2493 curwin->w_buffer = old_curbuf; | |
2494 #endif | |
2495 | |
2496 if (!buf_valid(newbuf)) | |
2497 return NULL; | |
2498 if (failed) | |
2499 { | |
2500 wipe_dummy_buffer(newbuf); | |
2501 return NULL; | |
2502 } | |
2503 return newbuf; | |
2504 } | |
2505 | |
2506 /* | |
2507 * Wipe out the dummy buffer that load_dummy_buffer() created. | |
2508 */ | |
2509 static void | |
2510 wipe_dummy_buffer(buf) | |
2511 buf_T *buf; | |
2512 { | |
2513 if (curbuf != buf) /* safety check */ | |
2514 wipe_buffer(buf, FALSE); | |
2515 } | |
2516 | |
2517 /* | |
2518 * Unload the dummy buffer that load_dummy_buffer() created. | |
2519 */ | |
2520 static void | |
2521 unload_dummy_buffer(buf) | |
2522 buf_T *buf; | |
2523 { | |
2524 if (curbuf != buf) /* safety check */ | |
2525 close_buffer(NULL, buf, DOBUF_UNLOAD); | |
2376 } | 2526 } |
2377 | 2527 |
2378 /* | 2528 /* |
2379 * ":[range]cbuffer [bufnr]" command. | 2529 * ":[range]cbuffer [bufnr]" command. |
2380 */ | 2530 */ |
2485 if (qf_add_entry(&prevp, | 2635 if (qf_add_entry(&prevp, |
2486 NULL, /* dir */ | 2636 NULL, /* dir */ |
2487 fnames[fi], | 2637 fnames[fi], |
2488 IObuff, | 2638 IObuff, |
2489 lnum, | 2639 lnum, |
2490 0, /* col */ | 2640 (int)(regmatch.startp[0] - IObuff) |
2641 + 1, /* col */ | |
2491 FALSE, /* virt_col */ | 2642 FALSE, /* virt_col */ |
2492 0, /* nr */ | 2643 0, /* nr */ |
2493 1, /* type */ | 2644 1, /* type */ |
2494 TRUE /* valid */ | 2645 TRUE /* valid */ |
2495 ) == FAIL) | 2646 ) == FAIL) |