summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-11-12 20:49:15 +0100
committerBram Moolenaar <Bram@vim.org>2019-11-12 20:49:15 +0100
commitcbee635eee3007db97646ddb9f211a1d4966eb2a (patch)
tree93384534e8cc5e6bcaa416213cf2fd2fd7ce8ea6
parentcc184cfb09161b3bbc7d5d8859a18e812367d19c (diff)
downloadvim-git-8.1.2294.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.c44
-rw-r--r--src/testdir/test_matchadd_conceal.vim39
-rw-r--r--src/version.c2
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,