0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.2.1517: cannot easily get the character under the cursor

Problem:    Cannot easily get the character under the cursor.
Solution:   Add the {chars} argument to strpart().
This commit is contained in:
Bram Moolenaar
2020-08-23 17:34:46 +02:00
parent 430deb1945
commit 6c53fca023
4 changed files with 36 additions and 14 deletions

View File

@@ -2836,7 +2836,8 @@ str2list({expr} [, {utf8}]) List convert each character of {expr} to
str2nr({expr} [, {base} [, {quoted}]]) str2nr({expr} [, {base} [, {quoted}]])
Number convert String to Number Number convert String to Number
strcharpart({str}, {start} [, {len}]) strcharpart({str}, {start} [, {len}])
String {len} characters of {str} at {start} String {len} characters of {str} at
character {start}
strchars({expr} [, {skipcc}]) 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} strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
strftime({format} [, {time}]) String format time with a specified format strftime({format} [, {time}]) String format time with a specified format
@@ -2845,8 +2846,9 @@ stridx({haystack}, {needle} [, {start}])
Number index of {needle} in {haystack} Number index of {needle} in {haystack}
string({expr}) String String representation of {expr} value string({expr}) String String representation of {expr} value
strlen({expr}) Number length of the String {expr} strlen({expr}) Number length of the String {expr}
strpart({str}, {start} [, {len}]) strpart({str}, {start} [, {len} [, {chars}]])
String {len} bytes of {str} at byte {start} String {len} bytes/chars of {str} at
byte {start}
strptime({format}, {timestring}) strptime({format}, {timestring})
Number Convert {timestring} to unix timestamp Number Convert {timestring} to unix timestamp
strridx({haystack}, {needle} [, {start}]) strridx({haystack}, {needle} [, {start}])
@@ -3418,7 +3420,8 @@ byte2line({byte}) *byte2line()*
byteidx({expr}, {nr}) *byteidx()* byteidx({expr}, {nr}) *byteidx()*
Return byte index of the {nr}'th character in the string Return byte index of the {nr}'th character in the string
{expr}. Use zero for the first character, it returns zero. {expr}. Use zero for the first character, it then returns
zero.
This function is only useful when there are multibyte This function is only useful when there are multibyte
characters, otherwise the returned value is equal to {nr}. characters, otherwise the returned value is equal to {nr}.
Composing characters are not counted separately, their byte Composing characters are not counted separately, their byte
@@ -9948,17 +9951,22 @@ strlen({expr}) The result is a Number, which is the length of the String
{expr} in bytes. {expr} in bytes.
If the argument is a Number it is first converted to a String. If the argument is a Number it is first converted to a String.
For other types an error is given. For other types an error is given.
If you want to count the number of multi-byte characters use If you want to count the number of multibyte characters use
|strchars()|. |strchars()|.
Also see |len()|, |strdisplaywidth()| and |strwidth()|. Also see |len()|, |strdisplaywidth()| and |strwidth()|.
Can also be used as a |method|: > Can also be used as a |method|: >
GetString()->strlen() GetString()->strlen()
strpart({src}, {start} [, {len}]) *strpart()* strpart({src}, {start} [, {len} [, {chars}]]) *strpart()*
The result is a String, which is part of {src}, starting from The result is a String, which is part of {src}, starting from
byte {start}, with the byte length {len}. byte {start}, with the byte length {len}.
To count characters instead of bytes use |strcharpart()|. When {chars} is present and TRUE then {len} is the number of
characters positions (composing characters are not counted
separately, thus "1" means one base character and any
following composing characters).
To count {start} as characters instead of bytes use
|strcharpart()|.
When bytes are selected which do not exist, this doesn't When bytes are selected which do not exist, this doesn't
result in an error, the bytes are simply omitted. result in an error, the bytes are simply omitted.
@@ -9970,8 +9978,8 @@ strpart({src}, {start} [, {len}]) *strpart()*
strpart("abcdefg", 3) == "defg" strpart("abcdefg", 3) == "defg"
< Note: To get the first character, {start} must be 0. For < Note: To get the first character, {start} must be 0. For
example, to get three bytes under and after the cursor: > example, to get the character under the cursor: >
strpart(getline("."), col(".") - 1, 3) strpart(getline("."), col(".") - 1, 1, v:true)
< <
Can also be used as a |method|: > Can also be used as a |method|: >
GetText()->strpart(5) GetText()->strpart(5)

View File

@@ -950,7 +950,7 @@ static funcentry_T global_functions[] =
{"stridx", 2, 3, FEARG_1, ret_number, f_stridx}, {"stridx", 2, 3, FEARG_1, ret_number, f_stridx},
{"string", 1, 1, FEARG_1, ret_string, f_string}, {"string", 1, 1, FEARG_1, ret_string, f_string},
{"strlen", 1, 1, FEARG_1, ret_number, f_strlen}, {"strlen", 1, 1, FEARG_1, ret_number, f_strlen},
{"strpart", 2, 3, FEARG_1, ret_string, f_strpart}, {"strpart", 2, 4, FEARG_1, ret_string, f_strpart},
{"strptime", 2, 2, FEARG_1, ret_number, {"strptime", 2, 2, FEARG_1, ret_number,
#ifdef HAVE_STRPTIME #ifdef HAVE_STRPTIME
f_strptime f_strptime
@@ -8270,10 +8270,8 @@ f_strpart(typval_T *argvars, typval_T *rettv)
else else
len = slen - n; // default len: all bytes that are available. len = slen - n; // default len: all bytes that are available.
/* // Only return the overlap between the specified part and the actual
* Only return the overlap between the specified part and the actual // string.
* string.
*/
if (n < 0) if (n < 0)
{ {
len += n; len += n;
@@ -8286,6 +8284,16 @@ f_strpart(typval_T *argvars, typval_T *rettv)
else if (n + len > slen) else if (n + len > slen)
len = slen - n; len = slen - n;
if (argvars[2].v_type != VAR_UNKNOWN && argvars[3].v_type != VAR_UNKNOWN)
{
int off;
// length in characters
for (off = n; off < slen && len > 0; --len)
off += mb_ptr2len(p + off);
len = off - n;
}
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strnsave(p + n, len); rettv->vval.v_string = vim_strnsave(p + n, len);
} }

View File

@@ -513,6 +513,10 @@ func Test_strpart()
call assert_equal('lép', strpart('éléphant', 2, 4)) call assert_equal('lép', strpart('éléphant', 2, 4))
call assert_equal('léphant', strpart('éléphant', 2)) call assert_equal('léphant', strpart('éléphant', 2))
call assert_equal('é', strpart('éléphant', 0, 1, 1))
call assert_equal('ép', strpart('éléphant', 3, 2, v:true))
call assert_equal('ó', strpart('cómposed', 1, 1, 1))
endfunc endfunc
func Test_tolower() func Test_tolower()

View File

@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1517,
/**/ /**/
1516, 1516,
/**/ /**/