diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer.c | 24 | ||||
-rw-r--r-- | src/ex_cmds.c | 5 | ||||
-rw-r--r-- | src/fileio.c | 11 | ||||
-rw-r--r-- | src/globals.h | 5 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 39 insertions, 8 deletions
diff --git a/src/buffer.c b/src/buffer.c index d25ed10ac7..7402c57ec8 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -550,7 +550,14 @@ static void free_buffer(buf_T *buf) free_buffer_stuff(buf, TRUE); unref_var_dict(buf->b_vars); aubuflocal_remove(buf); - vim_free(buf); + if (autocmd_busy) { + // Do not free the buffer structure while autocommands are executing, + // it's still needed. Free it when autocmd_busy is reset. + buf->b_next = au_pending_free_buf; + au_pending_free_buf = buf; + } else { + vim_free(buf); + } } /* @@ -1332,8 +1339,12 @@ buflist_new ( buf_copy_options(buf, 0); if ((flags & BLN_LISTED) && !buf->b_p_bl) { buf->b_p_bl = TRUE; - if (!(flags & BLN_DUMMY)) + if (!(flags & BLN_DUMMY)) { apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf); + if (!buf_valid(buf)) { + return NULL; + } + } } return buf; } @@ -1469,8 +1480,15 @@ buflist_new ( buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */ if (!(flags & BLN_DUMMY)) { apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf); - if (flags & BLN_LISTED) + if (!buf_valid(buf)) { + return NULL; + } + if (flags & BLN_LISTED) { apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf); + if (!buf_valid(buf)) { + return NULL; + } + } if (aborting()) /* autocmds may abort script processing */ return NULL; } diff --git a/src/ex_cmds.c b/src/ex_cmds.c index e3d02357e1..0779568bc8 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -2774,6 +2774,11 @@ do_ecmd ( } buf = buflist_new(ffname, sfname, 0L, BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED)); + // Autocmds may change curwin and curbuf. + if (oldwin != NULL) { + oldwin = curwin; + } + old_curbuf = curbuf; } if (buf == NULL) goto theend; diff --git a/src/fileio.c b/src/fileio.c index fb9f0e0cea..68b68ef3ed 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -7525,14 +7525,17 @@ apply_autocmds_group ( vim_free(sfname); --nesting; /* see matching increment above */ - /* - * When stopping to execute autocommands, restore the search patterns and - * the redo buffer. - */ + // When stopping to execute autocommands, restore the search patterns and + // the redo buffer. Free buffers in the au_pending_free_buf list. if (!autocmd_busy) { restore_search_patterns(); restoreRedobuff(); did_filetype = FALSE; + while (au_pending_free_buf != NULL) { + buf_T *b = au_pending_free_buf->b_next; + vim_free(au_pending_free_buf); + au_pending_free_buf = b; + } } /* diff --git a/src/globals.h b/src/globals.h index 731c99623c..2b39ef5416 100644 --- a/src/globals.h +++ b/src/globals.h @@ -352,6 +352,11 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when * which one is preferred, au_new_curbuf is set to it */ EXTERN buf_T *au_new_curbuf INIT(= NULL); +// When deleting the buffer and autocmd_busy is TRUE, do not free the buffer +// but link it in the list starting with au_pending_free_buf, using b_next. +// Free the buffer when autocmd_busy is set to FALSE. +EXTERN buf_T *au_pending_free_buf INIT(= NULL); + /* * Mouse coordinates, set by check_termcode() */ diff --git a/src/version.c b/src/version.c index 72cc8cf5d4..0f00231659 100644 --- a/src/version.c +++ b/src/version.c @@ -209,7 +209,7 @@ static int included_patches[] = { //254, //253, //252, - //251, + 251, //250, //249, //248, |