aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2016-10-31 10:13:41 -0400
committerGitHub <noreply@github.com>2016-10-31 10:13:41 -0400
commit859e9fa65f539020a15794a98bc8eff2f9538ded (patch)
tree36584f5b9667c461dd8d98c5ce3fde25d1cd9f6b /src/nvim/eval.c
parented198737fd739dcd4960763028a73e4efd83c452 (diff)
parentf6f77272b3233ea2926e2d7fb2c007e381a85ea1 (diff)
downloadrneovim-859e9fa65f539020a15794a98bc8eff2f9538ded.tar.gz
rneovim-859e9fa65f539020a15794a98bc8eff2f9538ded.tar.bz2
rneovim-859e9fa65f539020a15794a98bc8eff2f9538ded.zip
Merge pull request #5527 from brcolow/vim-7.4.1730
vim-patch:7.4.[1730,1734,1741,1742,1779,1782]
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 512555eac1..5d4241c8af 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -15612,6 +15612,39 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "strgetchar()" function
+static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char_u *str;
+ int len;
+ int error = false;
+ int charidx;
+
+ rettv->vval.v_number = -1;
+ str = get_tv_string_chk(&argvars[0]);
+ if (str == NULL) {
+ return;
+ }
+ len = (int)STRLEN(str);
+ charidx = get_tv_number_chk(&argvars[1], &error);
+ if (error) {
+ return;
+ }
+
+ {
+ int byteidx = 0;
+
+ while (charidx >= 0 && byteidx < len) {
+ if (charidx == 0) {
+ rettv->vval.v_number = mb_ptr2char(str + byteidx);
+ break;
+ }
+ charidx--;
+ byteidx += mb_cptr2len(str + byteidx);
+ }
+ }
+}
+
/*
* "stridx()" function
*/
@@ -15712,6 +15745,64 @@ static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (varnumber_T) mb_string2cells(s);
}
+// "strcharpart()" function
+static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
+ char_u *p;
+ int nchar;
+ int nbyte = 0;
+ int charlen;
+ int len = 0;
+ int slen;
+ int error = false;
+
+ p = get_tv_string(&argvars[0]);
+ slen = (int)STRLEN(p);
+
+ nchar = get_tv_number_chk(&argvars[1], &error);
+ if (!error) {
+ if (nchar > 0) {
+ while (nchar > 0 && nbyte < slen) {
+ nbyte += mb_cptr2len(p + nbyte);
+ nchar--;
+ }
+ } else {
+ nbyte = nchar;
+ }
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ charlen = get_tv_number(&argvars[2]);
+ while (charlen > 0 && nbyte + len < slen) {
+ int off = nbyte + len;
+
+ if (off < 0) {
+ len += 1;
+ } else {
+ len += mb_cptr2len(p + off);
+ }
+ charlen--;
+ }
+ } else {
+ len = slen - nbyte; // default: all bytes that are available.
+ }
+
+ // Only return the overlap between the specified part and the actual
+ // string.
+ if (nbyte < 0) {
+ len += nbyte;
+ nbyte = 0;
+ } else if (nbyte > slen) {
+ nbyte = slen;
+ }
+ if (len < 0) {
+ len = 0;
+ } else if (nbyte + len > slen) {
+ len = slen - nbyte;
+ }
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strnsave(p + nbyte, len);
+}
+
/*
* "strpart()" function
*/