0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 9.0.0061: ml_get error with nested autocommand

Problem:    ml_get error with nested autocommand.
Solution:   Also check line numbers for a nested autocommand. (closes #10761)
This commit is contained in:
Bram Moolenaar 2022-07-23 09:06:48 +01:00
parent b9e717367c
commit 5fa9f23a63
5 changed files with 57 additions and 10 deletions

View File

@ -2209,9 +2209,13 @@ apply_autocmds_group(
ap->last = FALSE; ap->last = FALSE;
ap->last = TRUE; ap->last = TRUE;
// Make sure cursor and topline are valid. The first time the current
// values are saved, restored by reset_lnums(). When nested only the
// values are corrected when needed.
if (nesting == 1) if (nesting == 1)
// make sure cursor and topline are valid
check_lnums(TRUE); check_lnums(TRUE);
else
check_lnums_nested(TRUE);
save_did_emsg = did_emsg; save_did_emsg = did_emsg;

View File

@ -77,6 +77,7 @@ int tabline_height(void);
int min_rows(void); int min_rows(void);
int only_one_window(void); int only_one_window(void);
void check_lnums(int do_curwin); void check_lnums(int do_curwin);
void check_lnums_nested(int do_curwin);
void reset_lnums(void); void reset_lnums(void);
void make_snapshot(int idx); void make_snapshot(int idx);
void restore_snapshot(int idx, int close_curwin); void restore_snapshot(int idx, int close_curwin);

View File

@ -2301,6 +2301,25 @@ func Test_autocmd_nested()
call assert_fails('au WinNew * nested nested echo bad', 'E983:') call assert_fails('au WinNew * nested nested echo bad', 'E983:')
endfunc endfunc
func Test_autocmd_nested_cursor_invalid()
set laststatus=0
copen
cclose
call setline(1, ['foo', 'bar', 'baz'])
3
augroup nested_inv
autocmd User foo ++nested copen
autocmd BufAdd * let &laststatus = 2 - &laststatus
augroup END
doautocmd User foo
augroup nested_inv
au!
augroup END
set laststatus&
bwipe!
endfunc
func Test_autocmd_once() func Test_autocmd_once()
" Without ++once WinNew triggers twice " Without ++once WinNew triggers twice
let g:did_split = 0 let g:did_split = 0

View File

@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
61,
/**/ /**/
60, 60,
/**/ /**/

View File

@ -6770,34 +6770,55 @@ only_one_window(void)
} }
/* /*
* Correct the cursor line number in other windows. Used after changing the * Implementation of check_lnums() and check_lnums_nested().
* current buffer, and before applying autocommands.
* When "do_curwin" is TRUE, also check current window.
*/ */
void static void
check_lnums(int do_curwin) check_lnums_both(int do_curwin, int nested)
{ {
win_T *wp; win_T *wp;
tabpage_T *tp; tabpage_T *tp;
FOR_ALL_TAB_WINDOWS(tp, wp) FOR_ALL_TAB_WINDOWS(tp, wp)
if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf)
{
if (!nested)
{ {
// save the original cursor position and topline // save the original cursor position and topline
wp->w_save_cursor.w_cursor_save = wp->w_cursor; wp->w_save_cursor.w_cursor_save = wp->w_cursor;
wp->w_save_cursor.w_topline_save = wp->w_topline; wp->w_save_cursor.w_topline_save = wp->w_topline;
}
if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count) if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count)
wp->w_cursor.lnum = curbuf->b_ml.ml_line_count; wp->w_cursor.lnum = curbuf->b_ml.ml_line_count;
if (wp->w_topline > curbuf->b_ml.ml_line_count) if (wp->w_topline > curbuf->b_ml.ml_line_count)
wp->w_topline = curbuf->b_ml.ml_line_count; wp->w_topline = curbuf->b_ml.ml_line_count;
// save the corrected cursor position and topline // save the (corrected) cursor position and topline
wp->w_save_cursor.w_cursor_corr = wp->w_cursor; wp->w_save_cursor.w_cursor_corr = wp->w_cursor;
wp->w_save_cursor.w_topline_corr = wp->w_topline; wp->w_save_cursor.w_topline_corr = wp->w_topline;
} }
} }
/*
* Correct the cursor line number in other windows. Used after changing the
* current buffer, and before applying autocommands.
* When "do_curwin" is TRUE, also check current window.
*/
void
check_lnums(int do_curwin)
{
check_lnums_both(do_curwin, FALSE);
}
/*
* Like check_lnums() but for when check_lnums() was already called.
*/
void
check_lnums_nested(int do_curwin)
{
check_lnums_both(do_curwin, TRUE);
}
/* /*
* Reset cursor and topline to its stored values from check_lnums(). * Reset cursor and topline to its stored values from check_lnums().
* check_lnums() must have been called first! * check_lnums() must have been called first!