mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.1.2294: cursor pos wrong with concealing and search causes a scroll
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 vim/vim#5215, closes vim/vim#5012)
cbee635eee
This commit is contained in:
parent
d5bc62a5ce
commit
910bbc3cca
@ -698,8 +698,10 @@ static void win_update(win_T *wp)
|
||||
int didline = FALSE; /* if TRUE, we finished the last line */
|
||||
int i;
|
||||
long j;
|
||||
static int recursive = FALSE; /* being called recursively */
|
||||
int old_botline = wp->w_botline;
|
||||
static bool recursive = false; // being called recursively
|
||||
const linenr_T old_botline = wp->w_botline;
|
||||
const int old_wrow = wp->w_wrow;
|
||||
const int old_wcol = wp->w_wcol;
|
||||
// Remember what happened to the previous line.
|
||||
#define DID_NONE 1 // didn't update a line
|
||||
#define DID_LINE 2 // updated a normal line
|
||||
@ -1639,18 +1641,51 @@ static void win_update(win_T *wp)
|
||||
wp->w_valid |= VALID_BOTLINE;
|
||||
wp->w_viewport_invalid = true;
|
||||
if (wp == curwin && wp->w_botline != old_botline && !recursive) {
|
||||
recursive = TRUE;
|
||||
const linenr_T old_topline = wp->w_topline;
|
||||
const int new_wcol = wp->w_wcol;
|
||||
recursive = true;
|
||||
curwin->w_valid &= ~VALID_TOPLINE;
|
||||
update_topline(); /* may invalidate w_botline again */
|
||||
if (must_redraw != 0) {
|
||||
/* Don't update for changes in buffer again. */
|
||||
update_topline(); // may invalidate w_botline again
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
recursive = FALSE;
|
||||
// Other windows might have w_redr_type raised in update_topline().
|
||||
must_redraw = 0;
|
||||
FOR_ALL_WINDOWS_IN_TAB(wwp, curtab) {
|
||||
if (wwp->w_redr_type > must_redraw) {
|
||||
must_redraw = wwp->w_redr_type;
|
||||
}
|
||||
}
|
||||
recursive = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
" Test for matchadd() and conceal feature
|
||||
if !has('conceal')
|
||||
finish
|
||||
endif
|
||||
|
||||
source check.vim
|
||||
CheckFeature conceal
|
||||
|
||||
source shared.vim
|
||||
source term_util.vim
|
||||
source view_util.vim
|
||||
|
||||
function! Test_simple_matchadd()
|
||||
new
|
||||
@ -273,3 +275,40 @@ function! Test_matchadd_and_syn_conceal()
|
||||
call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
|
||||
call assert_equal(screenattr(1, 11) , screenattr(1, 32))
|
||||
endfunction
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user