To: vim_dev@googlegroups.com Subject: Patch 7.4.2017 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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. Files: src/buffer.c, src/option.c, src/quickfix.c, src/vim.h *** ../vim-7.4.2016/src/buffer.c 2016-07-09 23:40:29.831039214 +0200 --- src/buffer.c 2016-07-10 16:43:48.432580746 +0200 *************** *** 316,322 **** { buf_T *bp; ! for (bp = firstbuf; bp != NULL; bp = bp->b_next) if (bp == buf) return TRUE; return FALSE; --- 316,324 ---- { buf_T *bp; ! /* 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,405 **** 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)) { /* Autocommands deleted the buffer. */ aucmd_abort: --- 399,407 ---- if (buf->b_nwindows == 1) { buf->b_closing = TRUE; ! if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, ! FALSE, buf) ! && !buf_valid(buf)) { /* Autocommands deleted the buffer. */ aucmd_abort: *************** *** 416,424 **** if (!unload_buf) { buf->b_closing = TRUE; ! apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, ! FALSE, buf); ! if (!buf_valid(buf)) /* Autocommands deleted the buffer. */ goto aucmd_abort; buf->b_closing = FALSE; --- 418,426 ---- if (!unload_buf) { buf->b_closing = TRUE; ! 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,597 **** 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 */ 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 */ 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 */ return; } buf->b_closing = FALSE; --- 579,601 ---- buf->b_closing = TRUE; if (buf->b_ml.ml_mfp != NULL) { ! 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) { ! 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) { ! 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,1462 **** prevbuf = curbuf; #ifdef FEAT_AUTOCMD ! apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); # ifdef FEAT_EVAL ! if (buf_valid(prevbuf) && !aborting()) # else ! if (buf_valid(prevbuf)) # endif #endif { --- 1456,1466 ---- prevbuf = curbuf; #ifdef FEAT_AUTOCMD ! if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf) # ifdef FEAT_EVAL ! || (buf_valid(prevbuf) && !aborting())) # else ! || buf_valid(prevbuf)) # endif #endif { *************** *** 1654,1659 **** --- 1658,1665 ---- * 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,1708 **** 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_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)) return NULL; } #endif --- 1698,1717 ---- vim_free(ffname); if (lnum != 0) buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE); ! ! 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)) { ! if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf) ! && !buf_valid(buf)) return NULL; } #endif *************** *** 1881,1893 **** /* 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)) return NULL; if (flags & BLN_LISTED) { ! apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf); ! if (!buf_valid(buf)) return NULL; } # ifdef FEAT_EVAL --- 1890,1902 ---- /* 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. */ ! if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf) ! && !buf_valid(buf)) return NULL; if (flags & BLN_LISTED) { ! if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf) ! && !buf_valid(buf)) return NULL; } # ifdef FEAT_EVAL *** ../vim-7.4.2016/src/option.c 2016-07-01 23:13:57.380275358 +0200 --- src/option.c 2016-07-10 15:43:51.759068244 +0200 *************** *** 10635,10646 **** 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. */ --- 10635,10640 ---- *** ../vim-7.4.2016/src/quickfix.c 2016-07-09 17:55:24.902980302 +0200 --- src/quickfix.c 2016-07-10 16:45:08.119385640 +0200 *************** *** 1483,1496 **** } /* * 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; buf_T *buf; if (fname == NULL || *fname == NUL) /* no file name */ return 0; --- 1483,1504 ---- } /* + * 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 = NULL; buf_T *buf; + char_u *bufname; if (fname == NULL || *fname == NUL) /* no file name */ return 0; *************** *** 1522,1534 **** ptr = vim_strsave(fname); } /* Use concatenated directory name and file name */ ! buf = buflist_new(ptr, NULL, (linenr_T)0, 0); vim_free(ptr); } else ! buf = buflist_new(fname, NULL, (linenr_T)0, 0); if (buf == NULL) return 0; buf->b_has_qf_entry = TRUE; return buf->b_fnum; } --- 1530,1559 ---- ptr = vim_strsave(fname); } /* Use concatenated directory name and file name */ ! 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 ! { ! 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; } *** ../vim-7.4.2016/src/vim.h 2016-07-01 17:17:13.298266645 +0200 --- src/vim.h 2016-07-10 15:41:41.337027713 +0200 *************** *** 941,946 **** --- 941,947 ---- #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 *** ../vim-7.4.2016/src/version.c 2016-07-10 13:57:35.889542273 +0200 --- src/version.c 2016-07-10 16:08:56.172214520 +0200 *************** *** 760,761 **** --- 760,763 ---- { /* Add new patch number below this line */ + /**/ + 2017, /**/ -- hundred-and-one symptoms of being an internet addict: 263. You have more e-mail addresses than shorts. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///