mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #18182 from zeertzjq/vim-8.2.2472
vim-patch:8.1.1756,8.2.{2472,2474,2475,2476,2477,4791,4802}: autocommand fixes
This commit is contained in:
commit
e6dec30332
@ -466,6 +466,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
|||||||
// When the buffer is no longer in a window, trigger BufWinLeave
|
// When the buffer is no longer in a window, trigger BufWinLeave
|
||||||
if (buf->b_nwindows == 1) {
|
if (buf->b_nwindows == 1) {
|
||||||
buf->b_locked++;
|
buf->b_locked++;
|
||||||
|
buf->b_locked_split++;
|
||||||
if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false,
|
if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false,
|
||||||
buf) && !bufref_valid(&bufref)) {
|
buf) && !bufref_valid(&bufref)) {
|
||||||
// Autocommands deleted the buffer.
|
// Autocommands deleted the buffer.
|
||||||
@ -473,6 +474,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buf->b_locked--;
|
buf->b_locked--;
|
||||||
|
buf->b_locked_split--;
|
||||||
if (abort_if_last && last_nonfloat(win)) {
|
if (abort_if_last && last_nonfloat(win)) {
|
||||||
// Autocommands made this the only window.
|
// Autocommands made this the only window.
|
||||||
emsg(_(e_auabort));
|
emsg(_(e_auabort));
|
||||||
@ -483,6 +485,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
|||||||
// BufHidden
|
// BufHidden
|
||||||
if (!unload_buf) {
|
if (!unload_buf) {
|
||||||
buf->b_locked++;
|
buf->b_locked++;
|
||||||
|
buf->b_locked_split++;
|
||||||
if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,
|
if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,
|
||||||
buf) && !bufref_valid(&bufref)) {
|
buf) && !bufref_valid(&bufref)) {
|
||||||
// Autocommands deleted the buffer.
|
// Autocommands deleted the buffer.
|
||||||
@ -490,6 +493,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buf->b_locked--;
|
buf->b_locked--;
|
||||||
|
buf->b_locked_split--;
|
||||||
if (abort_if_last && last_nonfloat(win)) {
|
if (abort_if_last && last_nonfloat(win)) {
|
||||||
// Autocommands made this the only window.
|
// Autocommands made this the only window.
|
||||||
emsg(_(e_auabort));
|
emsg(_(e_auabort));
|
||||||
@ -678,6 +682,7 @@ void buf_freeall(buf_T *buf, int flags)
|
|||||||
|
|
||||||
// Make sure the buffer isn't closed by autocommands.
|
// Make sure the buffer isn't closed by autocommands.
|
||||||
buf->b_locked++;
|
buf->b_locked++;
|
||||||
|
buf->b_locked_split++;
|
||||||
|
|
||||||
bufref_T bufref;
|
bufref_T bufref;
|
||||||
set_bufref(&bufref, buf);
|
set_bufref(&bufref, buf);
|
||||||
@ -703,6 +708,7 @@ void buf_freeall(buf_T *buf, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buf->b_locked--;
|
buf->b_locked--;
|
||||||
|
buf->b_locked_split--;
|
||||||
|
|
||||||
// If the buffer was in curwin and the window has changed, go back to that
|
// 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
|
// window, if it still exists. This avoids that ":edit x" triggering a
|
||||||
@ -1466,8 +1472,8 @@ void set_curbuf(buf_T *buf, int action)
|
|||||||
set_bufref(&prevbufref, prevbuf);
|
set_bufref(&prevbufref, prevbuf);
|
||||||
set_bufref(&newbufref, buf);
|
set_bufref(&newbufref, buf);
|
||||||
|
|
||||||
// Autocommands may delete the current buffer and/or the buffer we want to go
|
// Autocommands may delete the current buffer and/or the buffer we want to
|
||||||
// to. In those cases don't close the buffer.
|
// go to. In those cases don't close the buffer.
|
||||||
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|
||||||
|| (bufref_valid(&prevbufref) && bufref_valid(&newbufref)
|
|| (bufref_valid(&prevbufref) && bufref_valid(&newbufref)
|
||||||
&& !aborting())) {
|
&& !aborting())) {
|
||||||
@ -1742,21 +1748,14 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl
|
|||||||
buf = curbuf;
|
buf = curbuf;
|
||||||
// It's like this buffer is deleted. Watch out for autocommands that
|
// It's like this buffer is deleted. Watch out for autocommands that
|
||||||
// change curbuf! If that happens, allocate a new buffer anyway.
|
// change curbuf! If that happens, allocate a new buffer anyway.
|
||||||
if (curbuf->b_p_bl) {
|
buf_freeall(buf, BFA_WIPE | BFA_DEL);
|
||||||
apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf);
|
if (buf != curbuf) { // autocommands deleted the buffer!
|
||||||
}
|
return NULL;
|
||||||
if (buf == curbuf) {
|
|
||||||
apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, false, curbuf);
|
|
||||||
}
|
}
|
||||||
if (aborting()) { // autocmds may abort script processing
|
if (aborting()) { // autocmds may abort script processing
|
||||||
xfree(ffname);
|
xfree(ffname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (buf == curbuf) {
|
|
||||||
// Make sure 'bufhidden' and 'buftype' are empty
|
|
||||||
clear_string_option(&buf->b_p_bh);
|
|
||||||
clear_string_option(&buf->b_p_bt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (buf != curbuf || curbuf == NULL) {
|
if (buf != curbuf || curbuf == NULL) {
|
||||||
buf = xcalloc(1, sizeof(buf_T));
|
buf = xcalloc(1, sizeof(buf_T));
|
||||||
@ -1776,14 +1775,6 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl
|
|||||||
buf->b_wininfo = xcalloc(1, sizeof(wininfo_T));
|
buf->b_wininfo = xcalloc(1, sizeof(wininfo_T));
|
||||||
|
|
||||||
if (buf == curbuf) {
|
if (buf == curbuf) {
|
||||||
// free all things allocated for this buffer
|
|
||||||
buf_freeall(buf, 0);
|
|
||||||
if (buf != curbuf) { // autocommands deleted the buffer!
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (aborting()) { // autocmds may abort script processing
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
free_buffer_stuff(buf, kBffInitChangedtick); // delete local vars et al.
|
free_buffer_stuff(buf, kBffInitChangedtick); // delete local vars et al.
|
||||||
|
|
||||||
// Init the options.
|
// Init the options.
|
||||||
@ -4855,6 +4846,10 @@ void do_arg_all(int count, int forceit, int keep_tabs)
|
|||||||
if (keep_tabs) {
|
if (keep_tabs) {
|
||||||
new_curwin = wp;
|
new_curwin = wp;
|
||||||
new_curtab = curtab;
|
new_curtab = curtab;
|
||||||
|
} else if (wp->w_frame->fr_parent != curwin->w_frame->fr_parent) {
|
||||||
|
emsg(_("E249: window layout changed unexpectedly"));
|
||||||
|
i = count;
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
win_move_after(wp, curwin);
|
win_move_after(wp, curwin);
|
||||||
}
|
}
|
||||||
|
@ -532,6 +532,8 @@ struct file_buffer {
|
|||||||
int b_flags; // various BF_ flags
|
int b_flags; // various BF_ flags
|
||||||
int b_locked; // Buffer is being closed or referenced, don't
|
int b_locked; // Buffer is being closed or referenced, don't
|
||||||
// let autocommands wipe it out.
|
// let autocommands wipe it out.
|
||||||
|
int b_locked_split; // Buffer is being closed, don't allow opening
|
||||||
|
// a new window with it.
|
||||||
int b_ro_locked; // Non-zero when the buffer can't be changed.
|
int b_ro_locked; // Non-zero when the buffer can't be changed.
|
||||||
// Used for FileChangedRO
|
// Used for FileChangedRO
|
||||||
|
|
||||||
|
@ -2497,16 +2497,19 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
|
|||||||
if (buf->b_fname != NULL) {
|
if (buf->b_fname != NULL) {
|
||||||
new_name = vim_strsave(buf->b_fname);
|
new_name = vim_strsave(buf->b_fname);
|
||||||
}
|
}
|
||||||
|
const bufref_T save_au_new_curbuf = au_new_curbuf;
|
||||||
set_bufref(&au_new_curbuf, buf);
|
set_bufref(&au_new_curbuf, buf);
|
||||||
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
|
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
|
||||||
cmdwin_type = save_cmdwin_type;
|
cmdwin_type = save_cmdwin_type;
|
||||||
if (!bufref_valid(&au_new_curbuf)) {
|
if (!bufref_valid(&au_new_curbuf)) {
|
||||||
// New buffer has been deleted.
|
// New buffer has been deleted.
|
||||||
delbuf_msg(new_name); // Frees new_name.
|
delbuf_msg(new_name); // Frees new_name.
|
||||||
|
au_new_curbuf = save_au_new_curbuf;
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (aborting()) { // autocmds may abort script processing
|
if (aborting()) { // autocmds may abort script processing
|
||||||
xfree(new_name);
|
xfree(new_name);
|
||||||
|
au_new_curbuf = save_au_new_curbuf;
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (buf == curbuf) { // already in new buffer
|
if (buf == curbuf) { // already in new buffer
|
||||||
@ -2540,12 +2543,14 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
|
|||||||
// autocmds may abort script processing
|
// autocmds may abort script processing
|
||||||
if (aborting() && curwin->w_buffer != NULL) {
|
if (aborting() && curwin->w_buffer != NULL) {
|
||||||
xfree(new_name);
|
xfree(new_name);
|
||||||
|
au_new_curbuf = save_au_new_curbuf;
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
// Be careful again, like above.
|
// Be careful again, like above.
|
||||||
if (!bufref_valid(&au_new_curbuf)) {
|
if (!bufref_valid(&au_new_curbuf)) {
|
||||||
// New buffer has been deleted.
|
// New buffer has been deleted.
|
||||||
delbuf_msg(new_name); // Frees new_name.
|
delbuf_msg(new_name); // Frees new_name.
|
||||||
|
au_new_curbuf = save_au_new_curbuf;
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (buf == curbuf) { // already in new buffer
|
if (buf == curbuf) { // already in new buffer
|
||||||
@ -2585,8 +2590,7 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
|
|||||||
did_get_winopts = true;
|
did_get_winopts = true;
|
||||||
}
|
}
|
||||||
xfree(new_name);
|
xfree(new_name);
|
||||||
au_new_curbuf.br_buf = NULL;
|
au_new_curbuf = save_au_new_curbuf;
|
||||||
au_new_curbuf.br_buf_free_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curwin->w_pcmark.lnum = 1;
|
curwin->w_pcmark.lnum = 1;
|
||||||
|
@ -6376,6 +6376,7 @@ static int open_cmdwin(void)
|
|||||||
// Create a window for the command-line buffer.
|
// Create a window for the command-line buffer.
|
||||||
if (win_split((int)p_cwh, WSP_BOT) == FAIL) {
|
if (win_split((int)p_cwh, WSP_BOT) == FAIL) {
|
||||||
beep_flush();
|
beep_flush();
|
||||||
|
ga_clear(&winsizes);
|
||||||
return K_IGNORE;
|
return K_IGNORE;
|
||||||
}
|
}
|
||||||
cmdwin_type = get_cmdline_type();
|
cmdwin_type = get_cmdline_type();
|
||||||
|
@ -2313,7 +2313,10 @@ static bool qflist_valid(win_T *wp, unsigned int qf_id)
|
|||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = &ql_info;
|
||||||
|
|
||||||
if (wp) {
|
if (wp) {
|
||||||
qi = GET_LOC_LIST(wp);
|
if (!win_valid(wp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
qi = GET_LOC_LIST(wp); // Location list
|
||||||
if (!qi) {
|
if (!qi) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2695,9 +2695,9 @@ func Test_autocmd_closes_window()
|
|||||||
au BufNew,BufWinLeave * e %e
|
au BufNew,BufWinLeave * e %e
|
||||||
file yyy
|
file yyy
|
||||||
au BufNew,BufWinLeave * ball
|
au BufNew,BufWinLeave * ball
|
||||||
call assert_fails('n xxx', 'E143:')
|
n xxx
|
||||||
|
|
||||||
bwipe %
|
%bwipe
|
||||||
au! BufNew
|
au! BufNew
|
||||||
au! BufWinLeave
|
au! BufWinLeave
|
||||||
endfunc
|
endfunc
|
||||||
@ -2713,9 +2713,34 @@ func Test_autocmd_quit_psearch()
|
|||||||
augroup aucmd_win_test
|
augroup aucmd_win_test
|
||||||
au!
|
au!
|
||||||
augroup END
|
augroup END
|
||||||
|
new
|
||||||
|
pclose
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Fuzzer found some strange combination that caused a crash.
|
||||||
|
func Test_autocmd_normal_mess()
|
||||||
|
" For unknown reason this hangs on MS-Windows
|
||||||
|
CheckNotMSWindows
|
||||||
|
|
||||||
|
augroup aucmd_normal_test
|
||||||
|
au BufLeave,BufWinLeave,BufHidden,BufUnload,BufDelete,BufWipeout * norm 7q/qc
|
||||||
|
augroup END
|
||||||
|
" Nvim has removed :open
|
||||||
|
" call assert_fails('o4', 'E1159')
|
||||||
|
call assert_fails('e4', 'E1159')
|
||||||
|
silent! H
|
||||||
|
call assert_fails('e xx', 'E1159')
|
||||||
|
normal G
|
||||||
|
|
||||||
|
augroup aucmd_normal_test
|
||||||
|
au!
|
||||||
|
augroup END
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_autocmd_closing_cmdwin()
|
func Test_autocmd_closing_cmdwin()
|
||||||
|
" For unknown reason this hangs on MS-Windows
|
||||||
|
CheckNotMSWindows
|
||||||
|
|
||||||
au BufWinLeave * nested q
|
au BufWinLeave * nested q
|
||||||
call assert_fails("norm 7q?\n", 'E855:')
|
call assert_fails("norm 7q?\n", 'E855:')
|
||||||
|
|
||||||
@ -2724,6 +2749,20 @@ func Test_autocmd_closing_cmdwin()
|
|||||||
only
|
only
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_autocmd_vimgrep()
|
||||||
|
augroup aucmd_vimgrep
|
||||||
|
au QuickfixCmdPre,BufNew,BufReadCmd * sb
|
||||||
|
" Nvim makes aucmd_win the last window
|
||||||
|
" au QuickfixCmdPre,BufNew,BufReadCmd * q9
|
||||||
|
au QuickfixCmdPre,BufNew,BufReadCmd * exe 'q' .. (winnr('$') - (win_gettype(winnr('$')) == 'autocmd'))
|
||||||
|
augroup END
|
||||||
|
call assert_fails('lv ?a? foo', 'E926:')
|
||||||
|
|
||||||
|
augroup aucmd_vimgrep
|
||||||
|
au!
|
||||||
|
augroup END
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_bufwipeout_changes_window()
|
func Test_bufwipeout_changes_window()
|
||||||
" This should not crash, but we don't have any expectations about what
|
" This should not crash, but we don't have any expectations about what
|
||||||
" happens, changing window in BufWipeout has unpredictable results.
|
" happens, changing window in BufWipeout has unpredictable results.
|
||||||
@ -2759,4 +2798,22 @@ func Test_v_event_readonly()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_noname_autocmd()
|
||||||
|
augroup test_noname_autocmd_group
|
||||||
|
autocmd!
|
||||||
|
autocmd BufEnter * call add(s:li, ["BufEnter", expand("<afile>")])
|
||||||
|
autocmd BufDelete * call add(s:li, ["BufDelete", expand("<afile>")])
|
||||||
|
autocmd BufLeave * call add(s:li, ["BufLeave", expand("<afile>")])
|
||||||
|
autocmd BufUnload * call add(s:li, ["BufUnload", expand("<afile>")])
|
||||||
|
autocmd BufWipeout * call add(s:li, ["BufWipeout", expand("<afile>")])
|
||||||
|
augroup END
|
||||||
|
|
||||||
|
let s:li = []
|
||||||
|
edit foo
|
||||||
|
call assert_equal([['BufUnload', ''], ['BufDelete', ''], ['BufWipeout', ''], ['BufEnter', 'foo']], s:li)
|
||||||
|
|
||||||
|
au! test_noname_autocmd_group
|
||||||
|
augroup! test_noname_autocmd_group
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -513,14 +513,15 @@ func Test_window_colon_command()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_access_freed_mem()
|
func Test_access_freed_mem()
|
||||||
|
call assert_equal(&columns, winwidth(0))
|
||||||
" This was accessing freed memory (but with what events?)
|
" This was accessing freed memory (but with what events?)
|
||||||
au BufEnter,BufLeave,WinEnter,WinLeave 0 vs xxx
|
au BufEnter,BufLeave,WinEnter,WinLeave 0 vs xxx
|
||||||
arg 0
|
arg 0
|
||||||
argadd
|
argadd
|
||||||
all
|
call assert_fails("all", "E242:")
|
||||||
all
|
|
||||||
au!
|
au!
|
||||||
bwipe xxx
|
bwipe xxx
|
||||||
|
call assert_equal(&columns, winwidth(0))
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_visual_cleared_after_window_split()
|
func Test_visual_cleared_after_window_split()
|
||||||
|
@ -72,8 +72,40 @@ typedef enum {
|
|||||||
WEE_TRIGGER_LEAVE_AUTOCMDS = 0x10,
|
WEE_TRIGGER_LEAVE_AUTOCMDS = 0x10,
|
||||||
} wee_flags_T;
|
} wee_flags_T;
|
||||||
|
|
||||||
|
static char e_cannot_split_window_when_closing_buffer[]
|
||||||
|
= N_("E1159: Cannot split a window when closing the buffer");
|
||||||
|
|
||||||
static char *m_onlyone = N_("Already only one window");
|
static char *m_onlyone = N_("Already only one window");
|
||||||
|
|
||||||
|
/// When non-zero splitting a window is forbidden. Used to avoid that nasty
|
||||||
|
/// autocommands mess up the window structure.
|
||||||
|
static int split_disallowed = 0;
|
||||||
|
|
||||||
|
// #define WIN_DEBUG
|
||||||
|
#ifdef WIN_DEBUG
|
||||||
|
/// Call this method to log the current window layout.
|
||||||
|
static void log_frame_layout(frame_T *frame)
|
||||||
|
{
|
||||||
|
DLOG("layout %s, wi: %d, he: %d, wwi: %d, whe: %d, id: %d",
|
||||||
|
frame->fr_layout == FR_LEAF ? "LEAF" : frame->fr_layout == FR_ROW ? "ROW" : "COL",
|
||||||
|
frame->fr_width,
|
||||||
|
frame->fr_height,
|
||||||
|
frame->fr_win == NULL ? -1 : frame->fr_win->w_width,
|
||||||
|
frame->fr_win == NULL ? -1 : frame->fr_win->w_height,
|
||||||
|
frame->fr_win == NULL ? -1 : frame->fr_win->w_id);
|
||||||
|
if (frame->fr_child != NULL) {
|
||||||
|
DLOG("children");
|
||||||
|
log_frame_layout(frame->fr_child);
|
||||||
|
if (frame->fr_next != NULL) {
|
||||||
|
DLOG("END of children");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (frame->fr_next != NULL) {
|
||||||
|
log_frame_layout(frame->fr_next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @return the current window, unless in the cmdline window and "prevwin" is
|
/// @return the current window, unless in the cmdline window and "prevwin" is
|
||||||
/// set, then return "prevwin".
|
/// set, then return "prevwin".
|
||||||
win_T *prevwin_curwin(void)
|
win_T *prevwin_curwin(void)
|
||||||
@ -909,6 +941,21 @@ void ui_ext_win_viewport(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If "split_disallowed" is set given an error and return FAIL.
|
||||||
|
/// Otherwise return OK.
|
||||||
|
static int check_split_disallowed(void)
|
||||||
|
{
|
||||||
|
if (split_disallowed > 0) {
|
||||||
|
emsg(_("E242: Can't split a window while closing another"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
if (curwin->w_buffer->b_locked_split) {
|
||||||
|
emsg(_(e_cannot_split_window_when_closing_buffer));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* split the current window, implements CTRL-W s and :split
|
* split the current window, implements CTRL-W s and :split
|
||||||
*
|
*
|
||||||
@ -926,6 +973,10 @@ void ui_ext_win_viewport(win_T *wp)
|
|||||||
*/
|
*/
|
||||||
int win_split(int size, int flags)
|
int win_split(int size, int flags)
|
||||||
{
|
{
|
||||||
|
if (check_split_disallowed() == FAIL) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
// When the ":tab" modifier was used open a new tab page instead.
|
// When the ":tab" modifier was used open a new tab page instead.
|
||||||
if (may_open_tabpage() == OK) {
|
if (may_open_tabpage() == OK) {
|
||||||
return OK;
|
return OK;
|
||||||
@ -1886,6 +1937,9 @@ static void win_totop(int size, int flags)
|
|||||||
if (curwin == aucmd_win) {
|
if (curwin == aucmd_win) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (check_split_disallowed() == FAIL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (curwin->w_floating) {
|
if (curwin->w_floating) {
|
||||||
ui_comp_remove_grid(&curwin->w_grid_alloc);
|
ui_comp_remove_grid(&curwin->w_grid_alloc);
|
||||||
@ -1929,6 +1983,11 @@ void win_move_after(win_T *win1, win_T *win2)
|
|||||||
|
|
||||||
// check if there is something to do
|
// check if there is something to do
|
||||||
if (win2->w_next != win1) {
|
if (win2->w_next != win1) {
|
||||||
|
if (win1->w_frame->fr_parent != win2->w_frame->fr_parent) {
|
||||||
|
iemsg("INTERNAL: trying to move a window into another frame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// may need move the status line, horizontal or vertical separator of the last window
|
// may need move the status line, horizontal or vertical separator of the last window
|
||||||
if (win1 == lastwin) {
|
if (win1 == lastwin) {
|
||||||
height = win1->w_prev->w_status_height;
|
height = win1->w_prev->w_status_height;
|
||||||
@ -2742,6 +2801,10 @@ int win_close(win_T *win, bool free_buf, bool force)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now we are really going to close the window. Disallow any autocommand
|
||||||
|
// to split a window to avoid trouble.
|
||||||
|
split_disallowed++;
|
||||||
|
|
||||||
// let terminal buffers know that this window dimensions may be ignored
|
// let terminal buffers know that this window dimensions may be ignored
|
||||||
win->w_closing = true;
|
win->w_closing = true;
|
||||||
|
|
||||||
@ -2809,6 +2872,8 @@ int win_close(win_T *win, bool free_buf, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
split_disallowed--;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If last window has a status line now and we don't want one,
|
* If last window has a status line now and we don't want one,
|
||||||
* remove the status line.
|
* remove the status line.
|
||||||
|
@ -60,6 +60,23 @@ describe('autocmd', function()
|
|||||||
eq(expected, eval('g:evs'))
|
eq(expected, eval('g:evs'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('first edit causes BufUnload on NoName', function()
|
||||||
|
local expected = {
|
||||||
|
{'BufUnload', ''},
|
||||||
|
{'BufDelete', ''},
|
||||||
|
{'BufWipeout', ''},
|
||||||
|
{'BufEnter', 'testfile1'},
|
||||||
|
}
|
||||||
|
command('let g:evs = []')
|
||||||
|
command('autocmd BufEnter * :call add(g:evs, ["BufEnter", expand("<afile>")])')
|
||||||
|
command('autocmd BufDelete * :call add(g:evs, ["BufDelete", expand("<afile>")])')
|
||||||
|
command('autocmd BufLeave * :call add(g:evs, ["BufLeave", expand("<afile>")])')
|
||||||
|
command('autocmd BufUnload * :call add(g:evs, ["BufUnload", expand("<afile>")])')
|
||||||
|
command('autocmd BufWipeout * :call add(g:evs, ["BufWipeout", expand("<afile>")])')
|
||||||
|
command('edit testfile1')
|
||||||
|
eq(expected, eval('g:evs'))
|
||||||
|
end)
|
||||||
|
|
||||||
it('WinClosed is non-recursive', function()
|
it('WinClosed is non-recursive', function()
|
||||||
command('let g:triggered = 0')
|
command('let g:triggered = 0')
|
||||||
command('autocmd WinClosed * :let g:triggered+=1 | :bdelete 2')
|
command('autocmd WinClosed * :let g:triggered+=1 | :bdelete 2')
|
||||||
@ -548,18 +565,6 @@ describe('autocmd', function()
|
|||||||
neq({}, meths.get_autocmds { group = "filetypedetect" })
|
neq({}, meths.get_autocmds { group = "filetypedetect" })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('should not access freed mem', function()
|
|
||||||
source [[
|
|
||||||
au BufEnter,BufLeave,WinEnter,WinLeave 0 vs xxx
|
|
||||||
arg 0
|
|
||||||
argadd
|
|
||||||
all
|
|
||||||
all
|
|
||||||
au!
|
|
||||||
bwipe xxx
|
|
||||||
]]
|
|
||||||
end)
|
|
||||||
|
|
||||||
it('should allow comma-separated patterns', function()
|
it('should allow comma-separated patterns', function()
|
||||||
source [[
|
source [[
|
||||||
augroup TestingPatterns
|
augroup TestingPatterns
|
||||||
|
Loading…
Reference in New Issue
Block a user