# HG changeset patch # User Bram Moolenaar # Date 1358438525 -3600 # Node ID d179a8eff9d7b0adc561f4a4dcfb0b7612c1f301 # Parent 639564cb15a14559a40f87adbf94e2061c2c0016 updated for version 7.3.769 Problem: 'matchpairs' does not work with multi-byte characters. Solution: Make it work. (Christian Brabandt) diff --git a/src/misc1.c b/src/misc1.c --- 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 --- a/src/option.c +++ b/src/option.c @@ -6149,16 +6149,46 @@ did_set_string_option(opt_idx, varp, new /* '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) + { + for (p = *varp; *p != NUL; ++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 + || (*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; + } } } @@ -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 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -59,4 +59,5 @@ int file_ff_differs __ARGS((buf_T *buf, 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 @@ findmatchlimit(oap, initc, flags, maxtra } 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, maxtra --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, maxtra * 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 --- 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 --- 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 --- 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,