comparison src/quickfix.c @ 3490:8101253704f6 v7.3.509

updated for version 7.3.509 Problem: ":vimgrep" fails when 'autochdir' is set. Solution: A more generic solution for changing directory. (Ben Fritz)
author Bram Moolenaar <bram@vim.org>
date Wed, 25 Apr 2012 18:57:21 +0200
parents 38a135730423
children bbf1fbbe4ab4
comparison
equal deleted inserted replaced
3489:f53d1d03019a 3490:8101253704f6
128 static void qf_update_buffer __ARGS((qf_info_T *qi)); 128 static void qf_update_buffer __ARGS((qf_info_T *qi));
129 static void qf_set_title __ARGS((qf_info_T *qi)); 129 static void qf_set_title __ARGS((qf_info_T *qi));
130 static void qf_fill_buffer __ARGS((qf_info_T *qi)); 130 static void qf_fill_buffer __ARGS((qf_info_T *qi));
131 #endif 131 #endif
132 static char_u *get_mef_name __ARGS((void)); 132 static char_u *get_mef_name __ARGS((void));
133 static buf_T *load_dummy_buffer __ARGS((char_u *fname)); 133 static void restore_start_dir __ARGS((char_u *dirname_start));
134 static void wipe_dummy_buffer __ARGS((buf_T *buf)); 134 static buf_T *load_dummy_buffer __ARGS((char_u *fname, char_u *dirname_start, char_u *resulting_dir));
135 static void unload_dummy_buffer __ARGS((buf_T *buf)); 135 static void wipe_dummy_buffer __ARGS((buf_T *buf, char_u *dirname_start));
136 static void unload_dummy_buffer __ARGS((buf_T *buf, char_u *dirname_start));
136 static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *)); 137 static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *));
137 138
138 /* Quickfix window check helper macro */ 139 /* Quickfix window check helper macro */
139 #define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL) 140 #define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
140 /* Location list window check helper macro */ 141 /* Location list window check helper macro */
3235 save_mls = p_mls; 3236 save_mls = p_mls;
3236 p_mls = 0; 3237 p_mls = 0;
3237 3238
3238 /* Load file into a buffer, so that 'fileencoding' is detected, 3239 /* Load file into a buffer, so that 'fileencoding' is detected,
3239 * autocommands applied, etc. */ 3240 * autocommands applied, etc. */
3240 buf = load_dummy_buffer(fname); 3241 buf = load_dummy_buffer(fname, dirname_start, dirname_now);
3241
3242 /* When autocommands changed directory: go back. We assume it was
3243 * ":lcd %:p:h". */
3244 mch_dirname(dirname_now, MAXPATHL);
3245 if (STRCMP(dirname_start, dirname_now) != 0)
3246 {
3247 exarg_T ea;
3248
3249 ea.arg = dirname_start;
3250 ea.cmdidx = CMD_lcd;
3251 ex_cd(&ea);
3252 }
3253 3242
3254 p_mls = save_mls; 3243 p_mls = save_mls;
3255 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL) 3244 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
3256 au_event_restore(save_ei); 3245 au_event_restore(save_ei);
3257 #endif 3246 #endif
3318 first_match_buf = buf; 3307 first_match_buf = buf;
3319 if (duplicate_name) 3308 if (duplicate_name)
3320 { 3309 {
3321 /* Never keep a dummy buffer if there is another buffer 3310 /* Never keep a dummy buffer if there is another buffer
3322 * with the same name. */ 3311 * with the same name. */
3323 wipe_dummy_buffer(buf); 3312 wipe_dummy_buffer(buf, dirname_start);
3324 buf = NULL; 3313 buf = NULL;
3325 } 3314 }
3326 else if (!cmdmod.hide 3315 else if (!cmdmod.hide
3327 || buf->b_p_bh[0] == 'u' /* "unload" */ 3316 || buf->b_p_bh[0] == 'u' /* "unload" */
3328 || buf->b_p_bh[0] == 'w' /* "wipe" */ 3317 || buf->b_p_bh[0] == 'w' /* "wipe" */
3334 * unload the buffer. 3323 * unload the buffer.
3335 * Ignore 'hidden' here, because it may lead to having too 3324 * Ignore 'hidden' here, because it may lead to having too
3336 * many swap files. */ 3325 * many swap files. */
3337 if (!found_match) 3326 if (!found_match)
3338 { 3327 {
3339 wipe_dummy_buffer(buf); 3328 wipe_dummy_buffer(buf, dirname_start);
3340 buf = NULL; 3329 buf = NULL;
3341 } 3330 }
3342 else if (buf != first_match_buf || (flags & VGR_NOJUMP)) 3331 else if (buf != first_match_buf || (flags & VGR_NOJUMP))
3343 { 3332 {
3344 unload_dummy_buffer(buf); 3333 unload_dummy_buffer(buf, dirname_start);
3345 buf = NULL; 3334 buf = NULL;
3346 } 3335 }
3347 } 3336 }
3348 3337
3349 if (buf != NULL) 3338 if (buf != NULL)
3485 } 3474 }
3486 return p; 3475 return p;
3487 } 3476 }
3488 3477
3489 /* 3478 /*
3490 * Load file "fname" into a dummy buffer and return the buffer pointer. 3479 * Restore current working directory to "dirname_start" if they differ, taking
3480 * into account whether it is set locally or globally.
3481 */
3482 static void
3483 restore_start_dir(dirname_start)
3484 char_u *dirname_start;
3485 {
3486 char_u *dirname_now = alloc(MAXPATHL);
3487
3488 if (NULL != dirname_now)
3489 {
3490 mch_dirname(dirname_now, MAXPATHL);
3491 if (STRCMP(dirname_start, dirname_now) != 0)
3492 {
3493 /* If the directory has changed, change it back by building up an
3494 * appropriate ex command and executing it. */
3495 exarg_T ea;
3496
3497 ea.arg = dirname_start;
3498 ea.cmdidx = (curwin->w_localdir == NULL) ? CMD_cd : CMD_lcd;
3499 ex_cd(&ea);
3500 }
3501 }
3502 }
3503
3504 /*
3505 * Load file "fname" into a dummy buffer and return the buffer pointer,
3506 * placing the directory resulting from the buffer load into the
3507 * "resulting_dir" pointer. "resulting_dir" must be allocated by the caller
3508 * prior to calling this function. Restores directory to "dirname_start" prior
3509 * to returning, if autocmds or the 'autochdir' option have changed it.
3510 *
3511 * If creating the dummy buffer does not fail, must call unload_dummy_buffer()
3512 * or wipe_dummy_buffer() later!
3513 *
3491 * Returns NULL if it fails. 3514 * Returns NULL if it fails.
3492 * Must call unload_dummy_buffer() or wipe_dummy_buffer() later!
3493 */ 3515 */
3494 static buf_T * 3516 static buf_T *
3495 load_dummy_buffer(fname) 3517 load_dummy_buffer(fname, dirname_start, resulting_dir)
3496 char_u *fname; 3518 char_u *fname;
3519 char_u *dirname_start; /* in: old directory */
3520 char_u *resulting_dir; /* out: new directory */
3497 { 3521 {
3498 buf_T *newbuf; 3522 buf_T *newbuf;
3499 buf_T *newbuf_to_wipe = NULL; 3523 buf_T *newbuf_to_wipe = NULL;
3500 int failed = TRUE; 3524 int failed = TRUE;
3501 aco_save_T aco; 3525 aco_save_T aco;
3546 aucmd_restbuf(&aco); 3570 aucmd_restbuf(&aco);
3547 if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe)) 3571 if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe))
3548 wipe_buffer(newbuf_to_wipe, FALSE); 3572 wipe_buffer(newbuf_to_wipe, FALSE);
3549 } 3573 }
3550 3574
3575 /*
3576 * When autocommands/'autochdir' option changed directory: go back.
3577 * Let the caller know what the resulting dir was first, in case it is
3578 * important.
3579 */
3580 mch_dirname(resulting_dir, MAXPATHL);
3581 restore_start_dir(dirname_start);
3582
3551 if (!buf_valid(newbuf)) 3583 if (!buf_valid(newbuf))
3552 return NULL; 3584 return NULL;
3553 if (failed) 3585 if (failed)
3554 { 3586 {
3555 wipe_dummy_buffer(newbuf); 3587 wipe_dummy_buffer(newbuf, dirname_start);
3556 return NULL; 3588 return NULL;
3557 } 3589 }
3558 return newbuf; 3590 return newbuf;
3559 } 3591 }
3560 3592
3561 /* 3593 /*
3562 * Wipe out the dummy buffer that load_dummy_buffer() created. 3594 * Wipe out the dummy buffer that load_dummy_buffer() created. Restores
3595 * directory to "dirname_start" prior to returning, if autocmds or the
3596 * 'autochdir' option have changed it.
3563 */ 3597 */
3564 static void 3598 static void
3565 wipe_dummy_buffer(buf) 3599 wipe_dummy_buffer(buf, dirname_start)
3566 buf_T *buf; 3600 buf_T *buf;
3601 char_u *dirname_start;
3567 { 3602 {
3568 if (curbuf != buf) /* safety check */ 3603 if (curbuf != buf) /* safety check */
3569 { 3604 {
3570 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 3605 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
3571 cleanup_T cs; 3606 cleanup_T cs;
3581 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 3616 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
3582 /* Restore the error/interrupt/exception state if not discarded by a 3617 /* Restore the error/interrupt/exception state if not discarded by a
3583 * new aborting error, interrupt, or uncaught exception. */ 3618 * new aborting error, interrupt, or uncaught exception. */
3584 leave_cleanup(&cs); 3619 leave_cleanup(&cs);
3585 #endif 3620 #endif
3586 } 3621 /* When autocommands/'autochdir' option changed directory: go back. */
3587 } 3622 restore_start_dir(dirname_start);
3588 3623 }
3589 /* 3624 }
3590 * Unload the dummy buffer that load_dummy_buffer() created. 3625
3626 /*
3627 * Unload the dummy buffer that load_dummy_buffer() created. Restores
3628 * directory to "dirname_start" prior to returning, if autocmds or the
3629 * 'autochdir' option have changed it.
3591 */ 3630 */
3592 static void 3631 static void
3593 unload_dummy_buffer(buf) 3632 unload_dummy_buffer(buf, dirname_start)
3594 buf_T *buf; 3633 buf_T *buf;
3634 char_u *dirname_start;
3595 { 3635 {
3596 if (curbuf != buf) /* safety check */ 3636 if (curbuf != buf) /* safety check */
3637 {
3597 close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE); 3638 close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE);
3639
3640 /* When autocommands/'autochdir' option changed directory: go back. */
3641 restore_start_dir(dirname_start);
3642 }
3598 } 3643 }
3599 3644
3600 #if defined(FEAT_EVAL) || defined(PROTO) 3645 #if defined(FEAT_EVAL) || defined(PROTO)
3601 /* 3646 /*
3602 * Add each quickfix error to list "list" as a dictionary. 3647 * Add each quickfix error to list "list" as a dictionary.