aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/eval/funcs.c10
-rw-r--r--src/nvim/testdir/test_functions.vim4
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()