aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-12-21 09:28:26 -0500
committerGitHub <noreply@github.com>2020-12-21 09:28:26 -0500
commitf15441be4b6697a4917f5edd99d403d5c953e66c (patch)
tree142f01b78c29051cf360ad3ada0efac6bd3e6d3f
parenta1ec36ff31ff1fd545dd135faa47dc782b41a687 (diff)
parentebb0cbc6cccb0b75507815939aa761ae625ba0df (diff)
downloadrneovim-f15441be4b6697a4917f5edd99d403d5c953e66c.tar.gz
rneovim-f15441be4b6697a4917f5edd99d403d5c953e66c.tar.bz2
rneovim-f15441be4b6697a4917f5edd99d403d5c953e66c.zip
Merge pull request #13573 from janlazo/vim-8.1.1872
vim-patch:8.1.1872,8.2.1966
-rw-r--r--src/nvim/autocmd.c31
-rw-r--r--src/nvim/autocmd.h14
-rw-r--r--src/nvim/main.c10
-rw-r--r--src/nvim/window.c13
4 files changed, 47 insertions, 21 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 53b11c250e..42224d0a4f 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -1106,9 +1106,9 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
win = curwin;
}
- aco->save_curwin = curwin;
- aco->save_prevwin = prevwin;
+ aco->save_curwin_handle = curwin->handle;
aco->save_curbuf = curbuf;
+ aco->save_prevwin_handle = prevwin == NULL ? 0 : prevwin->handle;
if (win != NULL) {
// There is a window for "buf" in the current tab page, make it the
// curwin. This is preferred, it has the least side effects (esp. if
@@ -1148,7 +1148,7 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
curwin = aucmd_win;
}
curbuf = buf;
- aco->new_curwin = curwin;
+ aco->new_curwin_handle = curwin->handle;
set_bufref(&aco->new_curbuf, curbuf);
}
@@ -1194,14 +1194,14 @@ void aucmd_restbuf(aco_save_T *aco)
unblock_autocmds();
- if (win_valid(aco->save_curwin)) {
- curwin = aco->save_curwin;
+ win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle);
+ if (save_curwin != NULL) {
+ curwin = save_curwin;
} else {
// Hmm, original window disappeared. Just use the first one.
curwin = firstwin;
}
- prevwin = win_valid(aco->save_prevwin) ? aco->save_prevwin
- : firstwin; // window disappeared?
+ prevwin = win_find_by_handle(aco->save_prevwin_handle);
vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
curbuf = curwin->w_buffer;
@@ -1216,11 +1216,14 @@ void aucmd_restbuf(aco_save_T *aco)
curwin->w_topfill = 0;
}
} else {
- // restore curwin
- if (win_valid(aco->save_curwin)) {
+ // Restore curwin. Use the window ID, a window may have been closed
+ // and the memory re-used for another one.
+ win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle);
+ if (save_curwin != NULL) {
// Restore the buffer which was previously edited by curwin, if it was
// changed, we are still the same window and the buffer is valid.
- if (curwin == aco->new_curwin && curbuf != aco->new_curbuf.br_buf
+ if (curwin->handle == aco->new_curwin_handle
+ && curbuf != aco->new_curbuf.br_buf
&& bufref_valid(&aco->new_curbuf)
&& aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) {
if (curwin->w_s == &curbuf->b_s) {
@@ -1232,10 +1235,9 @@ void aucmd_restbuf(aco_save_T *aco)
curbuf->b_nwindows++;
}
- curwin = aco->save_curwin;
- prevwin = win_valid(aco->save_prevwin) ? aco->save_prevwin
- : firstwin; // window disappeared?
+ curwin = save_curwin;
curbuf = curwin->w_buffer;
+ prevwin = win_find_by_handle(aco->save_prevwin_handle);
// In case the autocommand moves the cursor to a position that does not
// exist in curbuf
check_cursor();
@@ -1717,7 +1719,8 @@ void unblock_autocmds(void)
}
}
-static inline bool is_autocmd_blocked(void)
+bool is_autocmd_blocked(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return autocmd_blocked != 0;
}
diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h
index af1eeb0fc4..1c0f88f08f 100644
--- a/src/nvim/autocmd.h
+++ b/src/nvim/autocmd.h
@@ -7,13 +7,13 @@
// Struct to save values in before executing autocommands for a buffer that is
// not the current buffer.
typedef struct {
- buf_T *save_curbuf; ///< saved curbuf
- int use_aucmd_win; ///< using aucmd_win
- win_T *save_curwin; ///< saved curwin
- win_T *save_prevwin; ///< saved prevwin
- win_T *new_curwin; ///< new curwin
- bufref_T new_curbuf; ///< new curbuf
- char_u *globaldir; ///< saved value of globaldir
+ buf_T *save_curbuf; ///< saved curbuf
+ bool use_aucmd_win; ///< using aucmd_win
+ handle_T save_curwin_handle; ///< ID of saved curwin
+ handle_T new_curwin_handle; ///< ID of new curwin
+ handle_T save_prevwin_handle; ///< ID of saved prevwin
+ bufref_T new_curbuf; ///< new curbuf
+ char_u *globaldir; ///< saved value of globaldir
} aco_save_T;
typedef struct AutoCmd {
diff --git a/src/nvim/main.c b/src/nvim/main.c
index fd8264583b..ed055e76ba 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -662,7 +662,17 @@ void getout(int exitval)
}
if (v_dying <= 1) {
+ int unblock = 0;
+
+ // deathtrap() blocks autocommands, but we do want to trigger VimLeave.
+ if (is_autocmd_blocked()) {
+ unblock_autocmds();
+ unblock++;
+ }
apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, false, curbuf);
+ if (unblock) {
+ block_autocmds();
+ }
}
profile_dump();
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 0f17e2cb09..ad1e1f8f02 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1637,6 +1637,19 @@ bool win_valid(const win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
return false;
}
+// Find window "handle" in the current tab page.
+// Return NULL if not found.
+win_T *win_find_by_handle(handle_T handle)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->handle == handle) {
+ return wp;
+ }
+ }
+ return NULL;
+}
+
/// Check if "win" is a pointer to an existing window in any tabpage.
///
/// @param win window to check