summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-10-16 17:51:40 +0100
committerBram Moolenaar <Bram@vim.org>2021-10-16 17:51:40 +0100
commit93ff6720fe4427341bc426b6d46e6324f226c270 (patch)
tree59206daf1e304747723c5e4fcc8cabd16b3c310e
parentabdcfd1c837e244065d4fe04c7a78abae5af3f7e (diff)
downloadvim-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.txt7
-rw-r--r--src/charset.c3
-rw-r--r--src/screen.c39
-rw-r--r--src/testdir/test_listchars.vim4
-rw-r--r--src/version.c2
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,