Skip to content

Commit 5fa9f23

Browse files
committed
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)
1 parent b9e7173 commit 5fa9f23

File tree

5 files changed

+57
-10
lines changed

5 files changed

+57
-10
lines changed

src/autocmd.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2209,9 +2209,13 @@ apply_autocmds_group(
22092209
ap->last = FALSE;
22102210
ap->last = TRUE;
22112211

2212+
// Make sure cursor and topline are valid. The first time the current
2213+
// values are saved, restored by reset_lnums(). When nested only the
2214+
// values are corrected when needed.
22122215
if (nesting == 1)
2213-
// make sure cursor and topline are valid
22142216
check_lnums(TRUE);
2217+
else
2218+
check_lnums_nested(TRUE);
22152219

22162220
save_did_emsg = did_emsg;
22172221

src/proto/window.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ int tabline_height(void);
7777
int min_rows(void);
7878
int only_one_window(void);
7979
void check_lnums(int do_curwin);
80+
void check_lnums_nested(int do_curwin);
8081
void reset_lnums(void);
8182
void make_snapshot(int idx);
8283
void restore_snapshot(int idx, int close_curwin);

src/testdir/test_autocmd.vim

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,6 +2301,25 @@ func Test_autocmd_nested()
23012301
call assert_fails('au WinNew * nested nested echo bad', 'E983:')
23022302
endfunc
23032303

2304+
func Test_autocmd_nested_cursor_invalid()
2305+
set laststatus=0
2306+
copen
2307+
cclose
2308+
call setline(1, ['foo', 'bar', 'baz'])
2309+
3
2310+
augroup nested_inv
2311+
autocmd User foo ++nested copen
2312+
autocmd BufAdd * let &laststatus = 2 - &laststatus
2313+
augroup END
2314+
doautocmd User foo
2315+
2316+
augroup nested_inv
2317+
au!
2318+
augroup END
2319+
set laststatus&
2320+
bwipe!
2321+
endfunc
2322+
23042323
func Test_autocmd_once()
23052324
" Without ++once WinNew triggers twice
23062325
let g:did_split = 0

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,8 @@ static char *(features[]) =
735735

736736
static int included_patches[] =
737737
{ /* Add new patch number below this line */
738+
/**/
739+
61,
738740
/**/
739741
60,
740742
/**/

src/window.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6770,34 +6770,55 @@ only_one_window(void)
67706770
}
67716771

67726772
/*
6773-
* Correct the cursor line number in other windows. Used after changing the
6774-
* current buffer, and before applying autocommands.
6775-
* When "do_curwin" is TRUE, also check current window.
6773+
* Implementation of check_lnums() and check_lnums_nested().
67766774
*/
6777-
void
6778-
check_lnums(int do_curwin)
6775+
static void
6776+
check_lnums_both(int do_curwin, int nested)
67796777
{
67806778
win_T *wp;
67816779
tabpage_T *tp;
67826780

67836781
FOR_ALL_TAB_WINDOWS(tp, wp)
67846782
if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf)
67856783
{
6786-
// save the original cursor position and topline
6787-
wp->w_save_cursor.w_cursor_save = wp->w_cursor;
6788-
wp->w_save_cursor.w_topline_save = wp->w_topline;
6784+
if (!nested)
6785+
{
6786+
// save the original cursor position and topline
6787+
wp->w_save_cursor.w_cursor_save = wp->w_cursor;
6788+
wp->w_save_cursor.w_topline_save = wp->w_topline;
6789+
}
67896790

67906791
if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count)
67916792
wp->w_cursor.lnum = curbuf->b_ml.ml_line_count;
67926793
if (wp->w_topline > curbuf->b_ml.ml_line_count)
67936794
wp->w_topline = curbuf->b_ml.ml_line_count;
67946795

6795-
// save the corrected cursor position and topline
6796+
// save the (corrected) cursor position and topline
67966797
wp->w_save_cursor.w_cursor_corr = wp->w_cursor;
67976798
wp->w_save_cursor.w_topline_corr = wp->w_topline;
67986799
}
67996800
}
68006801

6802+
/*
6803+
* Correct the cursor line number in other windows. Used after changing the
6804+
* current buffer, and before applying autocommands.
6805+
* When "do_curwin" is TRUE, also check current window.
6806+
*/
6807+
void
6808+
check_lnums(int do_curwin)
6809+
{
6810+
check_lnums_both(do_curwin, FALSE);
6811+
}
6812+
6813+
/*
6814+
* Like check_lnums() but for when check_lnums() was already called.
6815+
*/
6816+
void
6817+
check_lnums_nested(int do_curwin)
6818+
{
6819+
check_lnums_both(do_curwin, TRUE);
6820+
}
6821+
68016822
/*
68026823
* Reset cursor and topline to its stored values from check_lnums().
68036824
* check_lnums() must have been called first!

0 commit comments

Comments
 (0)