diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-08-23 18:03:41 -0400 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-08-23 18:32:39 -0400 |
commit | 107e50b25e4b9098c0d1b4c34fec4bb17a9c7ad7 (patch) | |
tree | 342665a263ff3d076b8d28df9b46f78eb4275187 | |
parent | bf8d96a30d27d123de723aa8985cf73588a08eea (diff) | |
download | rneovim-107e50b25e4b9098c0d1b4c34fec4bb17a9c7ad7.tar.gz rneovim-107e50b25e4b9098c0d1b4c34fec4bb17a9c7ad7.tar.bz2 rneovim-107e50b25e4b9098c0d1b4c34fec4bb17a9c7ad7.zip |
vim-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().
https://github.com/vim/vim/commit/6c53fca02301ff871cddc1c74c388e23e53a424a
-rw-r--r-- | runtime/doc/eval.txt | 26 | ||||
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 10 | ||||
-rw-r--r-- | src/nvim/testdir/test_functions.vim | 4 |
4 files changed, 32 insertions, 10 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 448885296d..ca03ee0374 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2409,7 +2409,8 @@ str2list({expr} [, {utf8}]) List convert each character of {expr} to str2nr({expr} [, {base}]) Number convert String to Number strchars({expr} [, {skipcc}]) Number character length of the String {expr} strcharpart({str}, {start} [, {len}]) - String {len} characters of {str} at {start} + String {len} characters of {str} at + character {start} strdisplaywidth({expr} [, {col}]) Number display length of the String {expr} strftime({format} [, {time}]) String time in specified format strgetchar({str}, {index}) Number get char {index} from {str} @@ -2417,8 +2418,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} characters of {str} at {start} +strpart({str}, {start} [, {len} [, {chars}]]) + String {len} bytes/chars of {str} at + byte {start} strridx({haystack}, {needle} [, {start}]) Number last index of {needle} in {haystack} strtrans({expr}) String translate string to make it printable @@ -2906,7 +2908,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 @@ -8438,14 +8441,19 @@ 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()|. -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. @@ -8457,8 +8465,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) < strridx({haystack}, {needle} [, {start}]) *strridx()* The result is a Number, which gives the byte index in diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index a5544435d2..be16ddd7f6 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -336,7 +336,7 @@ return { stridx={args={2, 3}}, string={args=1}, strlen={args=1}, - strpart={args={2, 3}}, + strpart={args={2, 4}}, strridx={args={2, 3}}, strtrans={args=1}, strwidth={args=1}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 18e514b9a0..8e0e420eb0 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -9946,6 +9946,16 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 < (int)slen && len > 0; len--) { + off += utfc_ptr2len((char_u *)p + off); + } + len = off - n; + } + rettv->v_type = VAR_STRING; rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len); } diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 51689db9c4..6b45ac61d1 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -334,6 +334,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() |