Skip to content

Commit 1077230

Browse files
committed
patch 8.1.0786: ml_get error when updating the status line
Problem: ml_get error when updating the status line and a terminal had its scrollback cleared. (Chris Patuzzo) Solution: Check the cursor position when drawing the status line. (closes #3830)
1 parent 113e107 commit 1077230

3 files changed

Lines changed: 53 additions & 6 deletions

File tree

src/buffer.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3869,6 +3869,8 @@ build_stl_str_hl(
38693869
struct stl_hlrec *hltab, /* return: HL attributes (can be NULL) */
38703870
struct stl_hlrec *tabtab) /* return: tab page nrs (can be NULL) */
38713871
{
3872+
linenr_T lnum;
3873+
size_t len;
38723874
char_u *p;
38733875
char_u *s;
38743876
char_u *t;
@@ -3943,15 +3945,33 @@ build_stl_str_hl(
39433945
fillchar = '-';
39443946
#endif
39453947

3946-
/* Get line & check if empty (cursorpos will show "0-1"). Note that
3947-
* p will become invalid when getting another buffer line. */
3948-
p = ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE);
3948+
// The cursor in windows other than the current one isn't always
3949+
// up-to-date, esp. because of autocommands and timers.
3950+
lnum = wp->w_cursor.lnum;
3951+
if (lnum > wp->w_buffer->b_ml.ml_line_count)
3952+
{
3953+
lnum = wp->w_buffer->b_ml.ml_line_count;
3954+
wp->w_cursor.lnum = lnum;
3955+
}
3956+
3957+
// Get line & check if empty (cursorpos will show "0-1"). Note that
3958+
// p will become invalid when getting another buffer line.
3959+
p = ml_get_buf(wp->w_buffer, lnum, FALSE);
39493960
empty_line = (*p == NUL);
39503961

3951-
/* Get the byte value now, in case we need it below. This is more
3952-
* efficient than making a copy of the line. */
3953-
if (wp->w_cursor.col > (colnr_T)STRLEN(p))
3962+
// Get the byte value now, in case we need it below. This is more efficient
3963+
// than making a copy of the line.
3964+
len = STRLEN(p);
3965+
if (wp->w_cursor.col > (colnr_T)len)
3966+
{
3967+
// Line may have changed since checking the cursor column, or the lnum
3968+
// was adjusted above.
3969+
wp->w_cursor.col = (colnr_T)len;
3970+
#ifdef FEAT_VIRTUALEDIT
3971+
wp->w_cursor.coladd = 0;
3972+
#endif
39543973
byteval = 0;
3974+
}
39553975
else
39563976
#ifdef FEAT_MBYTE
39573977
byteval = (*mb_ptr2char)(p + wp->w_cursor.col);

src/testdir/test_terminal.vim

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,3 +1719,28 @@ func Test_term_gettitle()
17191719

17201720
exe term . 'bwipe!'
17211721
endfunc
1722+
1723+
" When drawing the statusline the cursor position may not have been updated
1724+
" yet.
1725+
" 1. create a terminal, make it show 2 lines
1726+
" 2. 0.5 sec later: leave terminal window, execute "i"
1727+
" 3. 0.5 sec later: clear terminal window, now it's 1 line
1728+
" 4. 0.5 sec later: redraw, including statusline (used to trigger bug)
1729+
" 4. 0.5 sec later: should be done, clean up
1730+
func Test_terminal_statusline()
1731+
if !has('unix')
1732+
return
1733+
endif
1734+
set statusline=x
1735+
terminal
1736+
let tbuf = bufnr('')
1737+
call term_sendkeys(tbuf, "clear; echo a; echo b; sleep 1; clear\n")
1738+
call timer_start(500, { tid -> feedkeys("\<C-w>j", 'tx') })
1739+
call timer_start(1500, { tid -> feedkeys("\<C-l>", 'tx') })
1740+
au BufLeave * if &buftype == 'terminal' | silent! normal i | endif
1741+
1742+
sleep 2
1743+
exe tbuf . 'bwipe!'
1744+
au! BufLeave
1745+
set statusline=
1746+
endfunc

src/version.c

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

792792
static int included_patches[] =
793793
{ /* Add new patch number below this line */
794+
/**/
795+
786,
794796
/**/
795797
785,
796798
/**/

0 commit comments

Comments
 (0)