diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-12-21 09:28:26 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-21 09:28:26 -0500 |
commit | f15441be4b6697a4917f5edd99d403d5c953e66c (patch) | |
tree | 142f01b78c29051cf360ad3ada0efac6bd3e6d3f | |
parent | a1ec36ff31ff1fd545dd135faa47dc782b41a687 (diff) | |
parent | ebb0cbc6cccb0b75507815939aa761ae625ba0df (diff) | |
download | rneovim-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.c | 31 | ||||
-rw-r--r-- | src/nvim/autocmd.h | 14 | ||||
-rw-r--r-- | src/nvim/main.c | 10 | ||||
-rw-r--r-- | src/nvim/window.c | 13 |
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 |