]> granicus.if.org Git - vim/commitdiff
patch 7.4.2017 v7.4.2017
authorBram Moolenaar <Bram@vim.org>
Sun, 10 Jul 2016 15:00:38 +0000 (17:00 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 10 Jul 2016 15:00:38 +0000 (17:00 +0200)
Problem:    When there are many errors adding them to the quickfix list takes
            a long time.
Solution:   Add BLN_NOOPT.  Don't call buf_valid() in buf_copy_options().
            Remember the last file name used.  When going through the buffer
            list start from the end of the list.  Only call buf_valid() when
            autocommands were executed.

src/buffer.c
src/option.c
src/quickfix.c
src/version.c
src/vim.h

index b434d58e90b25dffc98cb6044f74e2280b9b9093..586ab3848ca04f30258c6c78c5b70ccddcc1332b 100644 (file)
@@ -316,7 +316,9 @@ buf_valid(buf_T *buf)
 {
     buf_T      *bp;
 
-    for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+    /* Assume that we more often have a recent buffer, start with the last
+     * one. */
+    for (bp = lastbuf; bp != NULL; bp = bp->b_prev)
        if (bp == buf)
            return TRUE;
     return FALSE;
@@ -397,9 +399,9 @@ close_buffer(
     if (buf->b_nwindows == 1)
     {
        buf->b_closing = TRUE;
-       apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
-                                                                 FALSE, buf);
-       if (!buf_valid(buf))
+       if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
+                                                                 FALSE, buf)
+               && !buf_valid(buf))
        {
            /* Autocommands deleted the buffer. */
 aucmd_abort:
@@ -416,9 +418,9 @@ aucmd_abort:
        if (!unload_buf)
        {
            buf->b_closing = TRUE;
-           apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
-                                                                 FALSE, buf);
-           if (!buf_valid(buf))
+           if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
+                                                                 FALSE, buf)
+                   && !buf_valid(buf))
                /* Autocommands deleted the buffer. */
                goto aucmd_abort;
            buf->b_closing = FALSE;
@@ -577,21 +579,23 @@ buf_freeall(buf_T *buf, int flags)
     buf->b_closing = TRUE;
     if (buf->b_ml.ml_mfp != NULL)
     {
-       apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
-       if (!buf_valid(buf))        /* autocommands may delete the buffer */
+       if (apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
+                                                                 FALSE, buf)
+               && !buf_valid(buf))     /* autocommands may delete the buffer */
            return;
     }
     if ((flags & BFA_DEL) && buf->b_p_bl)
     {
-       apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
-       if (!buf_valid(buf))        /* autocommands may delete the buffer */
+       if (apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname,
+                                                                  FALSE, buf)
+               && !buf_valid(buf))     /* autocommands may delete the buffer */
            return;
     }
     if (flags & BFA_WIPE)
     {
-       apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
-                                                                 FALSE, buf);
-       if (!buf_valid(buf))        /* autocommands may delete the buffer */
+       if (apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
+                                                                 FALSE, buf)
+               && !buf_valid(buf))     /* autocommands may delete the buffer */
            return;
     }
     buf->b_closing = FALSE;
@@ -1452,11 +1456,11 @@ set_curbuf(buf_T *buf, int action)
     prevbuf = curbuf;
 
 #ifdef FEAT_AUTOCMD
-    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+    if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf)
 # ifdef FEAT_EVAL
-    if (buf_valid(prevbuf) && !aborting())
+           || (buf_valid(prevbuf) && !aborting()))
 # else
-    if (buf_valid(prevbuf))
+           || buf_valid(prevbuf))
 # endif
 #endif
     {
@@ -1654,6 +1658,8 @@ do_autochdir(void)
  * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
  * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
  * If (flags & BLN_NEW) is TRUE, don't use an existing buffer.
+ * If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer
+ *                                 if the buffer already exists.
  * This is the ONLY way to create a new buffer.
  */
 static int  top_file_num = 1;          /* highest file number */
@@ -1692,17 +1698,20 @@ buflist_new(
        vim_free(ffname);
        if (lnum != 0)
            buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
-       /* copy the options now, if 'cpo' doesn't have 's' and not done
-        * already */
-       buf_copy_options(buf, 0);
+
+       if ((flags & BLN_NOOPT) == 0)
+           /* copy the options now, if 'cpo' doesn't have 's' and not done
+            * already */
+           buf_copy_options(buf, 0);
+
        if ((flags & BLN_LISTED) && !buf->b_p_bl)
        {
            buf->b_p_bl = TRUE;
 #ifdef FEAT_AUTOCMD
            if (!(flags & BLN_DUMMY))
            {
-               apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
-               if (!buf_valid(buf))
+               if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf)
+                       && !buf_valid(buf))
                    return NULL;
            }
 #endif
@@ -1881,13 +1890,13 @@ buflist_new(
        /* Tricky: these autocommands may change the buffer list.  They could
         * also split the window with re-using the one empty buffer. This may
         * result in unexpectedly losing the empty buffer. */
-       apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
-       if (!buf_valid(buf))
+       if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf)
+               && !buf_valid(buf))
            return NULL;
        if (flags & BLN_LISTED)
        {
-           apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
-           if (!buf_valid(buf))
+           if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf)
+                   && !buf_valid(buf))
                return NULL;
        }
 # ifdef FEAT_EVAL
index 95f4c734ac3388054bfc12a76951fe8632efea82..fbf07600ed0885c874b72f33723da760401642cc 100644 (file)
@@ -10634,12 +10634,6 @@ buf_copy_options(buf_T *buf, int flags)
     int                dont_do_help;
     int                did_isk = FALSE;
 
-    /*
-     * Don't do anything if the buffer is invalid.
-     */
-    if (buf == NULL || !buf_valid(buf))
-       return;
-
     /*
      * Skip this when the option defaults have not been set yet.  Happens when
      * main() allocates the first buffer.
index 92a02041740488c6cec92fc114002bddb8cc7d2c..065216afe1a975d1b28331728b16680469346747 100644 (file)
@@ -1482,6 +1482,13 @@ copy_loclist(win_T *from, win_T *to)
     to->w_llist->qf_curlist = qi->qf_curlist;  /* current list */
 }
 
+/*
+ * Looking up a buffer can be slow if there are many.  Remember the last one
+ * to make this a lot faster if there are multiple matches in the same file.
+ */
+static char_u *qf_last_bufname = NULL;
+static buf_T  *qf_last_buf = NULL;
+
 /*
  * Get buffer number for file "dir.name".
  * Also sets the b_has_qf_entry flag.
@@ -1489,8 +1496,9 @@ copy_loclist(win_T *from, win_T *to)
     static int
 qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
 {
-    char_u     *ptr;
+    char_u     *ptr = NULL;
     buf_T      *buf;
+    char_u     *bufname;
 
     if (fname == NULL || *fname == NUL)                /* no file name */
        return 0;
@@ -1522,13 +1530,30 @@ qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
                ptr = vim_strsave(fname);
        }
        /* Use concatenated directory name and file name */
-       buf = buflist_new(ptr, NULL, (linenr_T)0, 0);
+       bufname = ptr;
+    }
+    else
+       bufname = fname;
+
+    if (qf_last_bufname != NULL && STRCMP(bufname, qf_last_bufname) == 0
+           && buf_valid(qf_last_buf))
+    {
+       buf = qf_last_buf;
        vim_free(ptr);
     }
     else
-       buf = buflist_new(fname, NULL, (linenr_T)0, 0);
+    {
+       vim_free(qf_last_bufname);
+       buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT);
+       if (bufname == ptr)
+           qf_last_bufname = bufname;
+       else
+           qf_last_bufname = vim_strsave(bufname);
+       qf_last_buf = buf;
+    }
     if (buf == NULL)
        return 0;
+
     buf->b_has_qf_entry = TRUE;
     return buf->b_fnum;
 }
index cce37b19f121833538320703def4970f7e5c66b6..0d39ffa624458d1140a7862fb6a301b9fd4d43bf 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2017,
 /**/
     2016,
 /**/
index 7d76504bbc23c4eaa02932cb2dc7f9920220a543..4d6f9340d135f45a34bb2ffca5f69be71e7d5ebb 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -941,6 +941,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #define BLN_LISTED     2       /* put new buffer in buffer list */
 #define BLN_DUMMY      4       /* allocating dummy buffer */
 #define BLN_NEW                8       /* create a new buffer */
+#define BLN_NOOPT      16      /* don't copy options to existing buffer */
 
 /* Values for in_cinkeys() */
 #define KEY_OPEN_FORW  0x101