mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
vim-patch:8.2.2606: strchars() defaults to counting composing characters
Problem: strchars() defaults to counting composing characters.
Solution: Add strcharlen() which ignores composing characters.
70ce8a1561
Use docs from latest Vim instead.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -466,10 +466,11 @@ str2list({expr} [, {utf8}]) List convert each character of {expr} to
|
||||
ASCII/UTF-8 value
|
||||
str2nr({expr} [, {base} [, {quoted}]])
|
||||
Number convert String to Number
|
||||
strcharlen({expr}) Number character length of the String {expr}
|
||||
strcharpart({str}, {start} [, {len}])
|
||||
String {len} characters of {str} at
|
||||
character {start}
|
||||
strchars({expr} [, {skipcc}]) Number character length of the String {expr}
|
||||
strchars({expr} [, {skipcc}]) Number character count of the String {expr}
|
||||
strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
|
||||
strftime({format} [, {time}]) String format time with a specified format
|
||||
strgetchar({str}, {index}) Number get char {index} from {str}
|
||||
@@ -7836,6 +7837,21 @@ str2nr({string} [, {base}]) *str2nr()*
|
||||
Can also be used as a |method|: >
|
||||
GetText()->str2nr()
|
||||
|
||||
|
||||
strcharlen({string}) *strcharlen()*
|
||||
The result is a Number, which is the number of characters
|
||||
in String {string}. Composing characters are ignored.
|
||||
|strchars()| can count the number of characters, counting
|
||||
composing characters separately.
|
||||
|
||||
Returns 0 if {string} is empty or on error.
|
||||
|
||||
Also see |strlen()|, |strdisplaywidth()| and |strwidth()|.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetText()->strcharlen()
|
||||
|
||||
|
||||
strcharpart({src}, {start} [, {len}]) *strcharpart()*
|
||||
Like |strpart()| but using character index and length instead
|
||||
of byte index and length. Composing characters are counted
|
||||
@@ -7850,12 +7866,14 @@ strcharpart({src}, {start} [, {len}]) *strcharpart()*
|
||||
Can also be used as a |method|: >
|
||||
GetText()->strcharpart(5)
|
||||
|
||||
|
||||
strchars({string} [, {skipcc}]) *strchars()*
|
||||
The result is a Number, which is the number of characters
|
||||
in String {string}.
|
||||
When {skipcc} is omitted or zero, composing characters are
|
||||
counted separately.
|
||||
When {skipcc} set to 1, Composing characters are ignored.
|
||||
|strcharlen()| always does this.
|
||||
|
||||
Returns zero on error.
|
||||
|
||||
|
@@ -619,7 +619,8 @@ String manipulation: *string-functions*
|
||||
stridx() first index of a short string in a long string
|
||||
strridx() last index of a short string in a long string
|
||||
strlen() length of a string in bytes
|
||||
strchars() length of a string in characters
|
||||
strcharlen() length of a string in characters
|
||||
strchars() number of characters in a string
|
||||
strwidth() size of string when displayed
|
||||
strdisplaywidth() size of string when displayed, deals with tabs
|
||||
setcellwidths() set character cell width overrides
|
||||
|
@@ -376,6 +376,7 @@ return {
|
||||
str2float={args=1, base=1},
|
||||
str2list={args={1, 2}, base=1},
|
||||
str2nr={args={1, 3}, base=1},
|
||||
strcharlen={args=1, base=1},
|
||||
strcharpart={args={2, 3}, base=1},
|
||||
strchars={args={1, 2}, base=1},
|
||||
strdisplaywidth={args={1, 2}, base=1},
|
||||
|
@@ -8447,13 +8447,30 @@ static void f_strlen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
|
||||
}
|
||||
|
||||
static void strchar_common(typval_T *argvars, typval_T *rettv, bool skipcc)
|
||||
{
|
||||
const char *s = tv_get_string(&argvars[0]);
|
||||
varnumber_T len = 0;
|
||||
int (*func_mb_ptr2char_adv)(const char_u **pp);
|
||||
|
||||
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
|
||||
while (*s != NUL) {
|
||||
func_mb_ptr2char_adv((const char_u **)&s);
|
||||
len++;
|
||||
}
|
||||
rettv->vval.v_number = len;
|
||||
}
|
||||
|
||||
/// "strcharlen()" function
|
||||
static void f_strcharlen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
strchar_common(argvars, rettv, true);
|
||||
}
|
||||
|
||||
/// "strchars()" function
|
||||
static void f_strchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
const char *s = tv_get_string(&argvars[0]);
|
||||
int skipcc = false;
|
||||
varnumber_T len = 0;
|
||||
int (*func_mb_ptr2char_adv)(const char_u **pp);
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN) {
|
||||
skipcc = (int)tv_get_bool(&argvars[1]);
|
||||
@@ -8461,12 +8478,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
if (skipcc < 0 || skipcc > 1) {
|
||||
semsg(_(e_using_number_as_bool_nr), skipcc);
|
||||
} else {
|
||||
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
|
||||
while (*s != NUL) {
|
||||
func_mb_ptr2char_adv((const char_u **)&s);
|
||||
len++;
|
||||
}
|
||||
rettv->vval.v_number = len;
|
||||
strchar_common(argvars, rettv, skipcc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@ func Test_visual_block_insert()
|
||||
bwipeout!
|
||||
endfunc
|
||||
|
||||
" Test for built-in function strchars()
|
||||
" Test for built-in functions strchars() and strcharlen()
|
||||
func Test_strchars()
|
||||
let inp = ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
|
||||
let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]]
|
||||
@@ -21,6 +21,13 @@ func Test_strchars()
|
||||
call assert_equal(exp[i][1], inp[i]->strchars(0))
|
||||
call assert_equal(exp[i][2], strchars(inp[i], 1))
|
||||
endfor
|
||||
|
||||
let exp = [1, 3, 1, 1, 1]
|
||||
for i in range(len(inp))
|
||||
call assert_equal(exp[i], inp[i]->strcharlen())
|
||||
call assert_equal(exp[i], strcharlen(inp[i]))
|
||||
endfor
|
||||
|
||||
call assert_fails("let v=strchars('abc', [])", 'E745:')
|
||||
call assert_fails("let v=strchars('abc', 2)", 'E1023:')
|
||||
endfunc
|
||||
|
Reference in New Issue
Block a user