diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-11-05 17:16:49 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-11-05 18:06:00 +0800 |
commit | 781616bee5e319fdfa034484c026222b50926ebf (patch) | |
tree | 8decb6167be762e9bd93132c5e47168f3b56f9ca /src | |
parent | 451850920b361059ba99bbde4b90b7730327eebb (diff) | |
download | rneovim-781616bee5e319fdfa034484c026222b50926ebf.tar.gz rneovim-781616bee5e319fdfa034484c026222b50926ebf.tar.bz2 rneovim-781616bee5e319fdfa034484c026222b50926ebf.zip |
vim-patch:8.2.2606: strchars() defaults to counting composing characters
Problem: strchars() defaults to counting composing characters.
Solution: Add strcharlen() which ignores composing characters.
https://github.com/vim/vim/commit/70ce8a1561c5396e4c4381f76a005cbb97646f80
Use docs from latest Vim instead.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 30 | ||||
-rw-r--r-- | src/nvim/testdir/test_utf8.vim | 9 |
3 files changed, 30 insertions, 10 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 61e7f99afd..f47d258125 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -376,6 +376,7 @@ return { str2float={args=1, base=1}, str2list={args={1, 2}, base=1}, str2nr={args={1, 3}, base=1}, + strcharlen={args=1, base=1}, strcharpart={args={2, 3}, base=1}, strchars={args={1, 2}, base=1}, strdisplaywidth={args={1, 2}, base=1}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4939c5ef5d..7ad4850d40 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -8447,26 +8447,38 @@ static void f_strlen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0])); } -/// "strchars()" function -static void f_strchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +static void strchar_common(typval_T *argvars, typval_T *rettv, bool skipcc) { const char *s = tv_get_string(&argvars[0]); - int skipcc = false; varnumber_T len = 0; int (*func_mb_ptr2char_adv)(const char_u **pp); + func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv; + while (*s != NUL) { + func_mb_ptr2char_adv((const char_u **)&s); + len++; + } + rettv->vval.v_number = len; +} + +/// "strcharlen()" function +static void f_strcharlen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + strchar_common(argvars, rettv, true); +} + +/// "strchars()" function +static void f_strchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + int skipcc = false; + if (argvars[1].v_type != VAR_UNKNOWN) { skipcc = (int)tv_get_bool(&argvars[1]); } if (skipcc < 0 || skipcc > 1) { semsg(_(e_using_number_as_bool_nr), skipcc); } else { - func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv; - while (*s != NUL) { - func_mb_ptr2char_adv((const char_u **)&s); - len++; - } - rettv->vval.v_number = len; + strchar_common(argvars, rettv, skipcc); } } diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim index 3d29d38231..aa3b02b575 100644 --- a/src/nvim/testdir/test_utf8.vim +++ b/src/nvim/testdir/test_utf8.vim @@ -12,7 +12,7 @@ func Test_visual_block_insert() bwipeout! endfunc -" Test for built-in function strchars() +" Test for built-in functions strchars() and strcharlen() func Test_strchars() let inp = ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"] let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]] @@ -21,6 +21,13 @@ func Test_strchars() call assert_equal(exp[i][1], inp[i]->strchars(0)) call assert_equal(exp[i][2], strchars(inp[i], 1)) endfor + + let exp = [1, 3, 1, 1, 1] + for i in range(len(inp)) + call assert_equal(exp[i], inp[i]->strcharlen()) + call assert_equal(exp[i], strcharlen(inp[i])) + endfor + call assert_fails("let v=strchars('abc', [])", 'E745:') call assert_fails("let v=strchars('abc', 2)", 'E1023:') endfunc |