From 165ba3e636769c38d67285e1b8ea2966ccb00b30 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 20 Mar 2017 14:01:22 +0100 Subject: vim-patch:7.4.2324 Problem: Crash when editing a new buffer and BufUnload autocommand wipes out the new buffer. (Norio Takagi) Solution: Don't allow wiping out this buffer. (partly by Hirohito Higashi) Move old style test13 into test_autocmd. Avoid ml_get error when editing a file. https://github.com/vim/vim/commit/e0ab94e7123ca7855f45919114d948ef2bc1e8c3 --- src/nvim/buffer.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 9e781f5dff..5edc87eab1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -360,6 +360,13 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) wipe_buf = true; } + // Disallow deleting the buffer when it is locked (already being closed or + // halfway a command that relies on it). Unloading is allowed. + if (buf->b_locked > 0 && (del_buf || wipe_buf)) { + EMSG(_("E937: Attempt to delete a buffer that is in use")); + return; + } + if (win_valid_any_tab(win)) { // Set b_last_cursor when closing the last window for the buffer. // Remember the last cursor position and window options of the buffer. @@ -378,14 +385,14 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) /* When the buffer is no longer in a window, trigger BufWinLeave */ if (buf->b_nwindows == 1) { - buf->b_closing = true; + buf->b_locked++; if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false, buf) && !bufref_valid(&bufref)) { // Autocommands deleted the buffer. EMSG(_(e_auabort)); return; } - buf->b_closing = false; + buf->b_locked--; if (abort_if_last && one_window()) { /* Autocommands made this the only window. */ EMSG(_(e_auabort)); @@ -395,14 +402,14 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) /* When the buffer becomes hidden, but is not unloaded, trigger * BufHidden */ if (!unload_buf) { - buf->b_closing = true; + buf->b_locked++; if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false, buf) && !bufref_valid(&bufref)) { // Autocommands deleted the buffer. EMSG(_(e_auabort)); return; } - buf->b_closing = false; + buf->b_locked--; if (abort_if_last && one_window()) { /* Autocommands made this the only window. */ EMSG(_(e_auabort)); @@ -559,7 +566,7 @@ void buf_freeall(buf_T *buf, int flags) tabpage_T *the_curtab = curtab; // Make sure the buffer isn't closed by autocommands. - buf->b_closing = true; + buf->b_locked++; bufref_T bufref; set_bufref(&bufref, buf); @@ -584,7 +591,7 @@ void buf_freeall(buf_T *buf, int flags) // Autocommands may delete the buffer. return; } - buf->b_closing = false; + buf->b_locked--; // If the buffer was in curwin and the window has changed, go back to that // window, if it still exists. This avoids that ":edit x" triggering a @@ -1111,7 +1118,7 @@ do_buffer ( * a window with this buffer. */ while (buf == curbuf - && !(curwin->w_closing || curwin->w_buffer->b_closing) + && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) && (firstwin != lastwin || first_tabpage->tp_next != NULL)) { if (win_close(curwin, FALSE) == FAIL) break; @@ -4499,7 +4506,7 @@ void ex_buffer_all(exarg_T *eap) : wp->w_width != Columns) || (had_tab > 0 && wp != firstwin) ) && firstwin != lastwin - && !(wp->w_closing || wp->w_buffer->b_closing) + && !(wp->w_closing || wp->w_buffer->b_locked > 0) ) { win_close(wp, FALSE); wpnext = firstwin; /* just in case an autocommand does -- cgit From 10f6624f65edbc8af84c9775e6712484be9c81a5 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 10:39:24 +0100 Subject: vim-patch:7.4.2328 Problem: Crash when BufWinLeave autocmd goes to another tab page. (Hirohito Higashi) Solution: Make close_buffer() go back to the right window. --- src/nvim/buffer.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5edc87eab1..7429e8628e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -337,6 +337,10 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); bool wipe_buf = (action == DOBUF_WIPE); + bool is_curwin = (curwin != NULL && curwin->w_buffer == buf); + win_T *the_curwin = curwin; + tabpage_T *the_curtab = curtab; + // Force unloading or deleting when 'bufhidden' says so, but not for terminal // buffers. // The caller must take care of NOT deleting/freeing when 'bufhidden' is @@ -419,6 +423,16 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) if (aborting()) /* autocmds may abort script processing */ return; } + + // If the buffer was in curwin and the window has changed, go back to that + // window, if it still exists. This avoids that ":edit x" triggering a + // "tabnext" BufUnload autocmd leaves a window behind without a buffer. + if (is_curwin && curwin != the_curwin && win_valid_any_tab(the_curwin)) { + block_autocmds(); + goto_tabpage_win(the_curtab, the_curwin); + unblock_autocmds(); + } + int nwindows = buf->b_nwindows; /* decrease the link count from windows (unless not in any window) */ -- cgit From 53ccd07fa1c0bfcb79ca11bd873ea12f4dc12f4a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 11:02:29 +0100 Subject: lint --- src/nvim/buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7429e8628e..3c416c157f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4518,8 +4518,8 @@ void ex_buffer_all(exarg_T *eap) ? wp->w_height + wp->w_status_height < Rows - p_ch - tabline_height() : wp->w_width != Columns) - || (had_tab > 0 && wp != firstwin) - ) && firstwin != lastwin + || (had_tab > 0 && wp != firstwin)) + && firstwin != lastwin && !(wp->w_closing || wp->w_buffer->b_locked > 0) ) { win_close(wp, FALSE); -- cgit From 85ba14af6ad19fa3c4ba1ade3819014254635b2f Mon Sep 17 00:00:00 2001 From: lonerover Date: Thu, 23 Mar 2017 22:54:30 +0800 Subject: vim-patch:7.4.2330 Problem: Coverity complains about not checking curwin to be NULL. Solution: Use firstwin to avoid the warning. https://github.com/vim/vim/commit/030cddc7ec0c3d2fe3969140cd1b92b2f18633c0 --- src/nvim/buffer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 3c416c157f..4a07884f98 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -627,10 +627,11 @@ void buf_freeall(buf_T *buf, int flags) */ if (buf == curbuf && !is_curbuf) return; - diff_buf_delete(buf); /* Can't use 'diff' for unloaded buffer. */ - /* Remove any ownsyntax, unless exiting. */ - if (firstwin != NULL && curwin->w_buffer == buf) + diff_buf_delete(buf); // Can't use 'diff' for unloaded buffer. + // Remove any ownsyntax, unless exiting. + if (curwin != NULL && curwin->w_buffer == buf) { reset_synblock(curwin); + } /* No folds in an empty buffer. */ FOR_ALL_TAB_WINDOWS(tp, win) { -- cgit From fb146e80aa1ead96518f38b9684e39249bc83485 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 26 Jul 2016 23:16:23 +0300 Subject: eval: Split eval.c into smaller files --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4a07884f98..f7333fead4 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1472,7 +1472,7 @@ static inline void buf_init_changedtick(buf_T *const buf) { STATIC_ASSERT(sizeof("changedtick") <= sizeof(buf->changedtick_di.di_key), "buf->changedtick_di cannot hold large enough keys"); - buf->changedtick_di = (dictitem16_T) { + buf->changedtick_di = (ChangedtickDictItem) { .di_flags = DI_FLAGS_RO|DI_FLAGS_FIX, // Must not include DI_FLAGS_ALLOC. .di_tv = (typval_T) { .v_type = VAR_NUMBER, -- cgit From e18a5783080f7c94f408ec5f53dedffdb69789e1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 22:24:34 +0300 Subject: *: Move some dictionary functions to typval.h and use char* Also fixes buffer reusage in setmatches() and complete(). --- src/nvim/buffer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f7333fead4..0ce9ce073e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -661,7 +661,7 @@ static void free_buffer(buf_T *buf) free_buffer_stuff(buf, true); unref_var_dict(buf->b_vars); aubuflocal_remove(buf); - dict_unref(buf->additional_data); + tv_dict_unref(buf->additional_data); clear_fmark(&buf->b_last_cursor); clear_fmark(&buf->b_last_insert); clear_fmark(&buf->b_last_change); @@ -1481,7 +1481,7 @@ static inline void buf_init_changedtick(buf_T *const buf) }, .di_key = "changedtick", }; - dict_add(buf->b_vars, (dictitem_T *)&buf->changedtick_di); + tv_dict_add(buf->b_vars, (dictitem_T *)&buf->changedtick_di); } /// Add a file name to the buffer list. @@ -1573,7 +1573,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) if (buf != curbuf || curbuf == NULL) { buf = xcalloc(1, sizeof(buf_T)); // init b: variables - buf->b_vars = dict_alloc(); + buf->b_vars = tv_dict_alloc(); init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE); buf_init_changedtick(buf); } @@ -5443,8 +5443,8 @@ void buf_open_scratch(handle_T bufnr, char *bufname) { (void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL); (void)setfname(curbuf, (char_u *)bufname, NULL, true); - set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); - set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); - set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); + set_option_value("bh", 0L, "hide", OPT_LOCAL); + set_option_value("bt", 0L, "nofile", OPT_LOCAL); + set_option_value("swf", 0L, NULL, OPT_LOCAL); RESET_BINDING(curwin); } -- cgit From 28dafe3ff0b0dc082fb62b2251fd64a167ce7188 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 21 Aug 2016 08:16:47 +0300 Subject: eval,*: Move get_tv_string to typval.c Function was renamed and changed to return `const char *`. --- src/nvim/buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0ce9ce073e..0fb9a21354 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4207,11 +4207,11 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) #ifdef WIN32 if (!buf->b_p_bin) { // If the file name is a shortcut file, use the file it links to. - char_u *rfname = (char_u *)os_resolve_shortcut(*ffname); + char *rfname = os_resolve_shortcut((const char *)(*ffname)); if (rfname != NULL) { xfree(*ffname); - *ffname = rfname; - *sfname = rfname; + *ffname = (char_u *)rfname; + *sfname = (char_u *)rfname; } } #endif -- cgit From 506b938947b7083fc8bef20eabc08ed033298add Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 14 Feb 2017 00:12:57 +0300 Subject: *: Make some more things const and with length --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0fb9a21354..c9101c5b53 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3504,7 +3504,7 @@ int build_stl_str_hl( curbuf = o_curbuf; // Remove the variable we just stored - do_unlet((char_u *)"g:actual_curbuf", true); + do_unlet(S_LEN("g:actual_curbuf"), true); // } -- cgit From 5dcf2804455f45eac8aad7d900bf60464a4b2888 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 02:03:05 +0300 Subject: fileio: Refactor msg_add_fname to something which needs no comments --- src/nvim/buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index c9101c5b53..292eb03a16 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2724,7 +2724,7 @@ fileinfo ( else name = curbuf->b_ffname; home_replace(shorthelp ? curbuf : NULL, name, p, - (int)(IOSIZE - (p - buffer)), TRUE); + (size_t)(IOSIZE - (p - buffer)), true); } vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s", @@ -2889,7 +2889,7 @@ void maketitle(void) buf[off++] = ' '; buf[off++] = '('; home_replace(curbuf, curbuf->b_ffname, - buf + off, SPACE_FOR_DIR - off, TRUE); + buf + off, (size_t)(SPACE_FOR_DIR - off), true); #ifdef BACKSLASH_IN_FILENAME /* avoid "c:/name" to be reduced to "c" */ if (isalpha(buf[off]) && buf[off + 1] == ':') -- cgit