diff options
author | Bram Moolenaar <Bram@vim.org> | 2015-12-03 16:33:12 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2015-12-03 16:33:12 +0100 |
commit | b00da1d6d1655cb6e415f84ecc3be5ff3b790811 (patch) | |
tree | b7ee0b6575e0f80ad0a2bc15739063d32329d565 | |
parent | 4649ded2877508fe343cbcf6f7e7fd277be0aab3 (diff) | |
download | vim-git-b00da1d6d1655cb6e415f84ecc3be5ff3b790811.tar.gz |
patch 7.4.951v7.4.951
Problem: Sorting number strings does not work as expected. (Luc Hermitte)
Solution: Add the 'N" argument to sort()
-rw-r--r-- | runtime/doc/eval.txt | 9 | ||||
-rw-r--r-- | src/eval.c | 16 | ||||
-rw-r--r-- | src/testdir/Makefile | 2 | ||||
-rw-r--r-- | src/testdir/test_alot.vim | 5 | ||||
-rw-r--r-- | src/testdir/test_sort.vim | 19 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 52 insertions, 1 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 9442996be..2e89098a6 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -5803,6 +5803,10 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702* 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 + sorted numerical. This is like 'n' but a string containing + digits will be used as the number they represent. + When {func} 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 @@ -5817,6 +5821,11 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702* on numbers, text strings will sort next to each other, in the same order as they were originally. + The sort is stable, items which compare equal (as number or as + string) will keep their relative position. E.g., when sorting + on numbers, text strings will sort next to each other, in the + same order as they were originally. + Also see |uniq()|. Example: > diff --git a/src/eval.c b/src/eval.c index 2d6c34b92..ef0ea5ee2 100644 --- a/src/eval.c +++ b/src/eval.c @@ -17928,6 +17928,7 @@ typedef struct static int item_compare_ic; static int item_compare_numeric; +static int item_compare_numbers; static char_u *item_compare_func; static dict_T *item_compare_selfdict; static int item_compare_func_err; @@ -17958,6 +17959,15 @@ item_compare(s1, s2) si2 = (sortItem_T *)s2; tv1 = &si1->item->li_tv; tv2 = &si2->item->li_tv; + + if (item_compare_numbers) + { + long v1 = get_tv_number(tv1); + long v2 = get_tv_number(tv2); + + return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; + } + /* tv2string() puts quotes around a string and allocates memory. Don't do * that for string variables. Use a single quote when comparing with a * non-string to do what the docs promise. */ @@ -18091,6 +18101,7 @@ do_sort_uniq(argvars, rettv, sort) item_compare_ic = FALSE; item_compare_numeric = FALSE; + item_compare_numbers = FALSE; item_compare_func = NULL; item_compare_selfdict = NULL; if (argvars[1].v_type != VAR_UNKNOWN) @@ -18116,6 +18127,11 @@ do_sort_uniq(argvars, rettv, sort) item_compare_func = NULL; item_compare_numeric = TRUE; } + else if (STRCMP(item_compare_func, "N") == 0) + { + item_compare_func = NULL; + item_compare_numbers = TRUE; + } else if (STRCMP(item_compare_func, "i") == 0) { item_compare_func = NULL; diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 3f65f435d..c7db9495e 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -69,7 +69,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ test_writefile.out NEW_TESTS = test_assert.res \ - test_undolevels.res + test_alot.res SCRIPTS_GUI = test16.out diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim new file mode 100644 index 000000000..97635095b --- /dev/null +++ b/src/testdir/test_alot.vim @@ -0,0 +1,5 @@ +" A series of tests that can run in one Vim invocation. +" This makes testing go faster, since Vim doesn't need to restart. + +source test_undolevels.vim +source test_sort.vim diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim new file mode 100644 index 000000000..30dd167cd --- /dev/null +++ b/src/testdir/test_sort.vim @@ -0,0 +1,19 @@ +" Test sort() + +func Test_sort_strings() + " numbers compared as strings + call assert_equal([1, 2, 3], sort([3, 2, 1])) + call assert_equal([13, 28, 3], sort([3, 28, 13])) +endfunc + +func Test_sort_numeric() + call assert_equal([1, 2, 3], sort([3, 2, 1], 'n')) + call assert_equal([3, 13, 28], sort([13, 28, 3], 'n')) + " strings are not sorted + call assert_equal(['13', '28', '3'], sort(['13', '28', '3'], 'n')) +endfunc + +func Test_sort_numbers() + call assert_equal([3, 13, 28], sort([13, 28, 3], 'N')) + call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N')) +endfunc diff --git a/src/version.c b/src/version.c index 31273feb2..4b2a1cbeb 100644 --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 951, +/**/ 950, /**/ 949, |