Skip to content

Commit

Permalink
patch 8.2.3522: cannot use \x and \u when setting 'listchars'
Browse files Browse the repository at this point in the history
Problem:    Cannot use \x and \u when setting 'listchars'.
Solution:   Support hex and unicode in hex form. (closes #9006)
  • Loading branch information
brammool committed Oct 16, 2021
1 parent abdcfd1 commit 93ff672
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 8 deletions.
7 changes: 7 additions & 0 deletions runtime/doc/options.txt
Expand Up @@ -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:%
Expand Down
3 changes: 0 additions & 3 deletions src/charset.c
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
39 changes: 34 additions & 5 deletions src/screen.c
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions src/testdir/test_listchars.vim
Expand Up @@ -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!
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -757,6 +757,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3522,
/**/
3521,
/**/
Expand Down

1 comment on commit 93ff672

@jdhao
Copy link

@jdhao jdhao commented on 93ff672 Oct 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this prompt fix! 👍

Please sign in to comment.