To: vim_dev@googlegroups.com Subject: Patch 8.2.1517 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1517 Problem: Cannot easily get the character under the cursor. Solution: Add the {chars} argument to strpart(). Files: runtime/doc/eval.txt, src/evalfunc.c, src/testdir/test_functions.vim *** ../vim-8.2.1516/runtime/doc/eval.txt 2020-08-17 21:07:17.941045702 +0200 --- runtime/doc/eval.txt 2020-08-23 17:21:49.883538057 +0200 *************** *** 2833,2840 **** 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} strptime({format}, {timestring}) Number Convert {timestring} to unix timestamp strridx({haystack}, {needle} [, {start}]) --- 2847,2855 ---- 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} [, {chars}]]) ! String {len} bytes/chars of {str} at ! byte {start} strptime({format}, {timestring}) Number Convert {timestring} to unix timestamp strridx({haystack}, {needle} [, {start}]) *************** *** 9905,9921 **** {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 |strchars()|. Also see |len()|, |strdisplaywidth()| and |strwidth()|. Can also be used as a |method|: > GetString()->strlen() ! strpart({src}, {start} [, {len}]) *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 bytes are selected which do not exist, this doesn't result in an error, the bytes are simply omitted. --- 9952,9973 ---- {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 multibyte characters use |strchars()|. Also see |len()|, |strdisplaywidth()| and |strwidth()|. Can also be used as a |method|: > GetString()->strlen() ! 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}. ! 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. *************** *** 9927,9934 **** 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) < Can also be used as a |method|: > GetText()->strpart(5) --- 9979,9986 ---- strpart("abcdefg", 3) == "defg" < Note: To get the first character, {start} must be 0. For ! 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) *** ../vim-8.2.1516/src/evalfunc.c 2020-08-20 15:02:38.540534948 +0200 --- src/evalfunc.c 2020-08-23 17:26:28.178765735 +0200 *************** *** 950,956 **** {"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}, {"strptime", 2, 2, FEARG_1, ret_number, #ifdef HAVE_STRPTIME f_strptime --- 950,956 ---- {"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, 4, FEARG_1, ret_string, f_strpart}, {"strptime", 2, 2, FEARG_1, ret_number, #ifdef HAVE_STRPTIME f_strptime *************** *** 8270,8279 **** else len = slen - n; // default len: all bytes that are available. ! /* ! * Only return the overlap between the specified part and the actual ! * string. ! */ if (n < 0) { len += n; --- 8270,8277 ---- else len = slen - n; // default len: all bytes that are available. ! // Only return the overlap between the specified part and the actual ! // string. if (n < 0) { len += n; *************** *** 8286,8291 **** --- 8284,8299 ---- 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); } *** ../vim-8.2.1516/src/testdir/test_functions.vim 2020-08-21 22:46:07.583820586 +0200 --- src/testdir/test_functions.vim 2020-08-23 17:30:40.214019258 +0200 *************** *** 513,518 **** --- 513,522 ---- 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() *** ../vim-8.2.1516/src/version.c 2020-08-23 16:29:07.737130996 +0200 --- src/version.c 2020-08-23 17:05:22.648922570 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1517, /**/ -- In war we're tough and able. Quite indefatigable Between our quests We sequin vests And impersonate Clark Gable It's a busy life in Camelot. I have to push the pram a lot. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///