diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-08-21 22:25:30 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-08-21 22:25:30 +0200 |
commit | 00b0d6d8dc2c04b3cb26ea3c3d58527939f01af6 (patch) | |
tree | 0f3a9bc3181d31e26e8539ab8f59f2c73c9ff39b /src/buffer.c | |
parent | fe6e7618b4d05cb91679dbf7ed5983c95ff5b6a2 (diff) | |
download | vim-git-00b0d6d8dc2c04b3cb26ea3c3d58527939f01af6.tar.gz |
patch 8.1.1908: every popup window consumes a buffer numberv8.1.1908
Problem: Every popup window consumes a buffer number.
Solution: Recycle buffers only used for popup windows. Do not list popup
window buffers.
Diffstat (limited to 'src/buffer.c')
-rw-r--r-- | src/buffer.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/src/buffer.c b/src/buffer.c index a9aa30c3e..257ae7d88 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -62,9 +62,21 @@ static char *msg_qflist = N_("[Quickfix List]"); #endif static char *e_auabort = N_("E855: Autocommands caused command to abort"); -/* Number of times free_buffer() was called. */ +// Number of times free_buffer() was called. static int buf_free_count = 0; +static int top_file_num = 1; // highest file number +static garray_T buf_reuse = GA_EMPTY; // file numbers to recycle + +/* + * Return the highest possible buffer number. + */ + int +get_highest_fnum(void) +{ + return top_file_num - 1; +} + /* * Read data from buffer for retrying. */ @@ -470,6 +482,7 @@ can_unload_buffer(buf_T *buf) * DOBUF_UNLOAD buffer is unloaded * DOBUF_DELETE buffer is unloaded and removed from buffer list * DOBUF_WIPE buffer is unloaded and really deleted + * DOBUF_WIPE_REUSE idem, and add to buf_reuse list * When doing all but the first one on the current buffer, the caller should * get a new buffer very soon! * @@ -493,8 +506,8 @@ close_buffer( win_T *the_curwin = curwin; tabpage_T *the_curtab = curtab; int unload_buf = (action != 0); - int del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); - int wipe_buf = (action == DOBUF_WIPE); + int wipe_buf = (action == DOBUF_WIPE || action == DOBUF_WIPE_REUSE); + int del_buf = (action == DOBUF_DEL || wipe_buf); /* * Force unloading or deleting when 'bufhidden' says so. @@ -686,6 +699,14 @@ aucmd_abort: */ if (wipe_buf) { + if (action == DOBUF_WIPE_REUSE) + { + // we can re-use this buffer number, store it + if (buf_reuse.ga_itemsize == 0) + ga_init2(&buf_reuse, sizeof(int), 50); + if (ga_grow(&buf_reuse, 1) == OK) + ((int *)buf_reuse.ga_data)[buf_reuse.ga_len++] = buf->b_fnum; + } if (buf->b_sfname != buf->b_ffname) VIM_CLEAR(buf->b_sfname); else @@ -1184,7 +1205,8 @@ do_bufdel( if (!VIM_ISDIGIT(*arg)) { p = skiptowhite_esc(arg); - bnr = buflist_findpat(arg, p, command == DOBUF_WIPE, + bnr = buflist_findpat(arg, p, + command == DOBUF_WIPE || command == DOBUF_WIPE_REUSE, FALSE, FALSE); if (bnr < 0) /* failed */ break; @@ -1275,6 +1297,7 @@ empty_curbuf( * action == DOBUF_UNLOAD unload specified buffer(s) * action == DOBUF_DEL delete specified buffer(s) from buffer list * action == DOBUF_WIPE delete specified buffer(s) really + * action == DOBUF_WIPE_REUSE idem, and add number to "buf_reuse" * * start == DOBUF_CURRENT go to "count" buffer from current buffer * start == DOBUF_FIRST go to "count" buffer from first buffer @@ -1294,7 +1317,7 @@ do_buffer( buf_T *buf; buf_T *bp; int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL - || action == DOBUF_WIPE); + || action == DOBUF_WIPE || action == DOBUF_WIPE_REUSE); switch (start) { @@ -1395,7 +1418,8 @@ do_buffer( /* When unloading or deleting a buffer that's already unloaded and * unlisted: fail silently. */ - if (action != DOBUF_WIPE && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl) + if (action != DOBUF_WIPE && action != DOBUF_WIPE_REUSE + && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl) return FAIL; if (!forceit && bufIsChanged(buf)) @@ -1631,13 +1655,14 @@ do_buffer( * DOBUF_UNLOAD unload it * DOBUF_DEL delete it * DOBUF_WIPE wipe it out + * DOBUF_WIPE_REUSE wipe it out and add to "buf_reuse" */ void set_curbuf(buf_T *buf, int action) { buf_T *prevbuf; int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL - || action == DOBUF_WIPE); + || action == DOBUF_WIPE || action == DOBUF_WIPE_REUSE); #ifdef FEAT_SYN_HL long old_tw = curbuf->b_p_tw; #endif @@ -1861,8 +1886,6 @@ no_write_message_nobang(buf_T *buf UNUSED) * functions for dealing with the buffer list */ -static int top_file_num = 1; /* highest file number */ - /* * Return TRUE if the current buffer is empty, unnamed, unmodified and used in * only one window. That means it can be re-used. @@ -1890,6 +1913,7 @@ curbuf_reusable(void) * 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. + * If (flags & BLN_REUSE) is TRUE, may use buffer number from "buf_reuse". * This is the ONLY way to create a new buffer. */ buf_T * @@ -2065,7 +2089,16 @@ buflist_new( } lastbuf = buf; - buf->b_fnum = top_file_num++; + if ((flags & BLN_REUSE) && buf_reuse.ga_len > 0) + { + // Recycle a previously used buffer number. Used for buffers which + // are normally hidden, e.g. in a popup window. Avoids that the + // buffer number grows rapidly. + --buf_reuse.ga_len; + buf->b_fnum = ((int *)buf_reuse.ga_data)[buf_reuse.ga_len]; + } + else + buf->b_fnum = top_file_num++; if (top_file_num < 0) /* wrap around (may cause duplicates) */ { emsg(_("W14: Warning: List of file names overflow")); |