# HG changeset patch # User Bram Moolenaar # Date 1660306504 -7200 # Node ID d97b2ce2625879172cb63889780c7387274d4b51 # Parent 325f7101453d246ea2e3a6a34f9cf5aa7a9dfd51 patch 9.0.0194: cursor displayed in wrong position after removing text prop Commit: https://github.com/vim/vim/commit/326c5d36e7cb8526330565109c17b4a13ff790ae Author: Bram Moolenaar Date: Fri Aug 12 13:05:49 2022 +0100 patch 9.0.0194: cursor displayed in wrong position after removing text prop Problem: Cursor displayed in wrong position after removing text prop. (Ben Jackson) Solution: Invalidate the cursor position. (closes #10898) diff --git a/src/change.c b/src/change.c --- a/src/change.c +++ b/src/change.c @@ -801,6 +801,7 @@ deleted_lines_mark(linenr_T lnum, long c /* * Marks the area to be redrawn after a change. + * Consider also calling changed_line_display_buf(). */ void changed_lines_buf( diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -594,6 +594,22 @@ changed_line_abv_curs_win(win_T *wp) } /* + * Display of line has changed for "buf", invalidate cursor position and + * w_botline. + */ + void +changed_line_display_buf(buf_T *buf) +{ + win_T *wp; + + FOR_ALL_WINDOWS(wp) + if (wp->w_buffer == buf) + wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL + |VALID_CROW|VALID_CHEIGHT + |VALID_TOPLINE|VALID_BOTLINE|VALID_BOTLINE_AP); +} + +/* * Make sure the value of curwin->w_botline is valid. */ void diff --git a/src/proto/move.pro b/src/proto/move.pro --- a/src/proto/move.pro +++ b/src/proto/move.pro @@ -11,6 +11,7 @@ void changed_cline_bef_curs(void); void changed_cline_bef_curs_win(win_T *wp); void changed_line_abv_curs(void); void changed_line_abv_curs_win(win_T *wp); +void changed_line_display_buf(buf_T *buf); void validate_botline(void); void validate_botline_win(win_T *wp); void invalidate_botline(void); diff --git a/src/testdir/dumps/Test_prop_with_text_cursormoved_1.dump b/src/testdir/dumps/Test_prop_with_text_cursormoved_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_cursormoved_1.dump @@ -0,0 +1,8 @@ +|t+0&#ffffff0|h|i|s| >i|s| |l|i|n|e| |o|n|e|x+0#ffffff16#ff404010@43 +@60 +@16| +0#0000000#ffffff0@43 +|t|h|i|s| |i|s| |l|i|n|e| |t|w|o| @43 +|t|h|r|e@1| @54 +|f|o|u|r| @55 +|f|i|v|e| @55 +@42|1|,|6| @10|A|l@1| diff --git a/src/testdir/dumps/Test_prop_with_text_cursormoved_2.dump b/src/testdir/dumps/Test_prop_with_text_cursormoved_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_cursormoved_2.dump @@ -0,0 +1,8 @@ +|t+0&#ffffff0|h|i|s| |i|s| |l|i|n|e| |o|n|e| @43 +|t|h|i|s| >i|s| |l|i|n|e| |t|w|o| @43 +|t|h|r|e@1| @54 +|f|o|u|r| @55 +|f|i|v|e| @55 +|~+0#4040ff13&| @58 +|~| @58 +| +0#0000000&@41|2|,|6| @10|A|l@1| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2775,6 +2775,45 @@ func Test_props_with_text_below_nowrap() call delete('XscriptPropsBelowNowrap') endfunc +func Test_props_with_text_CursorMoved() + CheckRunVimInTerminal + + let lines =<< trim END + call setline(1, ['this is line one', 'this is line two', 'three', 'four', 'five']) + + call prop_type_add('prop', #{highlight: 'Error'}) + let g:long_text = repeat('x', &columns * 2) + + let g:prop_id = v:null + func! Update() + if line('.') == 1 + if g:prop_id == v:null + let g:prop_id = prop_add(1, 0, #{type: 'prop', text_wrap: 'wrap', text: g:long_text}) + endif + elseif g:prop_id != v:null + call prop_remove(#{id: g:prop_id}) + let g:prop_id = v:null + endif + endfunc + + autocmd CursorMoved * call Update() + END + call writefile(lines, 'XscriptPropsCursorMovec') + let buf = RunVimInTerminal('-S XscriptPropsCursorMovec', #{rows: 8, cols: 60}) + call term_sendkeys(buf, "gg0w") + call VerifyScreenDump(buf, 'Test_prop_with_text_cursormoved_1', {}) + + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_prop_with_text_cursormoved_2', {}) + + " back to the first state + call term_sendkeys(buf, "k") + call VerifyScreenDump(buf, 'Test_prop_with_text_cursormoved_1', {}) + + call StopVimInTerminal(buf) + call delete('XscriptPropsCursorMovec') +endfunc + func Test_props_with_text_after_split_join() CheckRunVimInTerminal diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -310,6 +310,7 @@ prop_add_one( buf->b_ml.ml_flags |= ML_LINE_DIRTY; } + changed_line_display_buf(buf); changed_lines_buf(buf, start_lnum, end_lnum + 1, 0); res = OK; @@ -1507,6 +1508,7 @@ f_prop_remove(typval_T *argvars, typval_ if (first_changed > 0) { + changed_line_display_buf(buf); changed_lines_buf(buf, first_changed, last_changed + 1, 0); redraw_buf_later(buf, VALID); } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -736,6 +736,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 194, +/**/ 193, /**/ 192,