changeset 16996:d5e1e09a829f v8.1.1498

patch 8.1.1498: ":write" increments b:changedtick even though nothing changed commit https://github.com/vim/vim/commit/c024b4667875e5bc6fd0ed791530e33c3161bff7 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 8 18:07:21 2019 +0200 patch 8.1.1498: ":write" increments b:changedtick even though nothing changed Problem: ":write" increments b:changedtick even though nothing changed. (Daniel Hahler) Solution: Only increment b:changedtick if the modified flag is reset.
author Bram Moolenaar <Bram@vim.org>
date Sat, 08 Jun 2019 18:15:05 +0200
parents 6664cc1a0af4
children c92a414a53b9
files runtime/doc/eval.txt src/buffer.c src/change.c src/ex_cmds2.c src/fileio.c src/memline.c src/proto/change.pro src/undo.c src/version.c
diffstat 9 files changed, 26 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1504,8 +1504,10 @@ One local buffer variable is predefined:
 					*b:changedtick* *changetick*
 b:changedtick	The total number of changes to the current buffer.  It is
 		incremented for each change.  An undo command is also a change
-		in this case.  This can be used to perform an action only when
-		the buffer has changed.  Example: >
+		in this case.  Resetting 'modified' when writing the buffer is
+		also counted.
+		This can be used to perform an action only when the buffer has
+		changed.  Example: >
 		    :if my_changedtick != b:changedtick
 		    :	let my_changedtick = b:changedtick
 		    :	call My_Update()
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -60,7 +60,9 @@ static char *e_auabort = N_("E855: Autoc
 /* Number of times free_buffer() was called. */
 static int	buf_free_count = 0;
 
-/* Read data from buffer for retrying. */
+/*
+ * Read data from buffer for retrying.
+ */
     static int
 read_buffer(
     int		read_stdin,	    /* read file from stdin, otherwise fifo */
@@ -104,7 +106,7 @@ read_buffer(
 	if (!readonlymode && !BUFEMPTY())
 	    changed();
 	else if (retval == OK)
-	    unchanged(curbuf, FALSE);
+	    unchanged(curbuf, FALSE, TRUE);
 
 	if (retval == OK)
 	{
@@ -275,7 +277,7 @@ open_buffer(
        )
 	changed();
     else if (retval == OK && !read_stdin && !read_fifo)
-	unchanged(curbuf, FALSE);
+	unchanged(curbuf, FALSE, TRUE);
     save_file_ff(curbuf);		/* keep this fileformat */
 
     /* Set last_changedtick to avoid triggering a TextChanged autocommand right
@@ -700,7 +702,7 @@ aucmd_abort:
 buf_clear_file(buf_T *buf)
 {
     buf->b_ml.ml_line_count = 1;
-    unchanged(buf, TRUE);
+    unchanged(buf, TRUE, TRUE);
     buf->b_shortname = FALSE;
     buf->b_p_eol = TRUE;
     buf->b_start_eol = TRUE;
--- a/src/change.c
+++ b/src/change.c
@@ -842,9 +842,11 @@ changed_lines(
 /*
  * Called when the changed flag must be reset for buffer "buf".
  * When "ff" is TRUE also reset 'fileformat'.
+ * When "always_inc_changedtick" is TRUE b:changedtick is incremented also when
+ * the changed flag was off.
  */
     void
-unchanged(buf_T *buf, int ff)
+unchanged(buf_T *buf, int ff, int always_inc_changedtick)
 {
     if (buf->b_changed || (ff && file_ff_differs(buf, FALSE)))
     {
@@ -857,8 +859,10 @@ unchanged(buf_T *buf, int ff)
 #ifdef FEAT_TITLE
 	need_maketitle = TRUE;	    // set window title later
 #endif
+	++CHANGEDTICK(buf);
     }
-    ++CHANGEDTICK(buf);
+    else if (always_inc_changedtick)
+	++CHANGEDTICK(buf);
 #ifdef FEAT_NETBEANS_INTG
     netbeans_unmodified(buf);
 #endif
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1197,7 +1197,7 @@ dialog_changed(
     }
     else if (ret == VIM_NO)
     {
-	unchanged(buf, TRUE);
+	unchanged(buf, TRUE, FALSE);
     }
     else if (ret == VIM_ALL)
     {
@@ -1240,7 +1240,7 @@ dialog_changed(
 	 * mark all buffers as unchanged
 	 */
 	FOR_ALL_BUFFERS(buf2)
-	    unchanged(buf2, TRUE);
+	    unchanged(buf2, TRUE, FALSE);
     }
 }
 #endif
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4908,8 +4908,8 @@ restore_backup:
 	    && !write_info.bw_conv_error
 	    && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL))
     {
-	unchanged(buf, TRUE);
-	/* b:changedtick is always incremented in unchanged() but that
+	unchanged(buf, TRUE, FALSE);
+	/* b:changedtick is may be incremented in unchanged() but that
 	 * should not trigger a TextChanged event. */
 	if (buf->b_last_changedtick + 1 == CHANGEDTICK(buf))
 	    buf->b_last_changedtick = CHANGEDTICK(buf);
@@ -7081,7 +7081,7 @@ buf_reload(buf_T *buf, int orig_mode)
 	    else if (buf == curbuf)  /* "buf" still valid */
 	    {
 		/* Mark the buffer as unmodified and free undo info. */
-		unchanged(buf, TRUE);
+		unchanged(buf, TRUE, TRUE);
 		if ((flags & READ_KEEP_UNDO) == 0)
 		{
 		    u_blockfree(buf);
--- a/src/memline.c
+++ b/src/memline.c
@@ -1435,7 +1435,7 @@ ml_recover(int checkext)
 	set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
 	vim_free(b0_fenc);
     }
-    unchanged(curbuf, TRUE);
+    unchanged(curbuf, TRUE, TRUE);
 
     bnum = 1;		/* start with block 1 */
     page_count = 1;	/* which is 1 page */
--- a/src/proto/change.pro
+++ b/src/proto/change.pro
@@ -14,7 +14,7 @@ void appended_lines_mark(linenr_T lnum, 
 void deleted_lines(linenr_T lnum, long count);
 void deleted_lines_mark(linenr_T lnum, long count);
 void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra);
-void unchanged(buf_T *buf, int ff);
+void unchanged(buf_T *buf, int ff, int always_inc_changedtick);
 void ins_bytes(char_u *p);
 void ins_bytes_len(char_u *p, int len);
 void ins_char(int c);
--- a/src/undo.c
+++ b/src/undo.c
@@ -2805,7 +2805,7 @@ u_undoredo(int undo)
 	/* per netbeans undo rules, keep it as modified */
 	if (!isNetbeansModified(curbuf))
 #endif
-	unchanged(curbuf, FALSE);
+	unchanged(curbuf, FALSE, TRUE);
 
     /*
      * restore marks from before undo/redo
--- a/src/version.c
+++ b/src/version.c
@@ -768,6 +768,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1498,
+/**/
     1497,
 /**/
     1496,