diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-10-16 17:51:40 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-10-16 17:51:40 +0100 |
commit | 93ff6720fe4427341bc426b6d46e6324f226c270 (patch) | |
tree | 59206daf1e304747723c5e4fcc8cabd16b3c310e | |
parent | abdcfd1c837e244065d4fe04c7a78abae5af3f7e (diff) | |
download | vim-git-93ff6720fe4427341bc426b6d46e6324f226c270.tar.gz |
patch 8.2.3522: cannot use \x and \u when setting 'listchars'v8.2.3522
Problem: Cannot use \x and \u when setting 'listchars'.
Solution: Support hex and unicode in hex form. (closes #9006)
-rw-r--r-- | runtime/doc/options.txt | 7 | ||||
-rw-r--r-- | src/charset.c | 3 | ||||
-rw-r--r-- | src/screen.c | 39 | ||||
-rw-r--r-- | src/testdir/test_listchars.vim | 4 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 47 insertions, 8 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 67504795b..735e1c1f9 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4978,6 +4978,13 @@ A jump table for the options with a short description can be found at |Q_op|. be used when 'encoding' is "utf-8", otherwise only printable characters are allowed. All characters must be single width. + Each character can be specified as hex: > + set listchars=eol:\\x24 + set listchars=eol:\\u21b5 + set listchars=eol:\\U000021b5 +< Note that a double backslash is used. The number of hex characters + must be exactly 2 for \\x, 4 for \\u and 8 for \\U. + Examples: > :set lcs=tab:>-,trail:- :set lcs=tab:>-,eol:<,nbsp:% diff --git a/src/charset.c b/src/charset.c index fcaeedf75..2c46f7ad0 100644 --- a/src/charset.c +++ b/src/charset.c @@ -2013,8 +2013,6 @@ hex2nr(int c) return c - '0'; } -#if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) \ - || defined(PROTO) || defined(FEAT_AUTOSHELLDIR) /* * Convert two hex characters to a byte. * Return -1 if one of the characters is not hex. @@ -2026,7 +2024,6 @@ hexhex2nr(char_u *p) return -1; return (hex2nr(p[0]) << 4) + hex2nr(p[1]); } -#endif /* * Return TRUE if "str" starts with a backslash that should be removed. diff --git a/src/screen.c b/src/screen.c index 88775862d..78d7ef7d7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -4777,6 +4777,35 @@ screen_screenrow(void) #endif /* + * Calls mb_ptr2char_adv(p) and returns the character. + * If "p" starts with "\x", "\u" or "\U" the hex or unicode value is used. + */ + static int +get_encoded_char_adv(char_u **p) +{ + char_u *s = *p; + + if (s[0] == '\\' && (s[1] == 'x' || s[1] == 'u' || s[1] == 'U')) + { + varnumber_T num = 0; + int bytes; + int n; + + for (bytes = s[1] == 'x' ? 1 : s[1] == 'u' ? 2 : 4; bytes > 0; --bytes) + { + *p += 2; + n = hexhex2nr(*p); + if (n < 0) + return 0; + num = num * 256 + n; + } + *p += 2; + return num; + } + return mb_ptr2char_adv(p); +} + +/* * Handle setting 'listchars' or 'fillchars'. * Assume monocell characters. * Returns error message, NULL if it's OK. @@ -4884,19 +4913,19 @@ set_chars_option(win_T *wp, char_u **varp) { c2 = c3 = 0; s = p + len + 1; - c1 = mb_ptr2char_adv(&s); + c1 = get_encoded_char_adv(&s); if (mb_char2cells(c1) > 1) return e_invarg; if (tab[i].cp == &lcs_chars.tab2) { if (*s == NUL) return e_invarg; - c2 = mb_ptr2char_adv(&s); + c2 = get_encoded_char_adv(&s); if (mb_char2cells(c2) > 1) return e_invarg; if (!(*s == ',' || *s == NUL)) { - c3 = mb_ptr2char_adv(&s); + c3 = get_encoded_char_adv(&s); if (mb_char2cells(c3) > 1) return e_invarg; } @@ -4938,7 +4967,7 @@ set_chars_option(win_T *wp, char_u **varp) multispace_len = 0; while (*s != NUL && *s != ',') { - c1 = mb_ptr2char_adv(&s); + c1 = get_encoded_char_adv(&s); if (mb_char2cells(c1) > 1) return e_invarg; ++multispace_len; @@ -4954,7 +4983,7 @@ set_chars_option(win_T *wp, char_u **varp) while (*s != NUL && *s != ',') { - c1 = mb_ptr2char_adv(&s); + c1 = get_encoded_char_adv(&s); if (p == last_multispace) lcs_chars.multispace[multispace_pos++] = c1; } diff --git a/src/testdir/test_listchars.vim b/src/testdir/test_listchars.vim index 4cbd3650b..cb947aa84 100644 --- a/src/testdir/test_listchars.vim +++ b/src/testdir/test_listchars.vim @@ -288,6 +288,10 @@ func Test_listchars_unicode() call cursor(1, 1) call assert_equal(expected, ScreenLines(1, virtcol('$'))) + set listchars=eol:\\u21d4,space:\\u2423,multispace:≡\\u2262\\U00002263,nbsp:\\U00002260,tab:←↔\\u2192 + redraw! + call assert_equal(expected, ScreenLines(1, virtcol('$'))) + set listchars+=lead:⇨,trail:⇦ let expected = ['⇨⇨⇨⇨⇨⇨⇨⇨a←↔↔↔↔↔→b␣c≠d⇦⇦⇔'] redraw! diff --git a/src/version.c b/src/version.c index 16e49ac4c..1b6e997bf 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3522, +/**/ 3521, /**/ 3520, |