aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwatiko <service@mail.watiko.net>2016-02-20 17:18:23 +0900
committerwatiko <service@mail.watiko.net>2016-03-02 17:32:24 +0900
commitf6dca79f3aa2b55927a5f1cee4a6bf25d5c9bd37 (patch)
tree52c95d1a5b11bdd16b73e13a22a9d179cccac34a
parent576c5f7b74bfa46ba4c7290b5e5b951d3ee2d0bc (diff)
downloadrneovim-f6dca79f3aa2b55927a5f1cee4a6bf25d5c9bd37.tar.gz
rneovim-f6dca79f3aa2b55927a5f1cee4a6bf25d5c9bd37.tar.bz2
rneovim-f6dca79f3aa2b55927a5f1cee4a6bf25d5c9bd37.zip
vim-patch:7.4.951
Problem: Sorting number strings does not work as expected. (Luc Hermitte) Solution: Add the 'N" argument to sort() https://github.com/vim/vim/commit/b00da1d6d1655cb6e415f84ecc3be5ff3b790811
-rw-r--r--runtime/doc/eval.txt9
-rw-r--r--src/nvim/eval.c14
-rw-r--r--src/nvim/testdir/Makefile3
-rw-r--r--src/nvim/testdir/test_alot.vim4
-rw-r--r--src/nvim/testdir/test_sort.vim19
-rw-r--r--src/nvim/version.c2
6 files changed, 48 insertions, 3 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 0b2880ef03..36613ba6b3 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -6043,6 +6043,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
@@ -6057,6 +6061,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/nvim/eval.c b/src/nvim/eval.c
index 0e5da13242..c4e3781543 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -15748,6 +15748,7 @@ typedef struct {
static int item_compare_ic;
static bool item_compare_numeric;
+static bool item_compare_numbers;
static char_u *item_compare_func;
static dict_T *item_compare_selfdict;
static int item_compare_func_err;
@@ -15769,6 +15770,14 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
si2 = (sortItem_T *)s2;
typval_T *tv1 = &si1->item->li_tv;
typval_T *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.
@@ -15915,6 +15924,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
item_compare_ic = FALSE;
item_compare_numeric = false;
+ item_compare_numbers = false;
item_compare_func = NULL;
item_compare_selfdict = NULL;
@@ -15936,6 +15946,9 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
if (STRCMP(item_compare_func, "n") == 0) {
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;
item_compare_ic = TRUE;
@@ -22560,4 +22573,3 @@ static bool is_watched(dict_T *d)
{
return d && !QUEUE_EMPTY(&d->watchers);
}
-
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 63ca4cf6c4..9f54a5918c 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -39,7 +39,8 @@ SCRIPTS := \
test_marks.out \
test_match_conceal.out \
-NEW_TESTS =
+NEW_TESTS := \
+ test_alot.res \
SCRIPTS_GUI := test16.out
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
new file mode 100644
index 0000000000..ea2a19a08f
--- /dev/null
+++ b/src/nvim/testdir/test_alot.vim
@@ -0,0 +1,4 @@
+" 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_sort.vim
diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim
new file mode 100644
index 0000000000..30dd167cd6
--- /dev/null
+++ b/src/nvim/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/nvim/version.c b/src/nvim/version.c
index bc10187aa3..6701313db0 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -339,7 +339,7 @@ static int included_patches[] = {
// 954 NA
953,
952,
- // 951,
+ 951,
950,
949,
// 948 NA