mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:9.0.1602: stray character visible if marker on top of double-wide char (#23897)
Problem: Stray character is visible if 'smoothscroll' marker is displayed
on top of a double-wide character.
Solution: When overwriting a double-width character with the 'smoothscroll'
marker clear the second half. (closes vim/vim#12469)
ecb87dd7d3
This commit is contained in:
parent
0a439e3863
commit
53f30de2be
@ -500,8 +500,6 @@ static int grid_char_needs_redraw(ScreenGrid *grid, size_t off_from, size_t off_
|
|||||||
void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int clear_width,
|
void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int clear_width,
|
||||||
int rlflag, win_T *wp, int bg_attr, bool wrap)
|
int rlflag, win_T *wp, int bg_attr, bool wrap)
|
||||||
{
|
{
|
||||||
size_t max_off_from;
|
|
||||||
size_t max_off_to;
|
|
||||||
int col = 0;
|
int col = 0;
|
||||||
bool redraw_next; // redraw_this for next character
|
bool redraw_next; // redraw_this for next character
|
||||||
bool clear_next = false;
|
bool clear_next = false;
|
||||||
@ -519,6 +517,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
endcol = grid->cols;
|
endcol = grid->cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t max_off_from = (size_t)grid->cols;
|
||||||
grid_adjust(&grid, &row, &coloff);
|
grid_adjust(&grid, &row, &coloff);
|
||||||
|
|
||||||
// Safety check. Avoids clang warnings down the call stack.
|
// Safety check. Avoids clang warnings down the call stack.
|
||||||
@ -529,8 +528,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
|
|
||||||
size_t off_from = 0;
|
size_t off_from = 0;
|
||||||
size_t off_to = grid->line_offset[row] + (size_t)coloff;
|
size_t off_to = grid->line_offset[row] + (size_t)coloff;
|
||||||
max_off_from = linebuf_size;
|
const size_t max_off_to = grid->line_offset[row] + (size_t)grid->cols;
|
||||||
max_off_to = grid->line_offset[row] + (size_t)grid->cols;
|
|
||||||
|
|
||||||
// Take care of putting "<<<" on the first line for 'smoothscroll'.
|
// Take care of putting "<<<" on the first line for 'smoothscroll'.
|
||||||
if (topline && wp->w_skipcol > 0
|
if (topline && wp->w_skipcol > 0
|
||||||
@ -538,18 +536,23 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
&& *get_showbreak_value(wp) == NUL
|
&& *get_showbreak_value(wp) == NUL
|
||||||
// do not overwrite the 'listchars' "precedes" text with "<<<"
|
// do not overwrite the 'listchars' "precedes" text with "<<<"
|
||||||
&& !(wp->w_p_list && wp->w_p_lcs_chars.prec != 0)) {
|
&& !(wp->w_p_list && wp->w_p_lcs_chars.prec != 0)) {
|
||||||
int off = 0;
|
size_t off = 0;
|
||||||
int skip = 0;
|
size_t skip = 0;
|
||||||
if (wp->w_p_nu && wp->w_p_rnu) {
|
if (wp->w_p_nu && wp->w_p_rnu) {
|
||||||
// do not overwrite the line number, change "123 text" to
|
// do not overwrite the line number, change "123 text" to
|
||||||
// "123>>>xt".
|
// "123>>>xt".
|
||||||
while (skip < wp->w_width_inner && ascii_isdigit(*linebuf_char[off])) {
|
while (skip < max_off_from && ascii_isdigit(*linebuf_char[off])) {
|
||||||
off++;
|
off++;
|
||||||
skip++;
|
skip++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3 && i + skip < wp->w_width_inner; i++) {
|
for (size_t i = 0; i < 3 && i + skip < max_off_from; i++) {
|
||||||
|
if (line_off2cells(linebuf_char, off, max_off_from) > 1) {
|
||||||
|
// When the first half of a double-width character is
|
||||||
|
// overwritten, change the second half to a space.
|
||||||
|
schar_from_ascii(linebuf_char[off + 1], ' ');
|
||||||
|
}
|
||||||
schar_from_ascii(linebuf_char[off], '<');
|
schar_from_ascii(linebuf_char[off], '<');
|
||||||
linebuf_attr[off] = HL_ATTR(HLF_AT);
|
linebuf_attr[off] = HL_ATTR(HLF_AT);
|
||||||
off++;
|
off++;
|
||||||
|
@ -667,6 +667,32 @@ describe('smoothscroll', function()
|
|||||||
screen:expect(s1)
|
screen:expect(s1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- oldtest: Test_smoothscroll_marker_over_double_width_dump()
|
||||||
|
it('marker is drawn over double-width char correctly', function()
|
||||||
|
screen:try_resize(40, 6)
|
||||||
|
exec([[
|
||||||
|
call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
|
||||||
|
setlocal smoothscroll
|
||||||
|
]])
|
||||||
|
screen:expect([[
|
||||||
|
^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||||
|
口口口口口口口口口口 |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
feed('<C-E>')
|
||||||
|
screen:expect([[
|
||||||
|
<<< 口口口口口口口^口 |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
-- oldtest: Test_smoothscroll_zero_width()
|
-- oldtest: Test_smoothscroll_zero_width()
|
||||||
it("does not divide by zero with a narrow window", function()
|
it("does not divide by zero with a narrow window", function()
|
||||||
screen:try_resize(12, 2)
|
screen:try_resize(12, 2)
|
||||||
|
@ -399,6 +399,67 @@ func Test_smoothscroll_long_line_showbreak()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Check that 'smoothscroll' marker is drawn over double-width char correctly.
|
||||||
|
" Run with multiple encodings.
|
||||||
|
func Test_smoothscroll_marker_over_double_width()
|
||||||
|
" Run this in a separate Vim instance to avoid messing up.
|
||||||
|
let after =<< trim [CODE]
|
||||||
|
scriptencoding utf-8
|
||||||
|
call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
|
||||||
|
setlocal smoothscroll
|
||||||
|
redraw
|
||||||
|
exe "norm \<C-E>"
|
||||||
|
redraw
|
||||||
|
" Check the chars one by one. Don't check the whole line concatenated.
|
||||||
|
call assert_equal('<', screenstring(1, 1))
|
||||||
|
call assert_equal('<', screenstring(1, 2))
|
||||||
|
call assert_equal('<', screenstring(1, 3))
|
||||||
|
call assert_equal(' ', screenstring(1, 4))
|
||||||
|
call assert_equal('口', screenstring(1, 5))
|
||||||
|
call assert_equal('口', screenstring(1, 7))
|
||||||
|
call assert_equal('口', screenstring(1, 9))
|
||||||
|
call assert_equal('口', screenstring(1, 11))
|
||||||
|
call assert_equal('口', screenstring(1, 13))
|
||||||
|
call assert_equal('口', screenstring(1, 15))
|
||||||
|
call writefile(v:errors, 'Xresult')
|
||||||
|
qall!
|
||||||
|
[CODE]
|
||||||
|
|
||||||
|
let encodings = ['utf-8', 'cp932', 'cp936', 'cp949', 'cp950']
|
||||||
|
if !has('win32')
|
||||||
|
let encodings += ['euc-jp']
|
||||||
|
endif
|
||||||
|
if has('nvim')
|
||||||
|
let encodings = ['utf-8']
|
||||||
|
endif
|
||||||
|
for enc in encodings
|
||||||
|
let msg = 'enc=' .. enc
|
||||||
|
if RunVim([], after, $'--clean --cmd "set encoding={enc}"')
|
||||||
|
call assert_equal([], readfile('Xresult'), msg)
|
||||||
|
endif
|
||||||
|
call delete('Xresult')
|
||||||
|
endfor
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Same as the test above, but check the text actually shown on screen.
|
||||||
|
" Only run with UTF-8 encoding.
|
||||||
|
func Test_smoothscroll_marker_over_double_width_dump()
|
||||||
|
CheckScreendump
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
|
||||||
|
setlocal smoothscroll
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XSmoothMarkerOverDoubleWidth', 'D')
|
||||||
|
let buf = RunVimInTerminal('-S XSmoothMarkerOverDoubleWidth', #{rows: 6, cols: 40})
|
||||||
|
call VerifyScreenDump(buf, 'Test_smooth_marker_over_double_width_1', {})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "\<C-E>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_smooth_marker_over_double_width_2', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
func s:check_col_calc(win_col, win_line, buf_col)
|
func s:check_col_calc(win_col, win_line, buf_col)
|
||||||
call assert_equal(a:win_col, wincol())
|
call assert_equal(a:win_col, wincol())
|
||||||
call assert_equal(a:win_line, winline())
|
call assert_equal(a:win_line, winline())
|
||||||
|
Loading…
Reference in New Issue
Block a user