| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.509 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| 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 |
| |
| |
| |
| |
| |
| *** 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) |
| |
| |
| |
| *** 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 /// |