@@ -130,9 +130,10 @@ static void qf_set_title __ARGS((qf_info_T *qi));
130130static void qf_fill_buffer __ARGS ((qf_info_T * qi ));
131131#endif
132132static char_u * get_mef_name __ARGS ((void ));
133- static buf_T * load_dummy_buffer __ARGS ((char_u * fname ));
134- static void wipe_dummy_buffer __ARGS ((buf_T * buf ));
135- static void unload_dummy_buffer __ARGS ((buf_T * buf ));
133+ static void restore_start_dir __ARGS ((char_u * dirname_start ));
134+ static buf_T * load_dummy_buffer __ARGS ((char_u * fname , char_u * dirname_start , char_u * resulting_dir ));
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 ));
136137static qf_info_T * ll_get_or_alloc_list __ARGS ((win_T * ) );
137138
138139/* Quickfix window check helper macro */
@@ -3237,19 +3238,7 @@ ex_vimgrep(eap)
32373238
32383239 /* Load file into a buffer, so that 'fileencoding' is detected,
32393240 * autocommands applied, etc. */
3240- buf = load_dummy_buffer (fname );
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- }
3241+ buf = load_dummy_buffer (fname , dirname_start , dirname_now );
32533242
32543243 p_mls = save_mls ;
32553244#if defined(FEAT_AUTOCMD ) && defined(FEAT_SYN_HL )
@@ -3320,7 +3309,7 @@ ex_vimgrep(eap)
33203309 {
33213310 /* Never keep a dummy buffer if there is another buffer
33223311 * with the same name. */
3323- wipe_dummy_buffer (buf );
3312+ wipe_dummy_buffer (buf , dirname_start );
33243313 buf = NULL ;
33253314 }
33263315 else if (!cmdmod .hide
@@ -3336,12 +3325,12 @@ ex_vimgrep(eap)
33363325 * many swap files. */
33373326 if (!found_match )
33383327 {
3339- wipe_dummy_buffer (buf );
3328+ wipe_dummy_buffer (buf , dirname_start );
33403329 buf = NULL ;
33413330 }
33423331 else if (buf != first_match_buf || (flags & VGR_NOJUMP ))
33433332 {
3344- unload_dummy_buffer (buf );
3333+ unload_dummy_buffer (buf , dirname_start );
33453334 buf = NULL ;
33463335 }
33473336 }
@@ -3487,13 +3476,48 @@ skip_vimgrep_pat(p, s, flags)
34873476}
34883477
34893478/*
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+ *
34913514 * Returns NULL if it fails.
3492- * Must call unload_dummy_buffer() or wipe_dummy_buffer() later!
34933515 */
34943516 static buf_T *
3495- load_dummy_buffer (fname )
3517+ load_dummy_buffer (fname , dirname_start , resulting_dir )
34963518 char_u * fname ;
3519+ char_u * dirname_start ; /* in: old directory */
3520+ char_u * resulting_dir ; /* out: new directory */
34973521{
34983522 buf_T * newbuf ;
34993523 buf_T * newbuf_to_wipe = NULL ;
@@ -3548,22 +3572,33 @@ load_dummy_buffer(fname)
35483572 wipe_buffer (newbuf_to_wipe , FALSE);
35493573 }
35503574
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+
35513583 if (!buf_valid (newbuf ))
35523584 return NULL ;
35533585 if (failed )
35543586 {
3555- wipe_dummy_buffer (newbuf );
3587+ wipe_dummy_buffer (newbuf , dirname_start );
35563588 return NULL ;
35573589 }
35583590 return newbuf ;
35593591}
35603592
35613593/*
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.
35633597 */
35643598 static void
3565- wipe_dummy_buffer (buf )
3599+ wipe_dummy_buffer (buf , dirname_start )
35663600 buf_T * buf ;
3601+ char_u * dirname_start ;
35673602{
35683603 if (curbuf != buf ) /* safety check */
35693604 {
@@ -3583,18 +3618,28 @@ wipe_dummy_buffer(buf)
35833618 * new aborting error, interrupt, or uncaught exception. */
35843619 leave_cleanup (& cs );
35853620#endif
3621+ /* When autocommands/'autochdir' option changed directory: go back. */
3622+ restore_start_dir (dirname_start );
35863623 }
35873624}
35883625
35893626/*
3590- * Unload the dummy buffer that load_dummy_buffer() created.
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.
35913630 */
35923631 static void
3593- unload_dummy_buffer (buf )
3632+ unload_dummy_buffer (buf , dirname_start )
35943633 buf_T * buf ;
3634+ char_u * dirname_start ;
35953635{
35963636 if (curbuf != buf ) /* safety check */
3637+ {
35973638 close_buffer (NULL , buf , DOBUF_UNLOAD , FALSE);
3639+
3640+ /* When autocommands/'autochdir' option changed directory: go back. */
3641+ restore_start_dir (dirname_start );
3642+ }
35983643}
35993644
36003645#if defined(FEAT_EVAL ) || defined(PROTO )
0 commit comments