To: vim_dev@googlegroups.com Subject: Patch 7.4.057 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.057 Problem: byteidx() does not work for composing characters. Solution: Add byteidxcomp(). Files: src/eval.c, src/testdir/test69.in, src/testdir/test69.ok, runtime/doc/eval.txt *** ../vim-7.4.056/src/eval.c 2013-10-02 16:46:23.000000000 +0200 --- src/eval.c 2013-11-02 22:30:08.000000000 +0100 *************** *** 474,480 **** --- 474,482 ---- static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); + static void byteidx __ARGS((typval_T *argvars, typval_T *rettv, int comp)); static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_byteidxcomp __ARGS((typval_T *argvars, typval_T *rettv)); static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); #ifdef FEAT_FLOAT static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); *************** *** 7861,7866 **** --- 7863,7869 ---- {"bufwinnr", 1, 1, f_bufwinnr}, {"byte2line", 1, 1, f_byte2line}, {"byteidx", 2, 2, f_byteidx}, + {"byteidxcomp", 2, 2, f_byteidxcomp}, {"call", 2, 3, f_call}, #ifdef FEAT_FLOAT {"ceil", 1, 1, f_ceil}, *************** *** 9177,9189 **** #endif } - /* - * "byteidx()" function - */ static void ! f_byteidx(argvars, rettv) typval_T *argvars; typval_T *rettv; { #ifdef FEAT_MBYTE char_u *t; --- 9180,9190 ---- #endif } static void ! byteidx(argvars, rettv, comp) typval_T *argvars; typval_T *rettv; + int comp; { #ifdef FEAT_MBYTE char_u *t; *************** *** 9203,9209 **** { if (*t == NUL) /* EOL reached */ return; ! t += (*mb_ptr2len)(t); } rettv->vval.v_number = (varnumber_T)(t - str); #else --- 9204,9213 ---- { if (*t == NUL) /* EOL reached */ return; ! if (enc_utf8 && comp) ! t += utf_ptr2len(t); ! else ! t += (*mb_ptr2len)(t); } rettv->vval.v_number = (varnumber_T)(t - str); #else *************** *** 9212,9217 **** --- 9216,9243 ---- #endif } + /* + * "byteidx()" function + */ + static void + f_byteidx(argvars, rettv) + typval_T *argvars; + typval_T *rettv; + { + byteidx(argvars, rettv, FALSE); + } + + /* + * "byteidxcomp()" function + */ + static void + f_byteidxcomp(argvars, rettv) + typval_T *argvars; + typval_T *rettv; + { + byteidx(argvars, rettv, TRUE); + } + int func_call(name, args, selfdict, rettv) char_u *name; *** ../vim-7.4.056/src/testdir/test69.in 2013-03-07 18:30:50.000000000 +0100 --- src/testdir/test69.in 2013-11-02 22:46:02.000000000 +0100 *************** *** 1,6 **** --- 1,7 ---- Test for multi-byte text formatting. Also test, that 'mps' with multibyte chars works. And test "ra" on multi-byte characters. + Also test byteidx() and byteidxcomp() STARTTEST :so mbyte.vim *************** *** 154,159 **** --- 155,175 ---- aab STARTTEST + :let a = '.é.' " one char of two bytes + :let b = '.é.' " normal e with composing char + /^byteidx + :put =string([byteidx(a, 0), byteidx(a, 1), byteidx(a, 2), byteidx(a, 3), byteidx(a, 4)]) + :put =string([byteidx(b, 0), byteidx(b, 1), byteidx(b, 2), byteidx(b, 3), byteidx(b, 4)]) + /^byteidxcomp + :put =string([byteidxcomp(a, 0), byteidxcomp(a, 1), byteidxcomp(a, 2), byteidxcomp(a, 3), byteidxcomp(a, 4)]) + :let b = '.é.' + :put =string([byteidxcomp(b, 0), byteidxcomp(b, 1), byteidxcomp(b, 2), byteidxcomp(b, 3), byteidxcomp(b, 4), byteidxcomp(b, 5)]) + ENDTEST + + byteidx + byteidxcomp + + STARTTEST :g/^STARTTEST/.,/^ENDTEST/d :1;/^Results/,$wq! test.out ENDTEST *** ../vim-7.4.056/src/testdir/test69.ok 2013-03-07 18:31:32.000000000 +0100 --- src/testdir/test69.ok 2013-11-02 22:43:25.000000000 +0100 *************** *** 149,151 **** --- 149,159 ---- aaaa aaa + + byteidx + [0, 1, 3, 4, -1] + [0, 1, 4, 5, -1] + byteidxcomp + [0, 1, 3, 4, -1] + [0, 1, 2, 4, 5, -1] + *** ../vim-7.4.056/runtime/doc/eval.txt 2013-08-10 13:24:53.000000000 +0200 --- runtime/doc/eval.txt 2013-11-02 23:27:24.000000000 +0100 *************** *** 1712,1717 **** --- 1713,1719 ---- bufwinnr( {expr}) Number window number of buffer {expr} byte2line( {byte}) Number line number at byte count {byte} byteidx( {expr}, {nr}) Number byte index of {nr}'th char in {expr} + byteidxcomp( {expr}, {nr}) Number byte index of {nr}'th char in {expr} call( {func}, {arglist} [, {dict}]) any call {func} with arguments {arglist} ceil( {expr}) Float round {expr} up *************** *** 2260,2266 **** {expr}. Use zero for the first character, it returns zero. This function is only useful when there are multibyte characters, otherwise the returned value is equal to {nr}. ! Composing characters are counted as a separate character. Example : > echo matchstr(str, ".", byteidx(str, 3)) < will display the fourth character. Another way to do the --- 2262,2271 ---- {expr}. Use zero for the first character, it returns zero. This function is only useful when there are multibyte characters, otherwise the returned value is equal to {nr}. ! Composing characters are not counted separately, their byte ! length is added to the preceding base character. See ! |byteidxcomp()| below for counting composing characters ! separately. Example : > echo matchstr(str, ".", byteidx(str, 3)) < will display the fourth character. Another way to do the *************** *** 2269,2275 **** echo strpart(s, 0, byteidx(s, 1)) < If there are less than {nr} characters -1 is returned. If there are exactly {nr} characters the length of the string ! is returned. call({func}, {arglist} [, {dict}]) *call()* *E699* Call function {func} with the items in |List| {arglist} as --- 2274,2293 ---- echo strpart(s, 0, byteidx(s, 1)) < If there are less than {nr} characters -1 is returned. If there are exactly {nr} characters the length of the string ! in bytes is returned. ! ! byteidxcomp({expr}, {nr}) *byteidxcomp()* ! Like byteidx(), except that a composing character is counted ! as a separate character. Example: > ! let s = 'e' . nr2char(0x301) ! echo byteidx(s, 1) ! echo byteidxcomp(s, 1) ! echo byteidxcomp(s, 2) ! < The first and third echo result in 3 ('e' plus composing ! character is 3 bytes), the second echo results in 1 ('e' is ! one byte). ! Only works different from byteidx() when 'encoding' is set to ! a Unicode encoding. call({func}, {arglist} [, {dict}]) *call()* *E699* Call function {func} with the items in |List| {arglist} as *** ../vim-7.4.056/src/version.c 2013-11-02 21:49:28.000000000 +0100 --- src/version.c 2013-11-02 22:45:13.000000000 +0100 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 57, /**/ -- Any sufficiently advanced technology is indistinguishable from magic. Arthur C. Clarke Any sufficiently advanced bug is indistinguishable from a feature. Rich Kulawiec /// 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 ///