aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-09-04 17:03:57 -0700
committerGitHub <noreply@github.com>2019-09-04 17:03:57 -0700
commit632ee8d2ed6e307cc4d9ca2cf9e3ba0531a8af51 (patch)
treedfa1d1f1173fff6ac0e069f458b6e5956f31214e
parentd7aea13fee879a5e7854f2ebe9b7321cd8daf84f (diff)
parentd401539012f8222144b6873fd591baa232e8877c (diff)
downloadrneovim-632ee8d2ed6e307cc4d9ca2cf9e3ba0531a8af51.tar.gz
rneovim-632ee8d2ed6e307cc4d9ca2cf9e3ba0531a8af51.tar.bz2
rneovim-632ee8d2ed6e307cc4d9ca2cf9e3ba0531a8af51.zip
Merge #10946 from justinmk/vim-patchhhh
vim-patch:8.1.1498,8.1.1501: b:changedtick
-rw-r--r--runtime/doc/eval.txt6
-rw-r--r--src/nvim/buffer.c10
-rw-r--r--src/nvim/change.c12
-rw-r--r--src/nvim/ex_cmds2.c4
-rw-r--r--src/nvim/fileio.c12
-rw-r--r--src/nvim/memline.c2
-rw-r--r--src/nvim/testdir/test_changedtick.vim38
-rw-r--r--src/nvim/undo.c2
8 files changed, 64 insertions, 22 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 06f88955c9..8ec9dbdbdf 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1313,8 +1313,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()
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 382b4c45c1..6cb1da04be 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -144,7 +144,7 @@ read_buffer(
if (!readonlymode && !BUFEMPTY()) {
changed();
} else if (retval != FAIL) {
- unchanged(curbuf, false);
+ unchanged(curbuf, false, true);
}
apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, false,
@@ -299,7 +299,7 @@ int open_buffer(
|| (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)) {
changed();
} else if (retval != FAIL && !read_stdin && !read_fifo) {
- unchanged(curbuf, false);
+ unchanged(curbuf, false, true);
}
save_file_ff(curbuf); // keep this fileformat
@@ -641,13 +641,11 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
}
}
-/*
- * Make buffer not contain a file.
- */
+/// Make buffer not contain a file.
void buf_clear_file(buf_T *buf)
{
buf->b_ml.ml_line_count = 1;
- unchanged(buf, true);
+ unchanged(buf, true, true);
buf->b_p_eol = true;
buf->b_start_eol = true;
buf->b_p_bomb = false;
diff --git a/src/nvim/change.c b/src/nvim/change.c
index f8a4cf4282..3401f8a0a8 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -478,9 +478,11 @@ changed_lines(
}
}
-/// Called when the changed flag must be reset for buffer "buf".
-/// When "ff" is true also reset 'fileformat'.
-void unchanged(buf_T *buf, int ff)
+/// 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 even
+/// when the changed flag was off.
+void unchanged(buf_T *buf, int ff, bool always_inc_changedtick)
{
if (buf->b_changed || (ff && file_ff_differs(buf, false))) {
buf->b_changed = false;
@@ -491,8 +493,10 @@ void unchanged(buf_T *buf, int ff)
check_status(buf);
redraw_tabline = true;
need_maketitle = true; // set window title later
+ buf_inc_changedtick(buf);
+ } else if (always_inc_changedtick) {
+ buf_inc_changedtick(buf);
}
- buf_inc_changedtick(buf);
}
/// Insert string "p" at the cursor position. Stops at a NUL byte.
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 691ad74100..18df168c57 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1323,7 +1323,7 @@ void dialog_changed(buf_T *buf, bool checkall)
(void)buf_write_all(buf, false);
}
} else if (ret == VIM_NO) {
- unchanged(buf, true);
+ unchanged(buf, true, false);
} else if (ret == VIM_ALL) {
// Write all modified files that can be written.
// Skip readonly buffers, these need to be confirmed
@@ -1348,7 +1348,7 @@ void dialog_changed(buf_T *buf, bool checkall)
} else if (ret == VIM_DISCARDALL) {
// mark all buffers as unchanged
FOR_ALL_BUFFERS(buf2) {
- unchanged(buf2, true);
+ unchanged(buf2, true, false);
}
}
}
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 8b19257d3d..b99a254fad 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -3485,10 +3485,10 @@ restore_backup:
if (reset_changed && whole && !append
&& !write_info.bw_conv_error
&& (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) {
- unchanged(buf, true);
+ unchanged(buf, true, false);
const varnumber_T changedtick = buf_get_changedtick(buf);
if (buf->b_last_changedtick + 1 == changedtick) {
- // changedtick is always incremented in unchanged() but that
+ // b:changedtick may be incremented in unchanged() but that
// should not trigger a TextChanged event.
buf->b_last_changedtick = changedtick;
}
@@ -5107,14 +5107,14 @@ void buf_reload(buf_T *buf, int orig_mode)
}
(void)move_lines(savebuf, buf);
}
- } else if (buf == curbuf) { /* "buf" still valid */
- /* Mark the buffer as unmodified and free undo info. */
- unchanged(buf, TRUE);
+ } else if (buf == curbuf) { // "buf" still valid.
+ // Mark the buffer as unmodified and free undo info.
+ unchanged(buf, true, true);
if ((flags & READ_KEEP_UNDO) == 0) {
u_blockfree(buf);
u_clearall(buf);
} else {
- /* Mark all undo states as changed. */
+ // Mark all undo states as changed.
u_unchanged(curbuf);
}
}
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index b69812a389..15dd2767a2 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -1003,7 +1003,7 @@ void ml_recover(void)
set_option_value("fenc", 0L, (char *)b0_fenc, OPT_LOCAL);
xfree(b0_fenc);
}
- unchanged(curbuf, TRUE);
+ unchanged(curbuf, true, true);
bnum = 1; /* start with block 1 */
page_count = 1; /* which is 1 page */
diff --git a/src/nvim/testdir/test_changedtick.vim b/src/nvim/testdir/test_changedtick.vim
index 3a91bb54aa..c789cdc1bc 100644
--- a/src/nvim/testdir/test_changedtick.vim
+++ b/src/nvim/testdir/test_changedtick.vim
@@ -55,3 +55,41 @@ func Test_changedtick_fixed()
call assert_fails('unlet d["changedtick"]', 'E46:')
endfunc
+
+func Test_changedtick_not_incremented_with_write()
+ new
+ let fname = "XChangeTick"
+ exe 'w ' .. fname
+
+ " :write when the buffer is not changed does not increment changedtick
+ let expected = b:changedtick
+ w
+ call assert_equal(expected, b:changedtick)
+
+ " :write when the buffer IS changed DOES increment changedtick
+ let expected = b:changedtick + 1
+ setlocal modified
+ w
+ call assert_equal(expected, b:changedtick)
+
+ " Two ticks: change + write
+ let expected = b:changedtick + 2
+ call setline(1, 'hello')
+ w
+ call assert_equal(expected, b:changedtick)
+
+ " Two ticks: start insert + write
+ let expected = b:changedtick + 2
+ normal! o
+ w
+ call assert_equal(expected, b:changedtick)
+
+ " Three ticks: start insert + change + write
+ let expected = b:changedtick + 3
+ normal! ochanged
+ w
+ call assert_equal(expected, b:changedtick)
+
+ bwipe
+ call delete(fname)
+endfunc
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index c8343941d2..8ec36a8fe3 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2294,7 +2294,7 @@ static void u_undoredo(int undo, bool do_buf_event)
if (old_flags & UH_CHANGED) {
changed();
} else {
- unchanged(curbuf, FALSE);
+ unchanged(curbuf, false, true);
}
// because the calls to changed()/unchanged() above will bump changedtick