I noticed that the :sort command always sets 'modified'. This patch makes :sort check whether or not it actually changed the buffer.
Tests included. Thanks, Jason Franklin -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
>From 12223983b375d7d2d10187167077b310bad6260b Mon Sep 17 00:00:00 2001 From: Jason Franklin <j_...@fastmail.us> Date: Tue, 26 Jun 2018 16:50:45 -0400 Subject: [PATCH] Make :sort only set &mod when the buffer changed --- src/ex_cmds.c | 11 +++++++++- src/testdir/test_sort.vim | 46 +++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 994ef0c5e..5a70b20c1 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -398,6 +398,7 @@ ex_sort(exarg_T *eap) colnr_T end_col; int sort_what = 0; int format_found = 0; + int change_occurred = FALSE; // Buffer contents changed. /* Sorting one line is really quick! */ if (count <= 1) @@ -616,6 +617,12 @@ ex_sort(exarg_T *eap) lnum = eap->line2; for (i = 0; i < count; ++i) { + + // If the original line number of the line being placed is not the same + // as "lnum" (accounting for offset), we know that the buffer changed. + if (nrs[eap->forceit ? count - i - 1 : i].lnum + (count - 1) != lnum) + change_occurred = TRUE; + s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum); if (!unique || i == 0 || (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0) @@ -644,7 +651,9 @@ ex_sort(exarg_T *eap) mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted); else if (deleted < 0) mark_adjust(eap->line2, MAXLNUM, -deleted, 0L); - changed_lines(eap->line1, 0, eap->line2 + 1, -deleted); + + if (change_occurred) + changed_lines(eap->line1, 0, eap->line2 + 1, -deleted); curwin->w_cursor.lnum = eap->line1; beginline(BL_WHITE | BL_FIX); diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim index 4fddb47b5..7d036df50 100644 --- a/src/testdir/test_sort.vim +++ b/src/testdir/test_sort.vim @@ -1,13 +1,13 @@ -" Test sort() +" Tests for the "sort()" function and for the ":sort" command. -:func Compare1(a, b) abort +func Compare1(a, b) abort call sort(range(3), 'Compare2') return a:a - a:b -:endfunc +endfunc -:func Compare2(a, b) abort +func Compare2(a, b) abort return a:a - a:b -:endfunc +endfunc func Test_sort_strings() " numbers compared as strings @@ -45,9 +45,9 @@ func Test_sort_default() call assert_fails('call sort([3.3, 1, "2"], 3)', "E474") endfunc -" Tests for the :sort command +" Tests for the ":sort" command. func Test_sort_cmd() - let tests = [ + let l:tests = [ \ { \ 'name' : 'Alphabetical sort', \ 'cmd' : '%sort', @@ -1167,15 +1167,39 @@ func Test_sort_cmd() \ '1.234', \ '123.456' \ ] + \ }, + \ { + \ 'name' : 'alphabetical, sorted input', + \ 'cmd' : 'sort', + \ 'input' : [ + \ 'a', + \ 'b', + \ 'c', + \ ], + \ 'expected' : [ + \ 'a', + \ 'b', + \ 'c', + \ ] \ } \ ] - for t in tests + for l:t in l:tests enew! - call append(0, t.input) + call append(0, l:t.input) $delete _ - exe t.cmd - call assert_equal(t.expected, getline(1, '$'), t.name) + setlocal nomodified + execute l:t.cmd + + call assert_equal(l:t.expected, getline(1, '$'), l:t.name) + + " Previously, the ":sort" command would set 'modified' even if the buffer + " contents did not change. Here, we check that this problem is fixed. + if l:t.input == l:t.expected + call assert_false(&modified, l:t.name . ': &mod is not correct') + else + call assert_true(&modified, l:t.name . ': &mod is not correct') + endif endfor call assert_fails('sort no', 'E474') -- 2.17.1