To: vim_dev@googlegroups.com Subject: Patch 7.3.509 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.3.509 Problem: ":vimgrep" fails when 'autochdir' is set. Solution: A more generic solution for changing directory. (Ben Fritz) Files: src/quickfix.c *** ../vim-7.3.508/src/quickfix.c 2012-03-07 20:13:44.000000000 +0100 --- src/quickfix.c 2012-04-25 18:52:24.000000000 +0200 *************** *** 130,138 **** static void qf_fill_buffer __ARGS((qf_info_T *qi)); #endif static char_u *get_mef_name __ARGS((void)); ! static buf_T *load_dummy_buffer __ARGS((char_u *fname)); ! static void wipe_dummy_buffer __ARGS((buf_T *buf)); ! static void unload_dummy_buffer __ARGS((buf_T *buf)); static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *)); /* Quickfix window check helper macro */ --- 130,139 ---- static void qf_fill_buffer __ARGS((qf_info_T *qi)); #endif static char_u *get_mef_name __ARGS((void)); ! static void restore_start_dir __ARGS((char_u *dirname_start)); ! static buf_T *load_dummy_buffer __ARGS((char_u *fname, char_u *dirname_start, char_u *resulting_dir)); ! static void wipe_dummy_buffer __ARGS((buf_T *buf, char_u *dirname_start)); ! static void unload_dummy_buffer __ARGS((buf_T *buf, char_u *dirname_start)); static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *)); /* Quickfix window check helper macro */ *************** *** 3237,3255 **** /* Load file into a buffer, so that 'fileencoding' is detected, * autocommands applied, etc. */ ! buf = load_dummy_buffer(fname); ! ! /* When autocommands changed directory: go back. We assume it was ! * ":lcd %:p:h". */ ! mch_dirname(dirname_now, MAXPATHL); ! if (STRCMP(dirname_start, dirname_now) != 0) ! { ! exarg_T ea; ! ! ea.arg = dirname_start; ! ea.cmdidx = CMD_lcd; ! ex_cd(&ea); ! } p_mls = save_mls; #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL) --- 3238,3244 ---- /* Load file into a buffer, so that 'fileencoding' is detected, * autocommands applied, etc. */ ! buf = load_dummy_buffer(fname, dirname_start, dirname_now); p_mls = save_mls; #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL) *************** *** 3320,3326 **** { /* Never keep a dummy buffer if there is another buffer * with the same name. */ ! wipe_dummy_buffer(buf); buf = NULL; } else if (!cmdmod.hide --- 3309,3315 ---- { /* Never keep a dummy buffer if there is another buffer * with the same name. */ ! wipe_dummy_buffer(buf, dirname_start); buf = NULL; } else if (!cmdmod.hide *************** *** 3336,3347 **** * many swap files. */ if (!found_match) { ! wipe_dummy_buffer(buf); buf = NULL; } else if (buf != first_match_buf || (flags & VGR_NOJUMP)) { ! unload_dummy_buffer(buf); buf = NULL; } } --- 3325,3336 ---- * many swap files. */ if (!found_match) { ! wipe_dummy_buffer(buf, dirname_start); buf = NULL; } else if (buf != first_match_buf || (flags & VGR_NOJUMP)) { ! unload_dummy_buffer(buf, dirname_start); buf = NULL; } } *************** *** 3487,3499 **** } /* ! * Load file "fname" into a dummy buffer and return the buffer pointer. * Returns NULL if it fails. - * Must call unload_dummy_buffer() or wipe_dummy_buffer() later! */ static buf_T * ! load_dummy_buffer(fname) char_u *fname; { buf_T *newbuf; buf_T *newbuf_to_wipe = NULL; --- 3476,3523 ---- } /* ! * Restore current working directory to "dirname_start" if they differ, taking ! * into account whether it is set locally or globally. ! */ ! static void ! restore_start_dir(dirname_start) ! char_u *dirname_start; ! { ! char_u *dirname_now = alloc(MAXPATHL); ! ! if (NULL != dirname_now) ! { ! mch_dirname(dirname_now, MAXPATHL); ! if (STRCMP(dirname_start, dirname_now) != 0) ! { ! /* If the directory has changed, change it back by building up an ! * appropriate ex command and executing it. */ ! exarg_T ea; ! ! ea.arg = dirname_start; ! ea.cmdidx = (curwin->w_localdir == NULL) ? CMD_cd : CMD_lcd; ! ex_cd(&ea); ! } ! } ! } ! ! /* ! * Load file "fname" into a dummy buffer and return the buffer pointer, ! * placing the directory resulting from the buffer load into the ! * "resulting_dir" pointer. "resulting_dir" must be allocated by the caller ! * prior to calling this function. Restores directory to "dirname_start" prior ! * to returning, if autocmds or the 'autochdir' option have changed it. ! * ! * If creating the dummy buffer does not fail, must call unload_dummy_buffer() ! * or wipe_dummy_buffer() later! ! * * Returns NULL if it fails. */ static buf_T * ! load_dummy_buffer(fname, dirname_start, resulting_dir) char_u *fname; + char_u *dirname_start; /* in: old directory */ + char_u *resulting_dir; /* out: new directory */ { buf_T *newbuf; buf_T *newbuf_to_wipe = NULL; *************** *** 3548,3569 **** wipe_buffer(newbuf_to_wipe, FALSE); } if (!buf_valid(newbuf)) return NULL; if (failed) { ! wipe_dummy_buffer(newbuf); return NULL; } return newbuf; } /* ! * Wipe out the dummy buffer that load_dummy_buffer() created. */ static void ! wipe_dummy_buffer(buf) buf_T *buf; { if (curbuf != buf) /* safety check */ { --- 3572,3604 ---- wipe_buffer(newbuf_to_wipe, FALSE); } + /* + * When autocommands/'autochdir' option changed directory: go back. + * Let the caller know what the resulting dir was first, in case it is + * important. + */ + mch_dirname(resulting_dir, MAXPATHL); + restore_start_dir(dirname_start); + if (!buf_valid(newbuf)) return NULL; if (failed) { ! wipe_dummy_buffer(newbuf, dirname_start); return NULL; } return newbuf; } /* ! * Wipe out the dummy buffer that load_dummy_buffer() created. Restores ! * directory to "dirname_start" prior to returning, if autocmds or the ! * 'autochdir' option have changed it. */ static void ! wipe_dummy_buffer(buf, dirname_start) buf_T *buf; + char_u *dirname_start; { if (curbuf != buf) /* safety check */ { *************** *** 3583,3600 **** * new aborting error, interrupt, or uncaught exception. */ leave_cleanup(&cs); #endif } } /* ! * Unload the dummy buffer that load_dummy_buffer() created. */ static void ! unload_dummy_buffer(buf) buf_T *buf; { if (curbuf != buf) /* safety check */ close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE); } #if defined(FEAT_EVAL) || defined(PROTO) --- 3618,3645 ---- * new aborting error, interrupt, or uncaught exception. */ leave_cleanup(&cs); #endif + /* When autocommands/'autochdir' option changed directory: go back. */ + restore_start_dir(dirname_start); } } /* ! * Unload the dummy buffer that load_dummy_buffer() created. Restores ! * directory to "dirname_start" prior to returning, if autocmds or the ! * 'autochdir' option have changed it. */ static void ! unload_dummy_buffer(buf, dirname_start) buf_T *buf; + char_u *dirname_start; { if (curbuf != buf) /* safety check */ + { close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE); + + /* When autocommands/'autochdir' option changed directory: go back. */ + restore_start_dir(dirname_start); + } } #if defined(FEAT_EVAL) || defined(PROTO) *** ../vim-7.3.508/src/version.c 2012-04-25 18:24:24.000000000 +0200 --- src/version.c 2012-04-25 18:43:10.000000000 +0200 *************** *** 716,717 **** --- 716,719 ---- { /* Add new patch number below this line */ + /**/ + 509, /**/ -- Arthur pulls Pin out. The MONK blesses the grenade as ... ARTHUR: (quietly) One, two, five ... GALAHAD: Three, sir! ARTHUR: Three. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///