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 -- [email protected] -- 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    ///

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui