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