Problem: 'matchpairs' does not work with multi-byte characters.
Solution: Make it work. (Christian Brabandt)
*/
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))
/* '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;
}
}
{
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;
+ }
+}
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 : */
}
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;
}
/*
--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)
{
* 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 */
* 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;
}
Test for multi-byte text formatting.
+Also test, that 'mps' with multibyte chars works.
STARTTEST
:so mbyte.vim
}
+STARTTEST
+/^{/+1
+:set mps+=\16u2018:\16u2019
+d%
+ENDTEST
+
+{
+‘ two three ’ four
+}
STARTTEST
:g/^STARTTEST/.,/^ENDTEST/d
:1;/^Results/,$wq! test.out
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 769,
/**/
768,
/**/