# HG changeset patch # User Bram Moolenaar # Date 1554377405 -7200 # Node ID 5fb0f15fafea657a561c4afea4b23b215cc5c464 # Parent 4ef3771aa5e2012384bd6d9b327ec9c33fcc9838 patch 8.1.1110: composing chars on space wrong when 'listchars' is set commit https://github.com/vim/vim/commit/e5e4e22c1c15c8c22b14935affe969569acc8df9 Author: Bram Moolenaar Date: Thu Apr 4 13:28:45 2019 +0200 patch 8.1.1110: composing chars on space wrong when 'listchars' is set Problem: Composing chars on space wrong when 'listchars' is set. Solution: Do not use "space" and "nbsp" entries of 'listchars' when there is a composing character. (Yee Cheng Chin, closes #4197) diff --git a/src/screen.c b/src/screen.c --- a/src/screen.c +++ b/src/screen.c @@ -4808,34 +4808,36 @@ win_line( } #endif - // 'list': change char 160 to lcs_nbsp and space to lcs_space. - if (wp->w_p_list) - { - if ((c == 160 - || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f))) - && lcs_nbsp) + // 'list': Change char 160 to lcs_nbsp and space to lcs_space. + // But not when the character is followed by a composing + // character (use mb_l to check that). + if (wp->w_p_list + && ((((c == 160 && mb_l == 1) + || (mb_utf8 + && ((mb_c == 160 && mb_l == 2) + || (mb_c == 0x202f && mb_l == 3)))) + && lcs_nbsp) + || (c == ' ' + && mb_l == 1 + && lcs_space + && ptr - line <= trailcol))) + { + c = (c == ' ') ? lcs_space : lcs_nbsp; + if (area_attr == 0 && search_attr == 0) { - c = lcs_nbsp; - mb_c = c; - if (enc_utf8 && utf_char2len(c) > 1) - { - mb_utf8 = TRUE; - u8cc[0] = 0; - c = 0xc0; - } - else - mb_utf8 = FALSE; + n_attr = 1; + extra_attr = HL_ATTR(HLF_8); + saved_attr2 = char_attr; /* save current attr */ } - else if (c == ' ' && lcs_space && ptr - line <= trailcol) + mb_c = c; + if (enc_utf8 && utf_char2len(c) > 1) { - c = lcs_space; - if (mb_utf8 == FALSE && area_attr == 0 && search_attr == 0) - { - n_attr = 1; - extra_attr = HL_ATTR(HLF_8); - saved_attr2 = char_attr; // save current attr - } + mb_utf8 = TRUE; + u8cc[0] = 0; + c = 0xc0; } + else + mb_utf8 = FALSE; } if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') diff --git a/src/testdir/test_listchars.vim b/src/testdir/test_listchars.vim --- a/src/testdir/test_listchars.vim +++ b/src/testdir/test_listchars.vim @@ -114,6 +114,33 @@ func Test_listchars() set listchars& ff& endfunc +" Test that unicode listchars characters get properly inserted +func Test_listchars_unicode() + enew! + let oldencoding=&encoding + set encoding=utf-8 + set ff=unix + + set listchars=eol:⇔,space:␣,nbsp:≠,tab:←↔→ + set list + + let nbsp = nr2char(0xa0) + call append(0, [ + \ "a\tb c".nbsp."d" + \ ]) + let expected = [ + \ 'a←↔↔↔↔↔→b␣c≠d⇔' + \ ] + redraw! + call cursor(1, 1) + call assert_equal(expected, ScreenLines(1, virtcol('$'))) + let &encoding=oldencoding + enew! + set listchars& ff& +endfunction + +" Tests that space characters following composing character won't get replaced +" by listchars. func Test_listchars_composing() enew! let oldencoding=&encoding @@ -121,18 +148,20 @@ func Test_listchars_composing() set ff=unix set list - set listchars=eol:$,space:_ + set listchars=eol:$,space:_,nbsp:= + + let nbsp1 = nr2char(0xa0) + let nbsp2 = nr2char(0x202f) call append(0, [ - \ " \u3099 \u309A" + \ " \u3099\t \u309A".nbsp1.nbsp1."\u0302".nbsp2.nbsp2."\u0302", \ ]) let expected = [ - \ "_ \u3099^I \u309A$" + \ "_ \u3099^I \u309A=".nbsp1."\u0302=".nbsp2."\u0302$" \ ] redraw! call cursor(1, 1) - let got = ScreenLines(1, virtcol('$')) - bw! - call assert_equal(expected, got) + call assert_equal(expected, ScreenLines(1, virtcol('$'))) let &encoding=oldencoding + enew! set listchars& ff& endfunction diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -772,6 +772,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1110, +/**/ 1109, /**/ 1108,