mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
vim-patch:8.2.2607: strcharpart() cannot include composing characters
Problem: strcharpart() cannot include composing characters.
Solution: Add the {skipcc} argument.
02b4d9b18a
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@ -486,7 +486,7 @@ str2list({expr} [, {utf8}]) List convert each character of {expr} to
|
||||
str2nr({expr} [, {base} [, {quoted}]])
|
||||
Number convert String to Number
|
||||
strcharlen({expr}) Number character length of the String {expr}
|
||||
strcharpart({str}, {start} [, {len}])
|
||||
strcharpart({str}, {start} [, {len} [, {skipcc}]])
|
||||
String {len} characters of {str} at
|
||||
character {start}
|
||||
strchars({expr} [, {skipcc}]) Number character count of the String {expr}
|
||||
@ -7779,6 +7779,7 @@ slice({expr}, {start} [, {end}]) *slice()*
|
||||
Similar to using a |slice| "expr[start : end]", but "end" is
|
||||
used exclusive. And for a string the indexes are used as
|
||||
character indexes instead of byte indexes.
|
||||
Also, composing characters are not counted.
|
||||
When {end} is omitted the slice continues to the last item.
|
||||
When {end} is -1 the last item is omitted.
|
||||
Returns an empty value if {start} or {end} are invalid.
|
||||
@ -8129,12 +8130,16 @@ strcharlen({string}) *strcharlen()*
|
||||
GetText()->strcharlen()
|
||||
|
||||
|
||||
strcharpart({src}, {start} [, {len}]) *strcharpart()*
|
||||
strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()*
|
||||
Like |strpart()| but using character index and length instead
|
||||
of byte index and length. Composing characters are counted
|
||||
separately.
|
||||
of byte index and length.
|
||||
When {skipcc} is omitted or zero, composing characters are
|
||||
counted separately.
|
||||
When {skipcc} set to 1, Composing characters are ignored,
|
||||
similar to |slice()|.
|
||||
When a character index is used where a character does not
|
||||
exist it is assumed to be one character. For example: >
|
||||
exist it is omitted and counted as one character. For
|
||||
example: >
|
||||
strcharpart('abc', -1, 2)
|
||||
< results in 'a'.
|
||||
|
||||
|
@ -386,7 +386,7 @@ return {
|
||||
str2list={args={1, 2}, base=1},
|
||||
str2nr={args={1, 3}, base=1},
|
||||
strcharlen={args=1, base=1},
|
||||
strcharpart={args={2, 3}, base=1, fast=true},
|
||||
strcharpart={args={2, 4}, base=1, fast=true},
|
||||
strchars={args={1, 2}, base=1},
|
||||
strdisplaywidth={args={1, 2}, base=1},
|
||||
strftime={args={1, 2}, base=1},
|
||||
|
@ -1834,12 +1834,26 @@ void f_strcharpart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
const size_t slen = strlen(p);
|
||||
|
||||
int nbyte = 0;
|
||||
varnumber_T skipcc = false;
|
||||
bool error = false;
|
||||
varnumber_T nchar = tv_get_number_chk(&argvars[1], &error);
|
||||
if (!error) {
|
||||
if (argvars[2].v_type != VAR_UNKNOWN
|
||||
&& argvars[3].v_type != VAR_UNKNOWN) {
|
||||
skipcc = tv_get_bool(&argvars[3]);
|
||||
if (skipcc < 0 || skipcc > 1) {
|
||||
semsg(_(e_using_number_as_bool_nr), skipcc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nchar > 0) {
|
||||
while (nchar > 0 && (size_t)nbyte < slen) {
|
||||
nbyte += utf_ptr2len(p + nbyte);
|
||||
if (skipcc) {
|
||||
nbyte += utfc_ptr2len(p + nbyte);
|
||||
} else {
|
||||
nbyte += utf_ptr2len(p + nbyte);
|
||||
}
|
||||
nchar--;
|
||||
}
|
||||
} else {
|
||||
@ -1855,7 +1869,11 @@ void f_strcharpart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
if (off < 0) {
|
||||
len += 1;
|
||||
} else {
|
||||
len += utf_ptr2len(p + off);
|
||||
if (skipcc) {
|
||||
len += utfc_ptr2len(p + off);
|
||||
} else {
|
||||
len += utf_ptr2len(p + off);
|
||||
}
|
||||
}
|
||||
charlen--;
|
||||
}
|
||||
|
@ -31,4 +31,14 @@ func Test_strcharpart()
|
||||
call assert_equal('a', strcharpart('àxb', 0, 1))
|
||||
call assert_equal('̀', strcharpart('àxb', 1, 1))
|
||||
call assert_equal('x', strcharpart('àxb', 2, 1))
|
||||
|
||||
|
||||
call assert_equal('a', strcharpart('àxb', 0, 1, 0))
|
||||
call assert_equal('à', strcharpart('àxb', 0, 1, 1))
|
||||
call assert_equal('x', strcharpart('àxb', 1, 1, 1))
|
||||
|
||||
call assert_fails("let v = strcharpart('abc', 0, 0, [])", 'E745:')
|
||||
call assert_fails("let v = strcharpart('abc', 0, 0, 2)", 'E1023:')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
Reference in New Issue
Block a user