diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 10 | ||||
-rw-r--r-- | src/nvim/testdir/test_functions.vim | 4 |
3 files changed, 15 insertions, 1 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index a5544435d2..be16ddd7f6 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -336,7 +336,7 @@ return { stridx={args={2, 3}}, string={args=1}, strlen={args=1}, - strpart={args={2, 3}}, + strpart={args={2, 4}}, strridx={args={2, 3}}, strtrans={args=1}, strwidth={args=1}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 18e514b9a0..8e0e420eb0 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -9946,6 +9946,16 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) len = slen - n; } + if (argvars[2].v_type != VAR_UNKNOWN && argvars[3].v_type != VAR_UNKNOWN) { + int off; + + // length in characters + for (off = n; off < (int)slen && len > 0; len--) { + off += utfc_ptr2len((char_u *)p + off); + } + len = off - n; + } + rettv->v_type = VAR_STRING; rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len); } diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 51689db9c4..6b45ac61d1 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -334,6 +334,10 @@ func Test_strpart() call assert_equal('lép', strpart('éléphant', 2, 4)) call assert_equal('léphant', strpart('éléphant', 2)) + + call assert_equal('é', strpart('éléphant', 0, 1, 1)) + call assert_equal('ép', strpart('éléphant', 3, 2, v:true)) + call assert_equal('ó', strpart('cómposed', 1, 1, 1)) endfunc func Test_tolower() |