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

Raspunde prin e-mail lui