Saturday, December 29, 2012

Re: matchpairs and Unicode

diff --git a/src/misc1.c b/src/misc1.c
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2288,14 +2288,18 @@
*/
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
--- a/src/option.c
+++ b/src/option.c
@@ -6149,16 +6149,46 @@
/* 'matchpairs' */
else if (gvarp == &p_mps)
{
- /* 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;
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ p = *varp;
+ while (*p)
+ {
+ 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)
+ {
+ errmsg = e_invarg;
+ break;
+ }
+ if (*p == ',')
+ p++;
+ }
+ }
+ 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;
+ }
}
}

@@ -11453,3 +11483,105 @@
{
return curbuf->b_p_sts < 0 ? get_sw_value() : curbuf->b_p_sts;
}
+
+/*
+ * Check matchpairs option for given chars, returns findc or NULL,
+ * if not found in 'mps' setting
+ */
+
+ void
+find_mps_values(initc, findc, backwards, switchit)
+ int *initc;
+ int *findc;
+ int *backwards;
+ int switchit;
+
+{
+ char_u *ptr;
+
+#ifdef FEAT_MBYTE
+ ptr = curbuf->b_p_mps;
+ while (*ptr)
+ {
+ if (*findc)
+ return;
+ if (has_mbyte)
+ {
+ if (*ptr == ',')
+ ptr++;
+ 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;
+ }
+ ptr += mb_ptr2len(ptr) + 1;
+ if (mb_ptr2char(ptr) == *initc)
+ {
+ if (switchit)
+ {
+ (*findc) = (*initc);
+ (*initc) = mb_ptr2char(ptr - mb_ptr2len(ptr) - 1);
+ (*backwards) = FALSE;
+ }
+ else
+ {
+ (*findc) = mb_ptr2char(ptr - mb_ptr2len(ptr) - 1);
+ (*backwards) = TRUE;
+ }
+ return;
+ }
+ ptr += mb_ptr2len(ptr);
+ }
+ else
+#endif
+ {
+ if (*ptr == ',')
+ ptr++;
+ 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;
+ }
+ if (!*++ptr)
+ break;
+ ptr++;
+ }
+ }
+ return;
+}
diff --git a/src/proto/option.pro b/src/proto/option.pro
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -59,4 +59,5 @@
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
--- a/src/search.c
+++ b/src/search.c
@@ -1786,28 +1786,8 @@
}
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)
return NULL;
}
/*
@@ -1887,27 +1867,14 @@
for (;;)
{
initc = linep[pos.col];
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ initc = mb_ptr2char(linep + pos.col);
+#endif
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
@@ -2350,7 +2317,11 @@
/* Check for match outside of quotes, and inside of
* quotes when the start is also inside of quotes. */
if ((!inquote || start_in_quotes == TRUE)
- && (c == initc || c == findc))
+ && (c == initc || c == findc
+#ifdef FEAT_MBYTE
+ || mb_ptr2char(linep + pos.col) == findc)
+#endif
+ )
{
int col, bslcnt = 0;

@@ -2469,20 +2440,44 @@
* 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;
+#ifdef FEAT_MBYTE
+ p += mb_ptr2len(p) + 1
+#else
+ p += 2
+#endif
+ )
{
+ if ((*p == c
+#ifdef FEAT_MBYTE
+ || c == mb_ptr2char(p))
+#endif
#ifdef FEAT_RIGHTLEFT
- if (*p == c && (curwin->w_p_rl ^ p_ri))
+ && (curwin->w_p_rl ^ p_ri)
+#endif
+ )
break;
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ p += mb_ptr2len(p) + 1;
+ else
#endif
- p += 2;
- if (*p == c
+ p += 2;
+ if ((*p == c
+#ifdef FEAT_MBYTE
+ || mb_ptr2char(p) == c
+#endif
+ )
#ifdef FEAT_RIGHTLEFT
&& !(curwin->w_p_rl ^ p_ri)
#endif
)
break;
- if (p[1] != ',')
+ if (
+#ifdef FEAT_MBYTE
+ p[mb_ptr2len(p)] != ',' &&
+#endif
+ p[1] != ',')
return;
}

diff --git a/src/testdir/test69.in b/src/testdir/test69.in
--- 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 @@
}

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
--- a/src/testdir/test69.ok
+++ b/src/testdir/test69.ok
@@ -140,3 +140,7 @@
a
}

+
+{
+ four
+}
Hi

On Do, 27 Dez 2012, KamilS wrote:

> > Thanks. If I have some spare time, I'll look into enhancing the
> > 'matchpairs' option.
>
> This is fantastic, thanks a lot!

Bram,
here is a patch to make the matchpairs setting multibyte aware.

regards,
Christian
--
Bei ARD und ZDF reihern Sie in den 1. Sitzen.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: