Skip to content

Commit

Permalink
Merge pull request #6323 from justinmk/vimpatches
Browse files Browse the repository at this point in the history
  • Loading branch information
justinmk committed Mar 24, 2017
2 parents a62ec4e + 7214d0b commit 3827405
Show file tree
Hide file tree
Showing 32 changed files with 1,499 additions and 314 deletions.
41 changes: 31 additions & 10 deletions src/nvim/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -360,6 +364,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.
Expand All @@ -378,14 +389,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));
Expand All @@ -395,14 +406,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));
Expand All @@ -412,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) */
Expand Down Expand Up @@ -559,7 +580,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);
Expand All @@ -584,7 +605,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
Expand Down Expand Up @@ -1111,7 +1132,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;
Expand Down Expand Up @@ -4497,9 +4518,9 @@ 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
&& !(wp->w_closing || wp->w_buffer->b_closing)
|| (had_tab > 0 && wp != firstwin))
&& firstwin != lastwin
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)
) {
win_close(wp, FALSE);
wpnext = firstwin; /* just in case an autocommand does
Expand Down
6 changes: 3 additions & 3 deletions src/nvim/buffer_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ struct file_buffer {

int b_nwindows; /* nr of windows open on this buffer */

int b_flags; /* various BF_ flags */
bool b_closing; /* buffer is being closed, don't let
autocommands close it too. */
int b_flags; // various BF_ flags
int b_locked; // Buffer is being closed or referenced, don't
// let autocommands wipe it out.

/*
* b_ffname has the full path of the file (NULL for no name).
Expand Down
5 changes: 5 additions & 0 deletions src/nvim/charset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,11 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
// continue until the NUL
posptr = NULL;
} else {
// Special check for an empty line, which can happen on exit, when
// ml_get_buf() always returns an empty string.
if (*ptr == NUL) {
pos->col = 0;
}
posptr = ptr + pos->col;
}

Expand Down
13 changes: 6 additions & 7 deletions src/nvim/ex_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -2284,20 +2284,24 @@ int do_ecmd(
} else {
win_T *the_curwin = curwin;

// Set the w_closing flag to avoid that autocommands close the window.
// Set w_closing to avoid that autocommands close the window.
// Set b_locked for the same reason.
the_curwin->w_closing = true;
buf->b_locked++;

if (curbuf == old_curbuf.br_buf) {
buf_copy_options(buf, BCO_ENTER);
}

// Close the link to the current buffer. This will set
// curwin->w_buffer to NULL.
// oldwin->w_buffer to NULL.
u_sync(false);
close_buffer(oldwin, curbuf,
(flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD,
false);

the_curwin->w_closing = false;
buf->b_locked--;

// autocmds may abort script processing
if (aborting() && curwin->w_buffer != NULL) {
Expand Down Expand Up @@ -2444,11 +2448,6 @@ int do_ecmd(
/* Assume success now */
retval = OK;

/*
* Reset cursor position, could be used by autocommands.
*/
check_cursor();

/*
* Check if we are editing the w_arg_idx file in the argument list.
*/
Expand Down
29 changes: 15 additions & 14 deletions src/nvim/ex_cmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ local ADDR_ARGUMENTS = 2
local ADDR_LOADED_BUFFERS = 3
local ADDR_BUFFERS = 4
local ADDR_TABS = 5
local ADDR_QUICKFIX = 6
local ADDR_TABS_RELATIVE = 6
local ADDR_QUICKFIX = 7
local ADDR_OTHER = 99

-- The following table is described in ex_cmds_defs.h file.
Expand Down Expand Up @@ -2650,12 +2651,12 @@ return {
{
command='tab',
flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM),
addr_type=ADDR_LINES,
addr_type=ADDR_TABS,
func='ex_wrongmodifier',
},
{
command='tabclose',
flags=bit.bor(RANGE, NOTADR, COUNT, BANG, TRLBAR, CMDWIN),
flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS,
func='ex_tabclose',
},
Expand All @@ -2680,7 +2681,7 @@ return {
{
command='tabfirst',
flags=bit.bor(TRLBAR),
addr_type=ADDR_LINES,
addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
Expand All @@ -2692,13 +2693,13 @@ return {
{
command='tablast',
flags=bit.bor(TRLBAR),
addr_type=ADDR_LINES,
addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
command='tabnext',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
addr_type=ADDR_LINES,
flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
Expand All @@ -2709,32 +2710,32 @@ return {
},
{
command='tabonly',
flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR, CMDWIN),
flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS,
func='ex_tabonly',
},
{
command='tabprevious',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
addr_type=ADDR_LINES,
flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext',
},
{
command='tabNext',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
addr_type=ADDR_LINES,
flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext',
},
{
command='tabrewind',
flags=bit.bor(TRLBAR),
addr_type=ADDR_LINES,
addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
command='tabs',
flags=bit.bor(TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
addr_type=ADDR_TABS,
func='ex_tabs',
},
{
Expand Down
3 changes: 2 additions & 1 deletion src/nvim/ex_cmds_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
#define ADDR_LOADED_BUFFERS 3
#define ADDR_BUFFERS 4
#define ADDR_TABS 5
#define ADDR_QUICKFIX 6
#define ADDR_TABS_RELATIVE 6 // Tab page that only relative
#define ADDR_QUICKFIX 7
#define ADDR_OTHER 99

typedef struct exarg exarg_T;
Expand Down
Loading

0 comments on commit 3827405

Please sign in to comment.