Skip to content

Commit 5fcd811

Browse files
committed
updated for version 7.3.509
Problem: ":vimgrep" fails when 'autochdir' is set. Solution: A more generic solution for changing directory. (Ben Fritz)
1 parent f4b1c52 commit 5fcd811

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

src/quickfix.c

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,10 @@ static void qf_set_title __ARGS((qf_info_T *qi));
130130
static void qf_fill_buffer __ARGS((qf_info_T *qi));
131131
#endif
132132
static 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));
136137
static 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)

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,8 @@ static char *(features[]) =
714714

715715
static int included_patches[] =
716716
{ /* Add new patch number below this line */
717+
/**/
718+
509,
717719
/**/
718720
508,
719721
/**/

0 commit comments

Comments
 (0)