diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-08-23 17:34:46 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-08-23 17:34:46 +0200 |
commit | 6c53fca02301ff871cddc1c74c388e23e53a424a (patch) | |
tree | a4cec7dd695a51465d06922b5c18a30d6b45509b | |
parent | 430deb1945cbc7a17ed42c5c737fc08d2eef327a (diff) | |
download | vim-git-8.2.1517.tar.gz |
patch 8.2.1517: cannot easily get the character under the cursorv8.2.1517
Problem: Cannot easily get the character under the cursor.
Solution: Add the {chars} argument to strpart().
-rw-r--r-- | runtime/doc/eval.txt | 26 | ||||
-rw-r--r-- | src/evalfunc.c | 18 | ||||
-rw-r--r-- | src/testdir/test_functions.vim | 4 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 36 insertions, 14 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 370964e56..09ef97963 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2836,7 +2836,8 @@ str2list({expr} [, {utf8}]) List convert each character of {expr} to str2nr({expr} [, {base} [, {quoted}]]) Number convert String to Number 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} strdisplaywidth({expr} [, {col}]) Number display length of the String {expr} strftime({format} [, {time}]) String format time with a specified format @@ -2845,8 +2846,9 @@ stridx({haystack}, {needle} [, {start}]) Number index of {needle} in {haystack} string({expr}) String String representation of {expr} value strlen({expr}) Number length of the String {expr} -strpart({str}, {start} [, {len}]) - String {len} bytes of {str} at byte {start} +strpart({str}, {start} [, {len} [, {chars}]]) + String {len} bytes/chars of {str} at + byte {start} strptime({format}, {timestring}) Number Convert {timestring} to unix timestamp strridx({haystack}, {needle} [, {start}]) @@ -3418,7 +3420,8 @@ byte2line({byte}) *byte2line()* byteidx({expr}, {nr}) *byteidx()* 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 characters, otherwise the returned value is equal to {nr}. 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. If the argument is a Number it is first converted to a String. 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()|. Also see |len()|, |strdisplaywidth()| and |strwidth()|. Can also be used as a |method|: > 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 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 result in an error, the bytes are simply omitted. @@ -9970,8 +9978,8 @@ strpart({src}, {start} [, {len}]) *strpart()* strpart("abcdefg", 3) == "defg" < Note: To get the first character, {start} must be 0. For - example, to get three bytes under and after the cursor: > - strpart(getline("."), col(".") - 1, 3) + example, to get the character under the cursor: > + strpart(getline("."), col(".") - 1, 1, v:true) < Can also be used as a |method|: > GetText()->strpart(5) diff --git a/src/evalfunc.c b/src/evalfunc.c index c8747e2c1..fcfd4b10d 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -950,7 +950,7 @@ static funcentry_T global_functions[] = {"stridx", 2, 3, FEARG_1, ret_number, f_stridx}, {"string", 1, 1, FEARG_1, ret_string, f_string}, {"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, #ifdef HAVE_STRPTIME f_strptime @@ -8270,10 +8270,8 @@ f_strpart(typval_T *argvars, typval_T *rettv) else len = slen - n; // default len: all bytes that are available. - /* - * Only return the overlap between the specified part and the actual - * string. - */ + // Only return the overlap between the specified part and the actual + // string. if (n < 0) { len += n; @@ -8286,6 +8284,16 @@ f_strpart(typval_T *argvars, typval_T *rettv) else if (n + len > slen) 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->vval.v_string = vim_strnsave(p + n, len); } diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index dc06bd72e..e15199b78 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -513,6 +513,10 @@ func Test_strpart() call assert_equal('lép', strpart('éléphant', 2, 4)) 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 func Test_tolower() diff --git a/src/version.c b/src/version.c index 4c2794af0..9eb448b2d 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1517, +/**/ 1516, /**/ 1515, |