# HG changeset patch # User Bram Moolenaar # Date 1645623003 -3600 # Node ID 3cb1a109e9877310130ccbda83f0b26c0deb3b22 # Parent 6197d182d7076487be730df38d5be90200219af2 patch 8.2.4455: accepting one and zero for second sort() argument is strange Commit: https://github.com/vim/vim/commit/2007dd49f5cb36f944cab1cfbceb0f864e625f74 Author: Bram Moolenaar Date: Wed Feb 23 13:17:47 2022 +0000 patch 8.2.4455: accepting one and zero for second sort() argument is strange Problem: Accepting one and zero for the second sort() argument is strange. Solution: Disallow using one and zero in Vim9 script. diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -539,8 +539,8 @@ sin({expr}) Float sine of {expr} sinh({expr}) Float hyperbolic sine of {expr} slice({expr}, {start} [, {end}]) String, List or Blob slice of a String, List or Blob -sort({list} [, {func} [, {dict}]]) - List sort {list}, using {func} to compare +sort({list} [, {how} [, {dict}]]) + List sort {list}, compare with {how} sound_clear() none stop playing all sounds sound_playevent({name} [, {callback}]) Number play an event sound @@ -8033,21 +8033,22 @@ slice({expr}, {start} [, {end}]) *slic GetList()->slice(offset) -sort({list} [, {func} [, {dict}]]) *sort()* *E702* +sort({list} [, {how} [, {dict}]]) *sort()* *E702* Sort the items in {list} in-place. Returns {list}. If you want a list to remain unmodified make a copy first: > :let sortedlist = sort(copy(mylist)) -< When {func} is omitted, is empty or zero, then sort() uses the +< When {how} is omitted or is an string, then sort() uses the string representation of each item to sort on. Numbers sort after Strings, |Lists| after Numbers. For sorting text in the current buffer use |:sort|. - When {func} is given and it is '1' or 'i' then case is - ignored. - - When {func} is given and it is 'l' then the current collation + When {how} is given and it is 'i' then case is ignored. + In legacy script, for backwards compatibility, the value one + can be used to ignore case. Zero means to not ignore case. + + When {how} is given and it is 'l' then the current collation locale is used for ordering. Implementation details: strcoll() is used to compare strings. See |:language| check or set the collation locale. |v:collate| can also be used to check the @@ -8064,19 +8065,19 @@ sort({list} [, {func} [, {dict}]]) *so < ['n', 'o', 'O', 'p', 'z', 'รถ'] ~ This does not work properly on Mac. - When {func} is given and it is 'n' then all items will be + When {how} is given and it is 'n' then all items will be sorted numerical (Implementation detail: this uses the strtod() function to parse numbers, Strings, Lists, Dicts and Funcrefs will be considered as being 0). - When {func} is given and it is 'N' then all items will be + When {how} is given and it is 'N' then all items will be sorted numerical. This is like 'n' but a string containing digits will be used as the number they represent. - When {func} is given and it is 'f' then all items will be + When {how} is given and it is 'f' then all items will be sorted numerical. All values must be a Number or a Float. - When {func} is a |Funcref| or a function name, this function + When {how} is a |Funcref| or a function name, this function is called to compare items. The function is invoked with two items as argument and must return zero if they are equal, 1 or bigger if the first one sorts after the second one, -1 or diff --git a/runtime/menu.vim b/runtime/menu.vim --- a/runtime/menu.vim +++ b/runtime/menu.vim @@ -2,7 +2,7 @@ " You can also use this as a start for your own set of menus. " " Maintainer: Bram Moolenaar -" Last Change: 2022 Feb 04 +" Last Change: 2022 Feb 23 " Note that ":an" (short for ":anoremenu") is often used to make a menu work " in all modes and avoid side effects from mappings defined by the user. @@ -378,7 +378,7 @@ def s:SetupColorSchemes() n += globpath(&packpath, "pack/*/opt/*/colors/*.vim", 1, 1) # Ignore case for VMS and windows, sort on name - var names = sort(map(n, 'substitute(v:val, "\\c.*[/\\\\:\\]]\\([^/\\\\:]*\\)\\.vim", "\\1", "")'), 1) + var names = sort(map(n, 'substitute(v:val, "\\c.*[/\\\\:\\]]\\([^/\\\\:]*\\)\\.vim", "\\1", "")'), 'i') # define all the submenu entries var idx = 100 diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -603,7 +603,6 @@ arg_sort_how(type_T *type, type_T *decl_ { if (type->tt_type == VAR_STRING || type->tt_type == VAR_PARTIAL - || type->tt_type == VAR_NUMBER // 1 means ignore case || type == &t_unknown || type == &t_any) return OK; diff --git a/src/list.c b/src/list.c --- a/src/list.c +++ b/src/list.c @@ -2198,7 +2198,8 @@ do_sort_uniq(typval_T *argvars, typval_T if (in_vim9script() && (check_for_list_arg(argvars, 0) == FAIL || (argvars[1].v_type != VAR_UNKNOWN - && check_for_opt_dict_arg(argvars, 2) == FAIL))) + && (check_for_string_or_func_arg(argvars, 1) == FAIL + || check_for_opt_dict_arg(argvars, 2) == FAIL)))) return; if (argvars[0].v_type != VAR_LIST) diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -949,7 +949,7 @@ func Test_reverse_sort_uniq() call assert_equal([-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255], sort(copy(l), 'n')) LET l = [7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', {}, []] - call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1)) + call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i')) call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i')) call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l))) endif @@ -961,6 +961,16 @@ func Test_reverse_sort_uniq() call assert_fails("call sort([1, 2], function('min'), 1)", "E715:") call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:") call assert_fails("call sort([1, 2], function('min'))", "E118:") + + let lines =<< trim END + call sort(['a', 'b'], 0) + END + call v9.CheckDefAndScriptFailure(lines, 'E1256: String or function required for argument 2') + + let lines =<< trim END + call sort(['a', 'b'], 1) + END + call v9.CheckDefAndScriptFailure(lines, 'E1256: String or function required for argument 2') endfunc " reduce a list, blob or string diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4455, +/**/ 4454, /**/ 4453,