Patch 8.0.1634
Problem:    The ex_vimgrep() function is too long.
Solution:   Split it in smaller functions. (Yegappan Lakshmanan)
Files:      src/quickfix.c


*** ../vim-8.0.1633/src/quickfix.c      2018-03-20 13:30:38.541270285 +0100
--- src/quickfix.c      2018-03-24 13:41:36.922735773 +0100
***************
*** 133,161 ****
  static efm_T  *fmt_start = NULL; /* cached across qf_parse_line() calls */
  
  static int    qf_init_ext(qf_info_T *qi, int qf_idx, char_u *efile, buf_T 
*buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, 
linenr_T lnumlast, char_u *qf_title, char_u *enc);
- static void   qf_store_title(qf_info_T *qi, int qf_idx, char_u *title);
  static void   qf_new_list(qf_info_T *qi, char_u *qf_title);
- static void   ll_free_all(qf_info_T **pqi);
  static int    qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u 
*fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u 
*pattern, int nr, int type, int valid);
- static qf_info_T *ll_new_list(void);
  static void   qf_free(qf_info_T *qi, int idx);
  static char_u *qf_types(int, int);
  static int    qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *);
  static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int 
is_file_stack);
  static char_u *qf_pop_dir(struct dir_stack_T **);
  static char_u *qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *);
- static int    qflist_valid(win_T *wp, int_u qf_id);
  static void   qf_fmt_text(char_u *text, char_u *buf, int bufsize);
- static void   qf_clean_dir_stack(struct dir_stack_T **);
  static int    qf_win_pos_update(qf_info_T *qi, int old_qf_index);
- static int    is_qf_win(win_T *win, qf_info_T *qi);
  static win_T  *qf_find_win(qf_info_T *qi);
  static buf_T  *qf_find_buf(qf_info_T *qi);
  static void   qf_update_buffer(qf_info_T *qi, qfline_T *old_last);
  static void   qf_set_title_var(qf_info_T *qi);
  static void   qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last);
  static char_u *get_mef_name(void);
- static void   restore_start_dir(char_u *dirname_start);
  static buf_T  *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u 
*resulting_dir);
  static void   wipe_dummy_buffer(buf_T *buf, char_u *dirname_start);
  static void   unload_dummy_buffer(buf_T *buf, char_u *dirname_start);
--- 133,154 ----
***************
*** 4167,4172 ****
--- 4160,4412 ----
  }
  
  /*
+  * Return the vimgrep autocmd name.
+  */
+     static char_u *
+ vgr_get_auname(cmdidx_T cmdidx)
+ {
+     switch (cmdidx)
+     {
+       case CMD_vimgrep:     return (char_u *)"vimgrep";
+       case CMD_lvimgrep:    return (char_u *)"lvimgrep";
+       case CMD_vimgrepadd:  return (char_u *)"vimgrepadd";
+       case CMD_lvimgrepadd: return (char_u *)"lvimgrepadd";
+       case CMD_grep:        return (char_u *)"grep";
+       case CMD_lgrep:       return (char_u *)"lgrep";
+       case CMD_grepadd:     return (char_u *)"grepadd";
+       case CMD_lgrepadd:    return (char_u *)"lgrepadd";
+       default: return NULL;
+     }
+ }
+ 
+ /*
+  * Initialize the regmatch used by vimgrep for pattern "s".
+  */
+     static void
+ vgr_init_regmatch(regmmatch_T *regmatch, char_u *s)
+ {
+     /* Get the search pattern: either white-separated or enclosed in // */
+     regmatch->regprog = NULL;
+ 
+     if (s == NULL || *s == NUL)
+     {
+       /* Pattern is empty, use last search pattern. */
+       if (last_search_pat() == NULL)
+       {
+           EMSG(_(e_noprevre));
+           return;
+       }
+       regmatch->regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
+     }
+     else
+       regmatch->regprog = vim_regcomp(s, RE_MAGIC);
+ 
+     regmatch->rmm_ic = p_ic;
+     regmatch->rmm_maxcol = 0;
+ }
+ 
+ /*
+  * Display a file name when vimgrep is running.
+  */
+     static void
+ vgr_display_fname(char_u *fname)
+ {
+     char_u    *p;
+ 
+     msg_start();
+     p = msg_strtrunc(fname, TRUE);
+     if (p == NULL)
+       msg_outtrans(fname);
+     else
+     {
+       msg_outtrans(p);
+       vim_free(p);
+     }
+     msg_clr_eos();
+     msg_didout = FALSE;           /* overwrite this message */
+     msg_nowait = TRUE;            /* don't wait for this message */
+     msg_col = 0;
+     out_flush();
+ }
+ 
+ /*
+  * Load a dummy buffer to search for a pattern using vimgrep.
+  */
+     static buf_T *
+ vgr_load_dummy_buf(
+       char_u *fname,
+       char_u *dirname_start,
+       char_u *dirname_now)
+ {
+     int               save_mls;
+ #if defined(FEAT_SYN_HL)
+     char_u    *save_ei = NULL;
+ #endif
+     buf_T     *buf;
+ 
+ #if defined(FEAT_SYN_HL)
+     /* Don't do Filetype autocommands to avoid loading syntax and
+      * indent scripts, a great speed improvement. */
+     save_ei = au_event_disable(",Filetype");
+ #endif
+     /* Don't use modelines here, it's useless. */
+     save_mls = p_mls;
+     p_mls = 0;
+ 
+     /* 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_SYN_HL)
+     au_event_restore(save_ei);
+ #endif
+ 
+     return buf;
+ }
+ 
+ /*
+  * Check whether a quickfix/location list valid. Autocmds may remove or change
+  * a quickfix list when vimgrep is running. If the list is not found, create a
+  * new list.
+  */
+     static int
+ vgr_qflist_valid(
+       qf_info_T   *qi,
+       int_u       save_qfid,
+       qfline_T    *cur_qf_start,
+       int         loclist_cmd,
+       char_u      *title)
+ {
+     if (loclist_cmd)
+     {
+       /*
+        * Verify that the location list is still valid. An autocmd might
+        * have freed the location list.
+        */
+       if (!qflist_valid(curwin, save_qfid))
+       {
+           EMSG(_(e_loc_list_changed));
+           return FALSE;
+       }
+     }
+     if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start)
+     {
+       int idx;
+ 
+       /* Autocommands changed the quickfix list.  Find the one we were
+        * using and restore it. */
+       for (idx = 0; idx < LISTCOUNT; ++idx)
+           if (cur_qf_start == qi->qf_lists[idx].qf_start)
+           {
+               qi->qf_curlist = idx;
+               break;
+           }
+       if (idx == LISTCOUNT)
+           /* List cannot be found, create a new one. */
+           qf_new_list(qi, title);
+     }
+ 
+     return TRUE;
+ }
+ 
+ /*
+  * Search for a pattern in all the lines in a buffer and add the matching 
lines
+  * to a quickfix list.
+  */
+     static int
+ vgr_match_buflines(
+       qf_info_T   *qi,
+       char_u      *fname,
+       buf_T       *buf,
+       regmmatch_T *regmatch,
+       long        tomatch,
+       int         duplicate_name,
+       int         flags)
+ {
+     int               found_match = FALSE;
+     long      lnum;
+     colnr_T   col;
+ 
+     for (lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0; ++lnum)
+     {
+       col = 0;
+       while (vim_regexec_multi(regmatch, curwin, buf, lnum,
+                   col, NULL, NULL) > 0)
+       {
+           /* Pass the buffer number so that it gets used even for a
+            * dummy buffer, unless duplicate_name is set, then the
+            * buffer will be wiped out below. */
+           if (qf_add_entry(qi,
+                       qi->qf_curlist,
+                       NULL,       /* dir */
+                       fname,
+                       duplicate_name ? 0 : buf->b_fnum,
+                       ml_get_buf(buf,
+                           regmatch->startpos[0].lnum + lnum, FALSE),
+                       regmatch->startpos[0].lnum + lnum,
+                       regmatch->startpos[0].col + 1,
+                       FALSE,      /* vis_col */
+                       NULL,       /* search pattern */
+                       0,          /* nr */
+                       0,          /* type */
+                       TRUE        /* valid */
+                       ) == FAIL)
+           {
+               got_int = TRUE;
+               break;
+           }
+           found_match = TRUE;
+           if (--tomatch == 0)
+               break;
+           if ((flags & VGR_GLOBAL) == 0
+                   || regmatch->endpos[0].lnum > 0)
+               break;
+           col = regmatch->endpos[0].col
+               + (col == regmatch->endpos[0].col);
+           if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE)))
+               break;
+       }
+       line_breakcheck();
+       if (got_int)
+           break;
+     }
+ 
+     return found_match;
+ }
+ 
+ /*
+  * Jump to the first match and update the directory.
+  */
+     static void
+ vgr_jump_to_match(
+       qf_info_T   *qi,
+       int         forceit,
+       int         *redraw_for_dummy,
+       buf_T       *first_match_buf,
+       char_u      *target_dir)
+ {
+     buf_T     *buf;
+ 
+     buf = curbuf;
+     qf_jump(qi, 0, 0, forceit);
+     if (buf != curbuf)
+       /* If we jumped to another buffer redrawing will already be
+        * taken care of. */
+       *redraw_for_dummy = FALSE;
+ 
+     /* Jump to the directory used after loading the buffer. */
+     if (curbuf == first_match_buf && target_dir != NULL)
+     {
+       exarg_T ea;
+ 
+       ea.arg = target_dir;
+       ea.cmdidx = CMD_lcd;
+       ex_cd(&ea);
+     }
+ }
+ 
+ /*
   * ":vimgrep {pattern} file(s)"
   * ":vimgrepadd {pattern} file(s)"
   * ":lvimgrep {pattern} file(s)"
***************
*** 4188,4194 ****
      int_u     save_qfid;
      qfline_T  *cur_qf_start;
      win_T     *wp;
-     long      lnum;
      buf_T     *buf;
      int               duplicate_name = FALSE;
      int               using_dummy;
--- 4428,4433 ----
***************
*** 4196,4226 ****
      int               found_match;
      buf_T     *first_match_buf = NULL;
      time_t    seconds = 0;
-     int               save_mls;
- #if defined(FEAT_SYN_HL)
-     char_u    *save_ei = NULL;
- #endif
      aco_save_T        aco;
      int               flags = 0;
-     colnr_T   col;
      long      tomatch;
      char_u    *dirname_start = NULL;
      char_u    *dirname_now = NULL;
      char_u    *target_dir = NULL;
      char_u    *au_name =  NULL;
  
!     switch (eap->cmdidx)
!     {
!       case CMD_vimgrep:     au_name = (char_u *)"vimgrep"; break;
!       case CMD_lvimgrep:    au_name = (char_u *)"lvimgrep"; break;
!       case CMD_vimgrepadd:  au_name = (char_u *)"vimgrepadd"; break;
!       case CMD_lvimgrepadd: au_name = (char_u *)"lvimgrepadd"; break;
!       case CMD_grep:        au_name = (char_u *)"grep"; break;
!       case CMD_lgrep:       au_name = (char_u *)"lgrep"; break;
!       case CMD_grepadd:     au_name = (char_u *)"grepadd"; break;
!       case CMD_lgrepadd:    au_name = (char_u *)"lgrepadd"; break;
!       default: break;
!     }
      if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
                                               curbuf->b_fname, TRUE, curbuf))
      {
--- 4435,4449 ----
      int               found_match;
      buf_T     *first_match_buf = NULL;
      time_t    seconds = 0;
      aco_save_T        aco;
      int               flags = 0;
      long      tomatch;
      char_u    *dirname_start = NULL;
      char_u    *dirname_now = NULL;
      char_u    *target_dir = NULL;
      char_u    *au_name =  NULL;
  
!     au_name = vgr_get_auname(eap->cmdidx);
      if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
                                               curbuf->b_fname, TRUE, curbuf))
      {
***************
*** 4256,4278 ****
        goto theend;
      }
  
!     if (s == NULL || *s == NUL)
!     {
!       /* Pattern is empty, use last search pattern. */
!       if (last_search_pat() == NULL)
!       {
!           EMSG(_(e_noprevre));
!           goto theend;
!       }
!       regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
!     }
!     else
!       regmatch.regprog = vim_regcomp(s, RE_MAGIC);
! 
      if (regmatch.regprog == NULL)
        goto theend;
-     regmatch.rmm_ic = p_ic;
-     regmatch.rmm_maxcol = 0;
  
      p = skipwhite(p);
      if (*p == NUL)
--- 4479,4487 ----
        goto theend;
      }
  
!     vgr_init_regmatch(&regmatch, s);
      if (regmatch.regprog == NULL)
        goto theend;
  
      p = skipwhite(p);
      if (*p == NUL)
***************
*** 4282,4288 ****
      }
  
      if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd
!               && eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != 
CMD_lvimgrepadd)
                                        || qi->qf_curlist == qi->qf_listcount)
        /* make place for a new list */
        qf_new_list(qi, title != NULL ? title : *eap->cmdlinep);
--- 4491,4498 ----
      }
  
      if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd
!               && eap->cmdidx != CMD_vimgrepadd
!               && eap->cmdidx != CMD_lvimgrepadd)
                                        || qi->qf_curlist == qi->qf_listcount)
        /* make place for a new list */
        qf_new_list(qi, title != NULL ? title : *eap->cmdlinep);
***************
*** 4322,4341 ****
            /* Display the file name every second or so, show the user we are
             * working on it. */
            seconds = time(NULL);
!           msg_start();
!           p = msg_strtrunc(fname, TRUE);
!           if (p == NULL)
!               msg_outtrans(fname);
!           else
!           {
!               msg_outtrans(p);
!               vim_free(p);
!           }
!           msg_clr_eos();
!           msg_didout = FALSE;     /* overwrite this message */
!           msg_nowait = TRUE;      /* don't wait for this message */
!           msg_col = 0;
!           out_flush();
        }
  
        buf = buflist_findname_exp(fnames[fi]);
--- 4532,4538 ----
            /* Display the file name every second or so, show the user we are
             * working on it. */
            seconds = time(NULL);
!           vgr_display_fname(fname);
        }
  
        buf = buflist_findname_exp(fnames[fi]);
***************
*** 4346,4404 ****
            using_dummy = TRUE;
            redraw_for_dummy = TRUE;
  
! #if defined(FEAT_SYN_HL)
!           /* Don't do Filetype autocommands to avoid loading syntax and
!            * indent scripts, a great speed improvement. */
!           save_ei = au_event_disable(",Filetype");
! #endif
!           /* Don't use modelines here, it's useless. */
!           save_mls = p_mls;
!           p_mls = 0;
! 
!           /* 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_SYN_HL)
!           au_event_restore(save_ei);
! #endif
        }
        else
            /* Use existing, loaded buffer. */
            using_dummy = FALSE;
  
!       if (loclist_cmd)
!       {
!           /*
!            * Verify that the location list is still valid. An autocmd might
!            * have freed the location list.
!            */
!           if (!qflist_valid(curwin, save_qfid))
!           {
!               EMSG(_(e_loc_list_changed));
!               goto theend;
!           }
!       }
!       if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start)
!       {
!           int idx;
! 
!           /* Autocommands changed the quickfix list.  Find the one we were
!            * using and restore it. */
!           for (idx = 0; idx < LISTCOUNT; ++idx)
!               if (cur_qf_start == qi->qf_lists[idx].qf_start)
!               {
!                   qi->qf_curlist = idx;
!                   break;
!               }
!           if (idx == LISTCOUNT)
!           {
!               /* List cannot be found, create a new one. */
!               qf_new_list(qi, *eap->cmdlinep);
!               cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
!           }
!       }
  
        if (buf == NULL)
        {
--- 4543,4559 ----
            using_dummy = TRUE;
            redraw_for_dummy = TRUE;
  
!           buf = vgr_load_dummy_buf(fname, dirname_start, dirname_now);
        }
        else
            /* Use existing, loaded buffer. */
            using_dummy = FALSE;
  
!       /* Check whether the quickfix list is still valid */
!       if (!vgr_qflist_valid(qi, save_qfid, cur_qf_start, loclist_cmd,
!                   *eap->cmdlinep))
!           goto theend;
!       cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
  
        if (buf == NULL)
        {
***************
*** 4409,4459 ****
        {
            /* Try for a match in all lines of the buffer.
             * For ":1vimgrep" look for first match only. */
!           found_match = FALSE;
!           for (lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0;
!                                                                      ++lnum)
!           {
!               col = 0;
!               while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
!                                                         col, NULL, NULL) > 0)
!               {
!                   /* Pass the buffer number so that it gets used even for a
!                    * dummy buffer, unless duplicate_name is set, then the
!                    * buffer will be wiped out below. */
!                   if (qf_add_entry(qi,
!                               qi->qf_curlist,
!                               NULL,       /* dir */
!                               fname,
!                               duplicate_name ? 0 : buf->b_fnum,
!                               ml_get_buf(buf,
!                                    regmatch.startpos[0].lnum + lnum, FALSE),
!                               regmatch.startpos[0].lnum + lnum,
!                               regmatch.startpos[0].col + 1,
!                               FALSE,      /* vis_col */
!                               NULL,       /* search pattern */
!                               0,          /* nr */
!                               0,          /* type */
!                               TRUE        /* valid */
!                               ) == FAIL)
!                   {
!                       got_int = TRUE;
!                       break;
!                   }
!                   found_match = TRUE;
!                   if (--tomatch == 0)
!                       break;
!                   if ((flags & VGR_GLOBAL) == 0
!                                              || regmatch.endpos[0].lnum > 0)
!                       break;
!                   col = regmatch.endpos[0].col
!                                           + (col == regmatch.endpos[0].col);
!                   if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE)))
!                       break;
!               }
!               line_breakcheck();
!               if (got_int)
!                   break;
!           }
            cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
  
            if (using_dummy)
--- 4564,4572 ----
        {
            /* Try for a match in all lines of the buffer.
             * For ":1vimgrep" look for first match only. */
!           found_match = vgr_match_buflines(qi, fname, buf, &regmatch,
!                   tomatch, duplicate_name, flags);
! 
            cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
  
            if (using_dummy)
***************
*** 4544,4567 ****
      if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
      {
        if ((flags & VGR_NOJUMP) == 0)
!       {
!           buf = curbuf;
!           qf_jump(qi, 0, 0, eap->forceit);
!           if (buf != curbuf)
!               /* If we jumped to another buffer redrawing will already be
!                * taken care of. */
!               redraw_for_dummy = FALSE;
! 
!           /* Jump to the directory used after loading the buffer. */
!           if (curbuf == first_match_buf && target_dir != NULL)
!           {
!               exarg_T ea;
! 
!               ea.arg = target_dir;
!               ea.cmdidx = CMD_lcd;
!               ex_cd(&ea);
!           }
!       }
      }
      else
        EMSG2(_(e_nomatch2), s);
--- 4657,4664 ----
      if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
      {
        if ((flags & VGR_NOJUMP) == 0)
!           vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy,
!                   first_match_buf, target_dir);
      }
      else
        EMSG2(_(e_nomatch2), s);
*** ../vim-8.0.1633/src/version.c       2018-03-23 22:39:27.325233934 +0100
--- src/version.c       2018-03-24 13:35:52.728627086 +0100
***************
*** 768,769 ****
--- 768,771 ----
  {   /* Add new patch number below this line */
+ /**/
+     1634,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
47. You are so familiar with the WWW that you find the search engines useless.

 /// 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

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui