diff options
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r-- | src/nvim/buffer.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ee87411523..3ccbb4efdd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -97,6 +97,11 @@ static char *e_auabort = N_("E855: Autocommands caused command to abort"); // Number of times free_buffer() was called. static int buf_free_count = 0; +typedef enum { + kBffClearWinInfo = 1, + kBffInitChangedtick = 2, +} BufFreeFlags; + // Read data from buffer for retrying. static int read_buffer( @@ -619,9 +624,9 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) free_buffer(buf); } else { if (del_buf) { - /* Free all internal variables and reset option values, to make - * ":bdel" compatible with Vim 5.7. */ - free_buffer_stuff(buf, true); + // Free all internal variables and reset option values, to make + // ":bdel" compatible with Vim 5.7. + free_buffer_stuff(buf, kBffClearWinInfo | kBffInitChangedtick); // Make it look like a new buffer. buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED; @@ -756,9 +761,12 @@ static void free_buffer(buf_T *buf) { handle_unregister_buffer(buf); buf_free_count++; - free_buffer_stuff(buf, true); - // b:changedtick uses an item in buf_T, remove it now. - tv_dict_item_remove(buf->b_vars, (dictitem_T *)&buf->changedtick_di); + // b:changedtick uses an item in buf_T. + free_buffer_stuff(buf, kBffClearWinInfo); + if (buf->b_vars->dv_refcount > DO_NOT_FREE_CNT) { + tv_dict_add(buf->b_vars, + tv_dict_item_copy((dictitem_T *)(&buf->changedtick_di))); + } unref_var_dict(buf->b_vars); aubuflocal_remove(buf); tv_dict_unref(buf->additional_data); @@ -783,22 +791,19 @@ static void free_buffer(buf_T *buf) } } -/* - * Free stuff in the buffer for ":bdel" and when wiping out the buffer. - */ -static void -free_buffer_stuff( - buf_T *buf, - int free_options // free options as well -) +/// Free stuff in the buffer for ":bdel" and when wiping out the buffer. +/// +/// @param buf Buffer pointer +/// @param free_flags BufFreeFlags +static void free_buffer_stuff(buf_T *buf, int free_flags) { - if (free_options) { + if (free_flags & kBffClearWinInfo) { clear_wininfo(buf); // including window-local options free_buf_options(buf, true); ga_clear(&buf->b_s.b_langp); } { - // Avoid loosing b:changedtick when deleting buffer: clearing variables + // Avoid losing b:changedtick when deleting buffer: clearing variables // implies using clear_tv() on b:changedtick and that sets changedtick to // zero. hashitem_T *const changedtick_hi = hash_find( @@ -808,7 +813,9 @@ free_buffer_stuff( } vars_clear(&buf->b_vars->dv_hashtab); // free all internal variables hash_init(&buf->b_vars->dv_hashtab); - buf_init_changedtick(buf); + if (free_flags & kBffInitChangedtick) { + buf_init_changedtick(buf); + } uc_clear(&buf->b_ucmds); // clear local user commands buf_delete_signs(buf, (char_u *)"*"); // delete any signs bufhl_clear_all(buf); // delete any highligts @@ -1787,7 +1794,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) if (aborting()) { // autocmds may abort script processing return NULL; } - free_buffer_stuff(buf, false); // delete local variables et al. + free_buffer_stuff(buf, kBffInitChangedtick); // delete local vars et al. // Init the options. buf->b_p_initialized = false; |