]> granicus.if.org Git - vim/commitdiff
patch 8.2.3522: cannot use \x and \u when setting 'listchars' v8.2.3522
authorBram Moolenaar <Bram@vim.org>
Sat, 16 Oct 2021 16:51:40 +0000 (17:51 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 16 Oct 2021 16:51:40 +0000 (17:51 +0100)
Problem:    Cannot use \x and \u when setting 'listchars'.
Solution:   Support hex and unicode in hex form. (closes #9006)

runtime/doc/options.txt
src/charset.c
src/screen.c
src/testdir/test_listchars.vim
src/version.c

index 67504795b6abb9c73004d607a1a040a6a87f1494..735e1c1f936ed2cd2ca58551963da415b2c87798 100644 (file)
@@ -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:%
index fcaeedf75770b014bc9b18c8daf1c0c92354a3c1..2c46f7ad04c0578b933c692dd5d3c5b9799f8f36 100644 (file)
@@ -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.
index 88775862d6d6cad5c28d82599d49f89f8b8f5437..78d7ef7d71270c58fa6f02ee433b735fd7bef2de 100644 (file)
@@ -4776,6 +4776,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.
@@ -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;
                        }
index 4cbd3650b496e5355c3086e90e4b3a24b99c6671..cb947aa84bf6d450a8b57a69dac614c8a4ded9d8 100644 (file)
@@ -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!
index 16e49ac4c1d5318a4c30cf4cb1645d92135d19f7..1b6e997bfa795645349665e4daa1415e95c7bffe 100644 (file)
@@ -757,6 +757,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3522,
 /**/
     3521,
 /**/