aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2020-11-09 12:23:14 +0100
committerGitHub <noreply@github.com>2020-11-09 12:23:14 +0100
commit42ffa2d62ee714a165d56f5fa8022a32c7534d71 (patch)
tree108fd22e5ff021d1ca1840b1ec8202871a90083b
parent4e6f00dd29332ce549006e8df1b1392ed4209954 (diff)
parent11326761c77372eba83b47139f5b53c6cd5c536a (diff)
downloadrneovim-42ffa2d62ee714a165d56f5fa8022a32c7534d71.tar.gz
rneovim-42ffa2d62ee714a165d56f5fa8022a32c7534d71.tar.bz2
rneovim-42ffa2d62ee714a165d56f5fa8022a32c7534d71.zip
Merge pull request #13205 from romgrk/add-bufmodified-autocmd
Implement BufModifiedSet autocmd
-rw-r--r--runtime/doc/autocmd.txt3
-rw-r--r--src/nvim/auevents.lua2
-rw-r--r--src/nvim/buffer_defs.h3
-rw-r--r--src/nvim/change.c2
-rw-r--r--src/nvim/edit.c8
-rw-r--r--src/nvim/normal.c11
-rw-r--r--test/functional/autocmd/bufmodifiedset_spec.lua22
7 files changed, 51 insertions, 0 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index ee90d67cbc..01b21aa085 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -253,6 +253,9 @@ BufLeave Before leaving to another buffer. Also when
new current window is not for the same buffer.
Not used for ":qa" or ":q" when exiting Vim.
+ *BufModifiedSet*
+BufModifiedSet After the `'modified'` value of a buffer has
+ been changed.
*BufNew*
BufNew Just after creating a new buffer. Also used
just after a buffer has been renamed. When
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 9c28398f5b..6be51c504c 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -7,6 +7,7 @@ return {
'BufFilePre', -- before renaming a buffer
'BufHidden', -- just after buffer becomes hidden
'BufLeave', -- before leaving a buffer
+ 'BufModifiedSet', -- after the 'modified' state of a buffer changes
'BufNew', -- after creating any buffer
'BufNewFile', -- when creating a buffer for a new file
'BufReadCmd', -- read buffer using command
@@ -124,6 +125,7 @@ return {
-- List of nvim-specific events or aliases for the purpose of generating
-- syntax file
nvim_specific = {
+ BufModifiedSet=true,
DirChanged=true,
Signal=true,
TabClosed=true,
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 0b89dff92f..93fe37b585 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -541,6 +541,9 @@ struct file_buffer {
int b_changed; // 'modified': Set to true if something in the
// file has been changed and not written out.
+ bool b_changed_invalid; // Set if BufModified autocmd has not been
+ // triggered since the last time b_changed was
+ // modified.
/// Change-identifier incremented for each change, including undo.
///
diff --git a/src/nvim/change.c b/src/nvim/change.c
index 9ee987b45d..271d350967 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -129,6 +129,7 @@ void changed(void)
void changed_internal(void)
{
curbuf->b_changed = true;
+ curbuf->b_changed_invalid = true;
ml_setflags(curbuf);
check_status(curbuf);
redraw_tabline = true;
@@ -502,6 +503,7 @@ 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;
+ buf->b_changed_invalid = true;
ml_setflags(buf);
if (ff) {
save_file_ff(buf);
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index d7cca9ba36..9c8d64a6b2 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1488,6 +1488,14 @@ static void ins_redraw(
do_autocmd_winscrolled(curwin);
}
+ // Trigger BufModified if b_changed_invalid is set.
+ if (ready && has_event(EVENT_BUFMODIFIEDSET)
+ && curbuf->b_changed_invalid == true
+ && !pum_visible()) {
+ apply_autocmds(EVENT_BUFMODIFIEDSET, NULL, NULL, false, curbuf);
+ curbuf->b_changed_invalid = false;
+ }
+
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)
&& conceal_cursor_moved) {
redrawWinline(curwin, curwin->w_cursor.lnum);
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 771ca732f4..2805a7d74e 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1229,6 +1229,16 @@ static void normal_check_text_changed(NormalState *s)
}
}
+static void normal_check_buffer_modified(NormalState *s)
+{
+ // Trigger BufModified if b_modified changed
+ if (!finish_op && has_event(EVENT_BUFMODIFIEDSET)
+ && curbuf->b_changed_invalid == true) {
+ apply_autocmds(EVENT_BUFMODIFIEDSET, NULL, NULL, false, curbuf);
+ curbuf->b_changed_invalid = false;
+ }
+}
+
static void normal_check_folds(NormalState *s)
{
// Include a closed fold completely in the Visual area.
@@ -1336,6 +1346,7 @@ static int normal_check(VimState *state)
normal_check_cursor_moved(s);
normal_check_text_changed(s);
normal_check_window_scrolled(s);
+ normal_check_buffer_modified(s);
// Updating diffs from changed() does not always work properly,
// esp. updating folds. Do an update just before redrawing if
diff --git a/test/functional/autocmd/bufmodifiedset_spec.lua b/test/functional/autocmd/bufmodifiedset_spec.lua
new file mode 100644
index 0000000000..c566361e37
--- /dev/null
+++ b/test/functional/autocmd/bufmodifiedset_spec.lua
@@ -0,0 +1,22 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local source = helpers.source
+local request = helpers.request
+
+describe('BufModified', function()
+ before_each(clear)
+
+ it('is triggered when modified and un-modified', function()
+ source([[
+ let g:modified = 0
+ autocmd BufModifiedSet * let g:modified += 1
+ ]])
+ request("nvim_command", [[normal! aa\<Esc>]])
+ eq(1, eval('g:modified'))
+ request("nvim_command", [[normal! u]])
+ eq(2, eval('g:modified'))
+ end)
+end)