To: vim_dev@googlegroups.com Subject: Patch 8.2.3522 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3522 Problem: Cannot use \x and \u when setting 'listchars'. Solution: Support hex and unicode in hex form. (closes #9006) Files: runtime/doc/options.txt, src/screen.c, src/charset.c, src/testdir/test_listchars.vim *** ../vim-8.2.3521/runtime/doc/options.txt 2021-10-16 15:41:25.378336694 +0100 --- runtime/doc/options.txt 2021-10-16 17:49:21.274245711 +0100 *************** *** 4966,4977 **** be used when 'encoding' is "utf-8", otherwise only printable characters are allowed. All characters must be single width. Examples: > :set lcs=tab:>-,trail:- :set lcs=tab:>-,eol:<,nbsp:% :set lcs=extends:>,precedes:< < The "NonText" highlighting will be used for "eol", "extends" and ! "precedes". "SpecialKey" for "nbsp", "space", "tab" and "trail". |hl-NonText| |hl-SpecialKey| *'lpl'* *'nolpl'* *'loadplugins'* *'noloadplugins'* --- 4978,4997 ---- 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:% :set lcs=extends:>,precedes:< < The "NonText" highlighting will be used for "eol", "extends" and ! "precedes". "SpecialKey" will be used for "tab", "nbsp", "space", ! "multispace", "lead" and "trail". |hl-NonText| |hl-SpecialKey| *'lpl'* *'nolpl'* *'loadplugins'* *'noloadplugins'* *** ../vim-8.2.3521/src/screen.c 2021-09-13 21:17:33.946410682 +0100 --- src/screen.c 2021-10-16 17:44:17.281607376 +0100 *************** *** 4777,4782 **** --- 4777,4811 ---- #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,4902 **** { c2 = c3 = 0; s = p + len + 1; ! c1 = mb_ptr2char_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); if (mb_char2cells(c2) > 1) return e_invarg; if (!(*s == ',' || *s == NUL)) { ! c3 = mb_ptr2char_adv(&s); if (mb_char2cells(c3) > 1) return e_invarg; } --- 4913,4931 ---- { c2 = c3 = 0; s = p + len + 1; ! 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 = get_encoded_char_adv(&s); if (mb_char2cells(c2) > 1) return e_invarg; if (!(*s == ',' || *s == NUL)) { ! c3 = get_encoded_char_adv(&s); if (mb_char2cells(c3) > 1) return e_invarg; } *************** *** 4938,4944 **** multispace_len = 0; while (*s != NUL && *s != ',') { ! c1 = mb_ptr2char_adv(&s); if (mb_char2cells(c1) > 1) return e_invarg; ++multispace_len; --- 4967,4973 ---- multispace_len = 0; while (*s != NUL && *s != ',') { ! c1 = get_encoded_char_adv(&s); if (mb_char2cells(c1) > 1) return e_invarg; ++multispace_len; *************** *** 4954,4960 **** while (*s != NUL && *s != ',') { ! c1 = mb_ptr2char_adv(&s); if (p == last_multispace) lcs_chars.multispace[multispace_pos++] = c1; } --- 4983,4989 ---- while (*s != NUL && *s != ',') { ! c1 = get_encoded_char_adv(&s); if (p == last_multispace) lcs_chars.multispace[multispace_pos++] = c1; } *** ../vim-8.2.3521/src/charset.c 2021-05-18 20:46:27.708961290 +0100 --- src/charset.c 2021-10-16 17:12:53.278414682 +0100 *************** *** 2013,2020 **** 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. --- 2013,2018 ---- *************** *** 2026,2032 **** return -1; return (hex2nr(p[0]) << 4) + hex2nr(p[1]); } - #endif /* * Return TRUE if "str" starts with a backslash that should be removed. --- 2024,2029 ---- *** ../vim-8.2.3521/src/testdir/test_listchars.vim 2021-09-10 15:58:24.446743066 +0100 --- src/testdir/test_listchars.vim 2021-10-16 17:45:21.094588809 +0100 *************** *** 288,293 **** --- 288,297 ---- 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! *** ../vim-8.2.3521/src/version.c 2021-10-16 16:48:23.651196150 +0100 --- src/version.c 2021-10-16 17:49:30.154380002 +0100 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3522, /**/ -- Did you ever see a "Hit any key to continue" message in a music piece? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///