summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <bram@vim.org>2015-06-25 16:09:26 +0200
committerBram Moolenaar <bram@vim.org>2015-06-25 16:09:26 +0200
commit628ec305d9fac9ab8dd2c75f6a4b3cef3e1827e3 (patch)
treed14e4acd3f86d421ef0d27bee63b8112e3c38596
parent36e8b606ce1aa2a45b54d8922c2c6e379bda0a81 (diff)
downloadvim-628ec305d9fac9ab8dd2c75f6a4b3cef3e1827e3.tar.gz
patch 7.4.755v7.4.755v7-4-755
Problem: It is not easy to count the number of characters. Solution: Add the skipcc argument to strchars(). (Hirohito Higashi, Ken Takata)
-rw-r--r--runtime/doc/eval.txt12
-rw-r--r--src/eval.c28
-rw-r--r--src/testdir/test_utf8.in6
-rw-r--r--src/testdir/test_utf8.ok15
-rw-r--r--src/version.c2
5 files changed, 47 insertions, 16 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 44abae62..223c3639 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1985,7 +1985,7 @@ split( {expr} [, {pat} [, {keepempty}]])
sqrt( {expr}) Float square root of {expr}
str2float( {expr}) Float convert String to Float
str2nr( {expr} [, {base}]) Number convert String to Number
-strchars( {expr}) Number character length of the String {expr}
+strchars( {expr} [, {skipcc}]) Number character length of the String {expr}
strdisplaywidth( {expr} [, {col}]) Number display length of the String {expr}
strftime( {format}[, {time}]) String time in specified format
stridx( {haystack}, {needle}[, {start}])
@@ -5913,15 +5913,11 @@ string({expr}) Return {expr} converted to a String. If {expr} is a Number,
*strlen()*
strlen({expr}) The result is a Number, which is the length of the String
{expr} in bytes.
- If you want to count the number of multi-byte characters (not
- counting composing characters) use something like this: >
-
- :let len = strlen(substitute(str, ".", "x", "g"))
-<
If the argument is a Number it is first converted to a String.
For other types an error is given.
- Also see |len()|, |strchars()|, |strdisplaywidth()| and
- |strwidth()|.
+ If you want to count the number of multi-byte characters use
+ |strchars()|.
+ Also see |len()|, |strdisplaywidth()| and |strwidth()|.
strpart({src}, {start}[, {len}]) *strpart()*
The result is a String, which is part of {src}, starting from
diff --git a/src/eval.c b/src/eval.c
index 452014f7..5869370f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3810,7 +3810,7 @@ do_lock_var(lp, name_end, deep, lock)
/* (un)lock a List item. */
item_lock(&lp->ll_li->li_tv, deep, lock);
else
- /* un(lock) a Dictionary item. */
+ /* (un)lock a Dictionary item. */
item_lock(&lp->ll_di->di_tv, deep, lock);
return ret;
@@ -8309,7 +8309,7 @@ static struct fst
{"str2float", 1, 1, f_str2float},
#endif
{"str2nr", 1, 2, f_str2nr},
- {"strchars", 1, 1, f_strchars},
+ {"strchars", 1, 2, f_strchars},
{"strdisplaywidth", 1, 2, f_strdisplaywidth},
#ifdef HAVE_STRFTIME
{"strftime", 1, 2, f_strftime},
@@ -18372,18 +18372,30 @@ f_strchars(argvars, rettv)
typval_T *rettv;
{
char_u *s = get_tv_string(&argvars[0]);
+ int skipcc = 0;
#ifdef FEAT_MBYTE
varnumber_T len = 0;
+ int (*func_mb_ptr2char_adv)(char_u **pp);
+#endif
- while (*s != NUL)
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ skipcc = get_tv_number_chk(&argvars[1], NULL);
+ if (skipcc < 0 || skipcc > 1)
+ EMSG(_(e_invarg));
+ else
{
- mb_cptr2char_adv(&s);
- ++len;
- }
- rettv->vval.v_number = len;
+#ifdef FEAT_MBYTE
+ func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
+ while (*s != NUL)
+ {
+ func_mb_ptr2char_adv(&s);
+ ++len;
+ }
+ rettv->vval.v_number = len;
#else
- rettv->vval.v_number = (varnumber_T)(STRLEN(s));
+ rettv->vval.v_number = (varnumber_T)(STRLEN(s));
#endif
+ }
}
/*
diff --git a/src/testdir/test_utf8.in b/src/testdir/test_utf8.in
index 713fee2c..8bc783e2 100644
--- a/src/testdir/test_utf8.in
+++ b/src/testdir/test_utf8.in
@@ -11,6 +11,12 @@ STARTTEST
:
:bwipeout!
:$put=r
+:" Test for built-in function strchars()
+:for str in ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
+: $put=strchars(str)
+: $put=strchars(str, 0)
+: $put=strchars(str, 1)
+:endfor
:call garbagecollect(1)
:/^start:/,$wq! test.out
ENDTEST
diff --git a/src/testdir/test_utf8.ok b/src/testdir/test_utf8.ok
index c5bed548..8ccdd6d7 100644
--- a/src/testdir/test_utf8.ok
+++ b/src/testdir/test_utf8.ok
@@ -2,3 +2,18 @@ start:
axaa
xあああ
bxbb
+1
+1
+1
+3
+3
+3
+2
+2
+1
+3
+3
+1
+1
+1
+1
diff --git a/src/version.c b/src/version.c
index eeef1c75..e712dc40 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 755,
+/**/
754,
/**/
753,