diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_cmds.c | 25 | ||||
-rw-r--r-- | src/nvim/testdir/test_sort.vim | 71 |
2 files changed, 89 insertions, 7 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0b57f9cc3a..97bddb3258 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -366,7 +366,10 @@ typedef struct { varnumber_T start_col_nr; ///< starting column number varnumber_T end_col_nr; ///< ending column number } line; - varnumber_T value; ///< value if sorting by integer + struct { + varnumber_T value; ///< value if sorting by integer + bool is_number; ///< true when line contains a number + } num; float_T value_flt; ///< value if sorting by float } st_u; } sorti_T; @@ -390,9 +393,15 @@ static int sort_compare(const void *s1, const void *s2) // When sorting numbers "start_col_nr" is the number, not the column // number. if (sort_nr) { - result = l1.st_u.value == l2.st_u.value - ? 0 : l1.st_u.value > l2.st_u.value - ? 1 : -1; + if (l1.st_u.num.is_number != l2.st_u.num.is_number) { + result = l1.st_u.num.is_number - l2.st_u.num.is_number; + } else { + result = l1.st_u.num.value == l2.st_u.num.value + ? 0 + : l1.st_u.num.value > l2.st_u.num.value + ? 1 + : -1; + } } else if (sort_flt) { result = l1.st_u.value_flt == l2.st_u.value_flt ? 0 : l1.st_u.value_flt > l2.st_u.value_flt @@ -567,11 +576,13 @@ void ex_sort(exarg_T *eap) s--; // include preceding negative sign } if (*s == NUL) { - // empty line should sort before any number - nrs[lnum - eap->line1].st_u.value = -MAXLNUM; + // line without number should sort before any number + nrs[lnum - eap->line1].st_u.num.is_number = false; + nrs[lnum - eap->line1].st_u.num.value = 0; } else { + nrs[lnum - eap->line1].st_u.num.is_number = true; vim_str2nr(s, NULL, NULL, sort_what, - &nrs[lnum - eap->line1].st_u.value, NULL, 0); + &nrs[lnum - eap->line1].st_u.num.value, NULL, 0); } } else { s = skipwhite(p); diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim index 14d008a17f..7da82b0185 100644 --- a/src/nvim/testdir/test_sort.vim +++ b/src/nvim/testdir/test_sort.vim @@ -1222,6 +1222,77 @@ func Test_sort_cmd() enew! endfunc +func Test_sort_large_num() + new + a +-2147483648 +-2147483647 + +-1 +0 +1 +-2147483646 +2147483646 +2147483647 +2147483647 +-2147483648 +abc + +. + " Numerical sort. Non-numeric lines are ordered before numerical lines. + " Ordering of non-numerical is stable. + sort n + call assert_equal(['', + \ 'abc', + \ '', + \ '-2147483648', + \ '-2147483648', + \ '-2147483647', + \ '-2147483646', + \ '-1', + \ '0', + \ '1', + \ '2147483646', + \ '2147483647', + \ '2147483647'], getline(1, '$')) + bwipe! + + if has('num64') + new + a +-9223372036854775808 +-9223372036854775807 + +-1 +0 +1 +-9223372036854775806 +9223372036854775806 +9223372036854775807 +9223372036854775807 +-9223372036854775808 +abc + +. + sort n + call assert_equal(['', + \ 'abc', + \ '', + \ '-9223372036854775808', + \ '-9223372036854775808', + \ '-9223372036854775807', + \ '-9223372036854775806', + \ '-1', + \ '0', + \ '1', + \ '9223372036854775806', + \ '9223372036854775807', + \ '9223372036854775807'], getline(1, '$')) + bwipe! + endif +endfunc + + func Test_sort_cmd_report() enew! call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3)) |