]> granicus.if.org Git - vim/commitdiff
patch 8.1.0120: buffer 'modified' set even when :sort has no changes v8.1.0120
authorBram Moolenaar <Bram@vim.org>
Thu, 28 Jun 2018 09:28:08 +0000 (11:28 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 28 Jun 2018 09:28:08 +0000 (11:28 +0200)
Problem:    Buffer 'modified' set even when :sort has no changes.
Solution:   Only set 'modified' when lines are moved. (Jason Franklin)

src/ex_cmds.c
src/testdir/test_sort.vim
src/version.c

index 994ef0c5e9634eca7f5fe7026e240a77decc45ec..3384fe85bf7b19bf771c67e4c34efe10a5ca9bc1 100644 (file)
@@ -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,12 +617,19 @@ ex_sort(exarg_T *eap)
     lnum = eap->line2;
     for (i = 0; i < count; ++i)
     {
-       s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum);
+       linenr_T get_lnum = nrs[eap->forceit ? count - i - 1 : i].lnum;
+
+       // 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 (get_lnum + ((linenr_T)count - 1) != lnum)
+           change_occurred = TRUE;
+
+       s = ml_get(get_lnum);
        if (!unique || i == 0
                || (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0)
        {
-           /* Copy the line into a buffer, it may become invalid in
-            * ml_append(). And it's needed for "unique". */
+           // Copy the line into a buffer, it may become invalid in
+           // ml_append(). And it's needed for "unique".
            STRCPY(sortbuf1, s);
            if (ml_append(lnum++, sortbuf1, (colnr_T)0, FALSE) == FAIL)
                break;
@@ -644,7 +652,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 || deleted != 0)
+       changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
 
     curwin->w_cursor.lnum = eap->line1;
     beginline(BL_WHITE | BL_FIX);
index 4fddb47b58ce0bb60b02923b3c12bcb4d092c3f0..6dc1d468c0ef5822e4c4d55f90aeeb79c9c68d1e 100644 (file)
@@ -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,7 +45,7 @@ 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 = [
        \ {
@@ -1167,15 +1167,54 @@ func Test_sort_cmd()
        \       '1.234',
        \       '123.456'
        \    ]
-       \ }
+       \ },
+       \ {
+       \    'name' : 'alphabetical, sorted input',
+       \    'cmd' : 'sort',
+       \    'input' : [
+       \       'a',
+       \       'b',
+       \       'c',
+       \    ],
+       \    'expected' : [
+       \       'a',
+       \       'b',
+       \       'c',
+       \    ]
+       \ },
+       \ {
+       \    'name' : 'alphabetical, sorted input, unique at end',
+       \    'cmd' : 'sort u',
+       \    'input' : [
+       \       'aa',
+       \       'bb',
+       \       'cc',
+       \       'cc',
+       \    ],
+       \    'expected' : [
+       \       'aa',
+       \       'bb',
+       \       'cc',
+       \    ]
+       \ },
        \ ]
 
   for t in tests
     enew!
     call append(0, t.input)
     $delete _
-    exe t.cmd
+    setlocal nomodified
+    execute t.cmd
+
     call assert_equal(t.expected, getline(1, '$'), 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 t.input == t.expected
+      call assert_false(&modified, t.name . ': &mod is not correct')
+    else
+      call assert_true(&modified, t.name . ': &mod is not correct')
+    endif
   endfor
 
   call assert_fails('sort no', 'E474')
index a7a96b396a97ebde78479753b363007b785d085c..aa8a1de06bb83d90c6c0e878b981f41b38ce730a 100644 (file)
@@ -789,6 +789,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    120,
 /**/
     119,
 /**/