summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <bram@vim.org>2013-01-17 17:02:05 +0100
committerBram Moolenaar <bram@vim.org>2013-01-17 17:02:05 +0100
commitc6ec467b2fb13fd7656af5653af1164a6b95a64b (patch)
tree79d4ef914c5014b66230d7768e37f7391814f188
parent10c47df9f3b464dfc6e514461364d18fdcea62f6 (diff)
downloadvim-c6ec467b2fb13fd7656af5653af1164a6b95a64b.tar.gz
updated for version 7.3.769v7.3.769v7-3-769
Problem: 'matchpairs' does not work with multi-byte characters. Solution: Make it work. (Christian Brabandt)
-rw-r--r--src/misc1.c12
-rw-r--r--src/option.c142
-rw-r--r--src/proto/option.pro1
-rw-r--r--src/search.c70
-rw-r--r--src/testdir/test69.in10
-rw-r--r--src/testdir/test69.ok4
-rw-r--r--src/version.c2
7 files changed, 176 insertions, 65 deletions
diff --git a/src/misc1.c b/src/misc1.c
index 636fc4a0..ab42f04d 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2288,14 +2288,18 @@ ins_char_bytes(buf, charlen)
*/
if (p_sm && (State & INSERT)
&& msg_silent == 0
-#ifdef FEAT_MBYTE
- && charlen == 1
-#endif
#ifdef FEAT_INS_EXPAND
&& !ins_compl_active()
#endif
)
- showmatch(c);
+ {
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ showmatch(mb_ptr2char(buf));
+ else
+#endif
+ showmatch(c);
+ }
#ifdef FEAT_RIGHTLEFT
if (!p_ri || (State & REPLACE_FLAG))
diff --git a/src/option.c b/src/option.c
index d8eb314d..8f524060 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6149,16 +6149,46 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
/* 'matchpairs' */
else if (gvarp == &p_mps)
{
- /* Check for "x:y,x:y" */
- for (p = *varp; *p != NUL; p += 4)
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
{
- if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
+ for (p = *varp; *p != NUL; ++p)
{
- errmsg = e_invarg;
- break;
+ int x2,x3 = -1;
+
+ if (*p != NUL)
+ p += mb_ptr2len(p);
+ if (*p != NUL)
+ x2 = *p++;
+ if (*p != NUL)
+ {
+ x3 = mb_ptr2char(p);
+ p += mb_ptr2len(p);
+ }
+ if (x2 != ':' || x2 == -1 || x3 == -1
+ || (*p != NUL && *p != ','))
+ {
+ errmsg = e_invarg;
+ break;
+ }
+ if (*p == NUL)
+ break;
+ }
+ }
+ else
+#endif
+ {
+ /* Check for "x:y,x:y" */
+ for (p = *varp; *p != NUL; p += 4)
+ {
+ if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
+ {
+ errmsg = e_invarg;
+ break;
+ }
+ if (p[3] == NUL)
+ break;
}
- if (p[3] == NUL)
- break;
}
}
@@ -11453,3 +11483,101 @@ get_sts_value()
{
return curbuf->b_p_sts < 0 ? get_sw_value() : curbuf->b_p_sts;
}
+
+/*
+ * Check matchpairs option for "*initc".
+ * If there is a match set "*initc" to the matching character and "*findc" to
+ * the opposite character. Set "*backwards" to the direction.
+ * When "switchit" is TRUE swap the direction.
+ */
+ void
+find_mps_values(initc, findc, backwards, switchit)
+ int *initc;
+ int *findc;
+ int *backwards;
+ int switchit;
+{
+ char_u *ptr;
+
+ ptr = curbuf->b_p_mps;
+ while (*ptr != NUL)
+ {
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ char_u *prev;
+
+ if (mb_ptr2char(ptr) == *initc)
+ {
+ if (switchit)
+ {
+ *findc = *initc;
+ *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
+ *backwards = TRUE;
+ }
+ else
+ {
+ *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
+ *backwards = FALSE;
+ }
+ return;
+ }
+ prev = ptr;
+ ptr += mb_ptr2len(ptr) + 1;
+ if (mb_ptr2char(ptr) == *initc)
+ {
+ if (switchit)
+ {
+ *findc = *initc;
+ *initc = mb_ptr2char(prev);
+ *backwards = FALSE;
+ }
+ else
+ {
+ *findc = mb_ptr2char(prev);
+ *backwards = TRUE;
+ }
+ return;
+ }
+ ptr += mb_ptr2len(ptr);
+ }
+ else
+#endif
+ {
+ if (*ptr == *initc)
+ {
+ if (switchit)
+ {
+ *backwards = TRUE;
+ *findc = *initc;
+ *initc = ptr[2];
+ }
+ else
+ {
+ *backwards = FALSE;
+ *findc = ptr[2];
+ }
+ return;
+ }
+ ptr += 2;
+ if (*ptr == *initc)
+ {
+ if (switchit)
+ {
+ *backwards = FALSE;
+ *findc = *initc;
+ *initc = ptr[-2];
+ }
+ else
+ {
+ *backwards = TRUE;
+ *findc = ptr[-2];
+ }
+ return;
+ }
+ ++ptr;
+ }
+ if (*ptr == ',')
+ ++ptr;
+ }
+}
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 63570fa4..ba0a4e16 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -59,4 +59,5 @@ int file_ff_differs __ARGS((buf_T *buf, int ignore_empty));
int check_ff_value __ARGS((char_u *p));
long get_sw_value __ARGS((void));
long get_sts_value __ARGS((void));
+void find_mps_values __ARGS((int *initc, int *findc, int *backwards, int switchit));
/* vim: set ft=c : */
diff --git a/src/search.c b/src/search.c
index d7bfc43b..0b1c519f 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1786,28 +1786,8 @@ findmatchlimit(oap, initc, flags, maxtravel)
}
else if (initc != '#' && initc != NUL)
{
- /* 'matchpairs' is "x:y,x:y" */
- for (ptr = curbuf->b_p_mps; *ptr; ptr += 2)
- {
- if (*ptr == initc)
- {
- findc = initc;
- initc = ptr[2];
- backwards = TRUE;
- break;
- }
- ptr += 2;
- if (*ptr == initc)
- {
- findc = initc;
- initc = ptr[-2];
- backwards = FALSE;
- break;
- }
- if (ptr[1] != ',')
- break;
- }
- if (!findc) /* invalid initc! */
+ find_mps_values(&initc, &findc, &backwards, TRUE);
+ if (findc == NUL)
return NULL;
}
/*
@@ -1886,36 +1866,14 @@ findmatchlimit(oap, initc, flags, maxtravel)
--pos.col;
for (;;)
{
- initc = linep[pos.col];
+ initc = PTR2CHAR(linep + pos.col);
if (initc == NUL)
break;
- for (ptr = curbuf->b_p_mps; *ptr; ++ptr)
- {
- if (*ptr == initc)
- {
- findc = ptr[2];
- backwards = FALSE;
- break;
- }
- ptr += 2;
- if (*ptr == initc)
- {
- findc = ptr[-2];
- backwards = TRUE;
- break;
- }
- if (!*++ptr)
- break;
- }
+ find_mps_values(&initc, &findc, &backwards, FALSE);
if (findc)
break;
-#ifdef FEAT_MBYTE
- if (has_mbyte)
- pos.col += (*mb_ptr2len)(linep + pos.col);
- else
-#endif
- ++pos.col;
+ pos.col += MB_PTR2LEN(linep + pos.col);
}
if (!findc)
{
@@ -2260,7 +2218,8 @@ findmatchlimit(oap, initc, flags, maxtravel)
* inquote if the number of quotes in a line is even, unless this
* line or the previous one ends in a '\'. Complicated, isn't it?
*/
- switch (c = linep[pos.col])
+ c = PTR2CHAR(linep + pos.col);
+ switch (c)
{
case NUL:
/* at end of line without trailing backslash, reset inquote */
@@ -2469,20 +2428,23 @@ showmatch(c)
* Only show match for chars in the 'matchpairs' option.
*/
/* 'matchpairs' is "x:y,x:y" */
- for (p = curbuf->b_p_mps; *p != NUL; p += 2)
+ for (p = curbuf->b_p_mps; *p != NUL; ++p)
{
+ if (PTR2CHAR(p) == c
#ifdef FEAT_RIGHTLEFT
- if (*p == c && (curwin->w_p_rl ^ p_ri))
- break;
+ && (curwin->w_p_rl ^ p_ri)
#endif
- p += 2;
- if (*p == c
+ )
+ break;
+ p += MB_PTR2LEN(p) + 1;
+ if (PTR2CHAR(p) == c
#ifdef FEAT_RIGHTLEFT
&& !(curwin->w_p_rl ^ p_ri)
#endif
)
break;
- if (p[1] != ',')
+ p += MB_PTR2LEN(p);
+ if (*p == NUL)
return;
}
diff --git a/src/testdir/test69.in b/src/testdir/test69.in
index 578f76bd..5c9a2f3d 100644
--- a/src/testdir/test69.in
+++ b/src/testdir/test69.in
@@ -1,4 +1,5 @@
Test for multi-byte text formatting.
+Also test, that 'mps' with multibyte chars works.
STARTTEST
:so mbyte.vim
@@ -134,6 +135,15 @@ ENDTEST
}
STARTTEST
+/^{/+1
+:set mps+=u2018:u2019
+d%
+ENDTEST
+
+{
+‘ two three ’ four
+}
+STARTTEST
:g/^STARTTEST/.,/^ENDTEST/d
:1;/^Results/,$wq! test.out
ENDTEST
diff --git a/src/testdir/test69.ok b/src/testdir/test69.ok
index 3dfe402e..59a5a6e5 100644
--- a/src/testdir/test69.ok
+++ b/src/testdir/test69.ok
@@ -140,3 +140,7 @@ a
a
}
+
+{
+ four
+}
diff --git a/src/version.c b/src/version.c
index 251cec81..6d15d586 100644
--- a/src/version.c
+++ b/src/version.c
@@ -726,6 +726,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 769,
+/**/
768,
/**/
767,