changeset 9473:bdac1019552f v7.4.2017

commit https://github.com/vim/vim/commit/8240433f48f7383c281ba2453cc55f10b8ec47d9 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 10 17:00:38 2016 +0200 patch 7.4.2017 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.
author Christian Brabandt <cb@256bit.org>
date Sun, 10 Jul 2016 17:15:05 +0200
parents 4f3a46b55fd1
children 3601fd30708f
files src/buffer.c src/option.c src/quickfix.c src/version.c src/vim.h
diffstat 5 files changed, 66 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -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
--- a/src/option.c
+++ b/src/option.c
@@ -10635,12 +10635,6 @@ buf_copy_options(buf_T *buf, int flags)
     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.
      */
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1483,14 +1483,22 @@ copy_loclist(win_T *from, win_T *to)
 }
 
 /*
+ * 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.
  */
     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 *direc
 		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;
 }
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2017,
+/**/
     2016,
 /**/
     2015,
--- a/src/vim.h
+++ b/src/vim.h
@@ -941,6 +941,7 @@ extern char *(*dyn_libintl_textdomain)(c
 #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