diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-11-12 20:49:15 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-11-12 20:49:15 +0100 |
commit | cbee635eee3007db97646ddb9f211a1d4966eb2a (patch) | |
tree | 93384534e8cc5e6bcaa416213cf2fd2fd7ce8ea6 | |
parent | cc184cfb09161b3bbc7d5d8859a18e812367d19c (diff) | |
download | vim-git-cbee635eee3007db97646ddb9f211a1d4966eb2a.tar.gz |
patch 8.1.2294: cursor pos wrong with concealing and search causes a scrollv8.1.2294
Problem: Cursor position wrong when characters are concealed and asearch
causes a scroll.
Solution: Fix the cursor column in a concealed line after window scroll.
(closes #5215, closes #5012)
-rw-r--r-- | src/drawscreen.c | 44 | ||||
-rw-r--r-- | src/testdir/test_matchadd_conceal.vim | 39 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 82 insertions, 3 deletions
diff --git a/src/drawscreen.c b/src/drawscreen.c index 275925727..de0fc6b97 100644 --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -1398,7 +1398,11 @@ win_update(win_T *wp) int i; long j; static int recursive = FALSE; // being called recursively - int old_botline = wp->w_botline; + linenr_T old_botline = wp->w_botline; +#ifdef FEAT_CONCEAL + int old_wrow = wp->w_wrow; + int old_wcol = wp->w_wcol; +#endif #ifdef FEAT_FOLDING long fold_count; #endif @@ -2567,18 +2571,52 @@ win_update(win_T *wp) wp->w_valid |= VALID_BOTLINE; if (wp == curwin && wp->w_botline != old_botline && !recursive) { + win_T *wwp; +#if defined(FEAT_CONCEAL) + linenr_T old_topline = wp->w_topline; + int new_wcol = wp->w_wcol; +#endif recursive = TRUE; curwin->w_valid &= ~VALID_TOPLINE; update_topline(); // may invalidate w_botline again - if (must_redraw != 0) + +#if defined(FEAT_CONCEAL) + if (old_wcol != new_wcol && (wp->w_valid & (VALID_WCOL|VALID_WROW)) + != (VALID_WCOL|VALID_WROW)) + { + // A win_line() call applied a fix to screen cursor column to + // accomodate concealment of cursor line, but in this call to + // update_topline() the cursor's row or column got invalidated. + // If they are left invalid, setcursor() will recompute them + // but there won't be any further win_line() call to re-fix the + // column and the cursor will end up misplaced. So we call + // cursor validation now and reapply the fix again (or call + // win_line() to do it for us). + validate_cursor(); + if (wp->w_wcol == old_wcol && wp->w_wrow == old_wrow + && old_topline == wp->w_topline) + wp->w_wcol = new_wcol; + else + redrawWinline(wp, wp->w_cursor.lnum); + } +#endif + // New redraw either due to updated topline or due to wcol fix. + if (wp->w_redr_type != 0) { // Don't update for changes in buffer again. i = curbuf->b_mod_set; curbuf->b_mod_set = FALSE; + j = curbuf->b_mod_xlines; + curbuf->b_mod_xlines = 0; win_update(curwin); - must_redraw = 0; curbuf->b_mod_set = i; + curbuf->b_mod_xlines = j; } + // Other windows might have w_redr_type raised in update_topline(). + must_redraw = 0; + FOR_ALL_WINDOWS(wwp) + if (wwp->w_redr_type > must_redraw) + must_redraw = wwp->w_redr_type; recursive = FALSE; } } diff --git a/src/testdir/test_matchadd_conceal.vim b/src/testdir/test_matchadd_conceal.vim index 6684378f6..83eadce5a 100644 --- a/src/testdir/test_matchadd_conceal.vim +++ b/src/testdir/test_matchadd_conceal.vim @@ -8,6 +8,8 @@ if !has('gui_running') && has('unix') endif source shared.vim +source term_util.vim +source view_util.vim func Test_simple_matchadd() new @@ -277,3 +279,40 @@ func Test_matchadd_and_syn_conceal() call assert_notequal(screenattr(1, 11) , screenattr(1, 12)) call assert_equal(screenattr(1, 11) , screenattr(1, 32)) endfunc + +func Test_cursor_column_in_concealed_line_after_window_scroll() + CheckRunVimInTerminal + + " Test for issue #5012 fix. + " For a concealed line with cursor, there should be no window's cursor + " position invalidation during win_update() after scrolling attempt that is + " not successful and no real topline change happens. The invalidation would + " cause a window's cursor position recalc outside of win_line() where it's + " not possible to take conceal into account. + let lines =<< trim END + 3split + let m = matchadd('Conceal', '=') + setl conceallevel=2 concealcursor=nc + normal gg + "==expr== + END + call writefile(lines, 'Xcolesearch') + let buf = RunVimInTerminal('Xcolesearch', {}) + + " Jump to something that is beyond the bottom of the window, + " so there's a scroll down. + call term_sendkeys(buf, ":so %\<CR>") + call term_sendkeys(buf, "/expr\<CR>") + call term_wait(buf) + + " Are the concealed parts of the current line really hidden? + let cursor_row = term_scrape(buf, '.')->map({_, e -> e.chars})->join('') + call assert_equal('"expr', cursor_row) + + " BugFix check: Is the window's cursor column properly updated for hidden + " parts of the current line? + call assert_equal(2, term_getcursor(buf)[1]) + + call StopVimInTerminal(buf) + call delete('Xcolesearch') +endfunc diff --git a/src/version.c b/src/version.c index 31133c53e..e147ac301 100644 --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2294, +/**/ 2293, /**/ 2292, |