To: vim_dev@googlegroups.com Subject: Patch 7.4.951 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.951 Problem: Sorting number strings does not work as expected. (Luc Hermitte) Solution: Add the 'N" argument to sort() Files: src/eval.c, runtime/doc/eval.txt, src/testdir/test_alot.vim, src/testdir/test_sort.vim, src/testdir/Makefile *** ../vim-7.4.950/src/eval.c 2015-12-03 14:55:49.606829394 +0100 --- src/eval.c 2015-12-03 16:21:24.923476442 +0100 *************** *** 17928,17933 **** --- 17928,17934 ---- 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,17963 **** --- 17959,17973 ---- 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,18096 **** --- 18101,18107 ---- 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,18121 **** --- 18127,18137 ---- 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; *** ../vim-7.4.950/runtime/doc/eval.txt 2015-11-30 21:37:23.596219585 +0100 --- runtime/doc/eval.txt 2015-12-03 16:06:30.317133724 +0100 *************** *** 5763,5768 **** --- 5803,5812 ---- 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 *************** *** 5772,5777 **** --- 5816,5826 ---- {dict} is for functions with the "dict" attribute. It will be used to set the local variable "self". |Dictionary-function| + 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: > *** ../vim-7.4.950/src/testdir/test_alot.vim 2015-12-03 16:30:58.857280913 +0100 --- src/testdir/test_alot.vim 2015-12-03 16:18:15.065525945 +0100 *************** *** 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 *** ../vim-7.4.950/src/testdir/test_sort.vim 2015-12-03 16:30:58.865280827 +0100 --- src/testdir/test_sort.vim 2015-12-03 16:25:04.101110445 +0100 *************** *** 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 *** ../vim-7.4.950/src/testdir/Makefile 2015-11-30 21:37:23.596219585 +0100 --- src/testdir/Makefile 2015-12-03 16:19:43.264573841 +0100 *************** *** 69,75 **** test_writefile.out NEW_TESTS = test_assert.res \ ! test_undolevels.res SCRIPTS_GUI = test16.out --- 69,75 ---- test_writefile.out NEW_TESTS = test_assert.res \ ! test_alot.res SCRIPTS_GUI = test16.out *** ../vim-7.4.950/src/version.c 2015-12-03 14:55:49.606829394 +0100 --- src/version.c 2015-12-03 16:19:21.824805283 +0100 *************** *** 743,744 **** --- 743,746 ---- { /* Add new patch number below this line */ + /**/ + 951, /**/ -- If Microsoft would build a car... ... Occasionally your car would die on the freeway for no reason. You would have to pull over to the side of the road, close all of the car windows, shut it off, restart it, and reopen the windows before you could continue. For some reason you would simply accept this. /// 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 ///