| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.769 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.769 |
| Problem: 'matchpairs' does not work with multi-byte characters. |
| Solution: Make it work. (Christian Brabandt) |
| Files: src/misc1.c, src/option.c, src/proto/option.pro, src/search.c, |
| src/testdir/test69.in, src/testdir/test69.ok |
| |
| |
| |
| |
| |
| *** 2288,2301 **** |
| */ |
| 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_RIGHTLEFT |
| if (!p_ri || (State & REPLACE_FLAG)) |
| --- 2288,2305 ---- |
| */ |
| if (p_sm && (State & INSERT) |
| && msg_silent == 0 |
| #ifdef FEAT_INS_EXPAND |
| && !ins_compl_active() |
| #endif |
| ) |
| ! { |
| ! #ifdef FEAT_MBYTE |
| ! if (has_mbyte) |
| ! showmatch(mb_ptr2char(buf)); |
| ! else |
| ! #endif |
| ! showmatch(c); |
| ! } |
| |
| #ifdef FEAT_RIGHTLEFT |
| if (!p_ri || (State & REPLACE_FLAG)) |
| |
| |
| |
| *** 6149,6164 **** |
| /* '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; |
| } |
| } |
| |
| --- 6149,6194 ---- |
| /* 'matchpairs' */ |
| else if (gvarp == &p_mps) |
| { |
| ! #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,11455 **** |
| --- 11483,11583 ---- |
| { |
| 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; |
| + } |
| + } |
| |
| |
| |
| *** 59,62 **** |
| --- 59,63 ---- |
| 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 : */ |
| |
| |
| |
| *** 1786,1813 **** |
| } |
| 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! */ |
| return NULL; |
| } |
| /* |
| --- 1786,1793 ---- |
| } |
| else if (initc != '#' && initc != NUL) |
| { |
| ! find_mps_values(&initc, &findc, &backwards, TRUE); |
| ! if (findc == NUL) |
| return NULL; |
| } |
| /* |
| |
| *** 1886,1921 **** |
| --pos.col; |
| for (;;) |
| { |
| ! initc = 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; |
| ! } |
| if (findc) |
| break; |
| ! #ifdef FEAT_MBYTE |
| ! if (has_mbyte) |
| ! pos.col += (*mb_ptr2len)(linep + pos.col); |
| ! else |
| ! #endif |
| ! ++pos.col; |
| } |
| if (!findc) |
| { |
| --- 1866,1879 ---- |
| --pos.col; |
| for (;;) |
| { |
| ! initc = PTR2CHAR(linep + pos.col); |
| if (initc == NUL) |
| break; |
| |
| ! find_mps_values(&initc, &findc, &backwards, FALSE); |
| if (findc) |
| break; |
| ! pos.col += MB_PTR2LEN(linep + pos.col); |
| } |
| if (!findc) |
| { |
| |
| *** 2260,2266 **** |
| * 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]) |
| { |
| case NUL: |
| /* at end of line without trailing backslash, reset inquote */ |
| --- 2218,2225 ---- |
| * 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? |
| */ |
| ! c = PTR2CHAR(linep + pos.col); |
| ! switch (c) |
| { |
| case NUL: |
| /* at end of line without trailing backslash, reset inquote */ |
| |
| *** 2469,2488 **** |
| * 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) |
| { |
| #ifdef FEAT_RIGHTLEFT |
| ! if (*p == c && (curwin->w_p_rl ^ p_ri)) |
| ! break; |
| #endif |
| ! p += 2; |
| ! if (*p == c |
| #ifdef FEAT_RIGHTLEFT |
| && !(curwin->w_p_rl ^ p_ri) |
| #endif |
| ) |
| break; |
| ! if (p[1] != ',') |
| return; |
| } |
| |
| --- 2428,2450 ---- |
| * Only show match for chars in the 'matchpairs' option. |
| */ |
| /* 'matchpairs' is "x:y,x:y" */ |
| ! for (p = curbuf->b_p_mps; *p != NUL; ++p) |
| { |
| + if (PTR2CHAR(p) == c |
| #ifdef FEAT_RIGHTLEFT |
| ! && (curwin->w_p_rl ^ p_ri) |
| #endif |
| ! ) |
| ! break; |
| ! p += MB_PTR2LEN(p) + 1; |
| ! if (PTR2CHAR(p) == c |
| #ifdef FEAT_RIGHTLEFT |
| && !(curwin->w_p_rl ^ p_ri) |
| #endif |
| ) |
| break; |
| ! p += MB_PTR2LEN(p); |
| ! if (*p == NUL) |
| return; |
| } |
| |
| |
| |
| |
| *** 1,4 **** |
| --- 1,5 ---- |
| Test for multi-byte text formatting. |
| + Also test, that 'mps' with multibyte chars works. |
| |
| STARTTEST |
| :so mbyte.vim |
| |
| *** 134,139 **** |
| --- 135,149 ---- |
| } |
| |
| STARTTEST |
| + /^{/+1 |
| + :set mps+=u2018:u2019 |
| + d% |
| + ENDTEST |
| + |
| + { |
| + ‘ two three ’ four |
| + } |
| + STARTTEST |
| :g/^STARTTEST/.,/^ENDTEST/d |
| :1;/^Results/,$wq! test.out |
| ENDTEST |
| |
| |
| |
| *** 140,142 **** |
| --- 140,146 ---- |
| a |
| } |
| |
| + |
| + { |
| + four |
| + } |
| |
| |
| |
| *** 727,728 **** |
| --- 727,730 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 769, |
| /**/ |
| |
| -- |
| Microsoft's definition of a boolean: TRUE, FALSE, MAYBE |
| "Embrace and extend"...? |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |