summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-06-03 19:45:06 +0100
committerBram Moolenaar <Bram@vim.org>2023-06-03 19:45:06 +0100
commitecb87dd7d3f7b9291092a7dd8fae1e59b9903252 (patch)
tree1deda588e0f24488bb553b4a33f93527cff42d8a
parent664fd12aa27a3c6bd19cfa474c4630d6c03fcc61 (diff)
patch 9.0.1602: stray character visible if marker on top of double-wide charv9.0.1602
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 #12469)
-rw-r--r--src/drawline.c5
-rw-r--r--src/testdir/dumps/Test_smooth_marker_over_double_width_1.dump6
-rw-r--r--src/testdir/dumps/Test_smooth_marker_over_double_width_2.dump6
-rw-r--r--src/testdir/test_scroll_opt.vim58
-rw-r--r--src/version.c2
5 files changed, 77 insertions, 0 deletions
diff --git a/src/drawline.c b/src/drawline.c
index 2b15f9a3f3..2fbfe452cd 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -823,6 +823,7 @@ wlv_screen_line(win_T *wp, winlinevars_T *wlv, int negative_width)
&& !(wp->w_p_list && wp->w_lcs_chars.prec != 0))
{
int off = (int)(current_ScreenLine - ScreenLines);
+ int max_off = off + screen_Columns;
int skip = 0;
if (wp->w_p_nu && wp->w_p_rnu)
@@ -836,6 +837,10 @@ wlv_screen_line(win_T *wp, winlinevars_T *wlv, int negative_width)
for (int i = 0; i < 3 && i + skip < wp->w_width; ++i)
{
+ if ((*mb_off2cells)(off, max_off) > 1)
+ // When the first half of a double-width character is
+ // overwritten, change the second half to a space.
+ ScreenLines[off + 1] = ' ';
ScreenLines[off] = '<';
if (enc_utf8)
ScreenLinesUC[off] = 0;
diff --git a/src/testdir/dumps/Test_smooth_marker_over_double_width_1.dump b/src/testdir/dumps/Test_smooth_marker_over_double_width_1.dump
new file mode 100644
index 0000000000..e02ae58d0f
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_marker_over_double_width_1.dump
@@ -0,0 +1,6 @@
+>a+0&#ffffff0@39
+|口*&@9| +&@19
+|~+0#4040ff13&| @38
+|~| @38
+|~| @38
+| +0#0000000&@21|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_smooth_marker_over_double_width_2.dump b/src/testdir/dumps/Test_smooth_marker_over_double_width_2.dump
new file mode 100644
index 0000000000..737038aeab
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_marker_over_double_width_2.dump
@@ -0,0 +1,6 @@
+|<+0#4040ff13#ffffff0@2| +0#0000000&|口*&@6>口| +&@19
+|~+0#4040ff13&| @38
+|~| @38
+|~| @38
+|~| @38
+| +0#0000000&@21|1|,|6|8|-|5|9| @6|A|l@1|
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 648060bd58..7a95e6fecf 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -399,6 +399,64 @@ func Test_smoothscroll_long_line_showbreak()
call StopVimInTerminal(buf)
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
+ 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)
call assert_equal(a:win_col, wincol())
call assert_equal(a:win_line, winline())
diff --git a/src/version.c b/src/version.c
index e373686ab5..a724b7ccfa 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1602,
+/**/
1601,
/**/
1600,