patch 7.4.755
Problem:    It is not easy to count the number of characters.
Solution:   Add the skipcc argument to strchars(). (Hirohito Higashi, Ken
            Takata)
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 44abae6..223c363 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1985,7 +1985,7 @@
 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 @@
 							*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 452014f..5869370 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3810,7 +3810,7 @@
 	/* (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 @@
     {"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 @@
     typval_T	*rettv;
 {
     char_u		*s = get_tv_string(&argvars[0]);
+    int			skipcc = 0;
 #ifdef FEAT_MBYTE
     varnumber_T		len = 0;
-
-    while (*s != NUL)
-    {
-	mb_cptr2char_adv(&s);
-	++len;
-    }
-    rettv->vval.v_number = len;
-#else
-    rettv->vval.v_number = (varnumber_T)(STRLEN(s));
+    int			(*func_mb_ptr2char_adv)(char_u **pp);
 #endif
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+	skipcc = get_tv_number_chk(&argvars[1], NULL);
+    if (skipcc < 0 || skipcc > 1)
+	EMSG(_(e_invarg));
+    else
+    {
+#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));
+#endif
+    }
 }
 
 /*
diff --git a/src/testdir/test_utf8.in b/src/testdir/test_utf8.in
index 713fee2..8bc783e 100644
--- a/src/testdir/test_utf8.in
+++ b/src/testdir/test_utf8.in
@@ -11,6 +11,12 @@
 :
 :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 c5bed54..8ccdd6d 100644
--- a/src/testdir/test_utf8.ok
+++ b/src/testdir/test_utf8.ok
@@ -2,3 +2,18 @@
 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 eeef1c7..e712dc4 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    755,
+/**/
     754,
 /**/
     753,