diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2020-11-09 12:23:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-09 12:23:14 +0100 |
commit | 42ffa2d62ee714a165d56f5fa8022a32c7534d71 (patch) | |
tree | 108fd22e5ff021d1ca1840b1ec8202871a90083b | |
parent | 4e6f00dd29332ce549006e8df1b1392ed4209954 (diff) | |
parent | 11326761c77372eba83b47139f5b53c6cd5c536a (diff) | |
download | rneovim-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.txt | 3 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 2 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 3 | ||||
-rw-r--r-- | src/nvim/change.c | 2 | ||||
-rw-r--r-- | src/nvim/edit.c | 8 | ||||
-rw-r--r-- | src/nvim/normal.c | 11 | ||||
-rw-r--r-- | test/functional/autocmd/bufmodifiedset_spec.lua | 22 |
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) |