vim-patch:7.4.951

Problem:    Sorting number strings does not work as expected. (Luc Hermitte)
Solution:   Add the 'N" argument to sort()

b00da1d6d1
This commit is contained in:
watiko 2016-02-20 17:18:23 +09:00
parent 576c5f7b74
commit f6dca79f3a
6 changed files with 48 additions and 3 deletions

View File

@ -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: >

View File

@ -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);
}

View File

@ -39,7 +39,8 @@ SCRIPTS := \
test_marks.out \
test_match_conceal.out \
NEW_TESTS =
NEW_TESTS := \
test_alot.res \
SCRIPTS_GUI := test16.out

View File

@ -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

View File

@ -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

View File

@ -339,7 +339,7 @@ static int included_patches[] = {
// 954 NA
953,
952,
// 951,
951,
950,
949,
// 948 NA