diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index e17281821c..5f36079a39 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -308,6 +308,9 @@ Name triggered by ~ |InsertCharPre| when a character was typed in Insert mode, before inserting it +|TextDeletePost| when some text is deleted (dw, dd, D) +|TextYankPost| when some text is yanked (yw, yd, Y) + |TextChanged| after a change was made to the text in Normal mode |TextChangedI| after a change was made to the text in Insert mode @@ -722,6 +725,24 @@ InsertCharPre When a character is typed in Insert mode, It is not allowed to change the text |textlock|. The event is not triggered when 'paste' is set. + *TextDeletePost* +TextDeletePost Just after a delete (|d|) command is issued. + Not issued if the black hole register + (|quote_|) is used. The affected text can be + accessed by several ways, through @" + (|quotequote| or |v:register|: > + :echo @" + :echo eval('@' . v:register) +< + *TextYankPost* +TextYankPost Just after a |yank| (|y|) command is issued. + Not issued if the black hole register + (|quote_|) is used. The affected text can be + accessed by several ways, through @" + (|quotequote| or |v:register|: > + :echo @" + :echo eval('@' . v:register) +< *InsertEnter* InsertEnter Just before starting Insert mode. Also for Replace mode and Virtual Replace mode. The diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index aa4a8d8332..a36d5232b5 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -83,6 +83,8 @@ return { 'TermResponse', -- after setting "v:termresponse" 'TextChanged', -- text was modified 'TextChangedI', -- text was modified in Insert mode + 'TextDeletePost', -- after a delete command was done (dd, dw, D) + 'TextYankPost', -- after a yank command was done (yy, yw, Y) 'User', -- user defined autocommand 'VimEnter', -- after starting Vim 'VimLeave', -- before exiting Vim diff --git a/src/nvim/ops.c b/src/nvim/ops.c index b1adc85e1d..42b72cc33b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -19,6 +19,7 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_getln.h" +#include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/getchar.h" #include "nvim/indent.h" @@ -1585,6 +1586,10 @@ int op_delete(oparg_T *oap) msgmore(curbuf->b_ml.ml_line_count - old_lcount); + textlock++; + apply_autocmds(EVENT_TEXTDELETEPOST, NULL, NULL, false, curbuf); + textlock--; + setmarks: if (oap->motion_type == MBLOCK) { curbuf->b_op_end.lnum = oap->end.lnum; @@ -2309,6 +2314,13 @@ bool op_yank(oparg_T *oap, bool message) yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK); op_yank_reg(oap, message, reg, is_append_register(oap->regname)); set_clipboard(oap->regname, reg); + + if (message) { + textlock++; + apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf); + textlock--; + } + return true; } diff --git a/test/functional/autocmd/text_deletepost.lua b/test/functional/autocmd/text_deletepost.lua new file mode 100644 index 0000000000..15c4eafdd4 --- /dev/null +++ b/test/functional/autocmd/text_deletepost.lua @@ -0,0 +1,27 @@ +local helpers = require('test.functional.helpers') +local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq +local feed, execute = helpers.feed, helpers.execute + + +describe('TextDeletePost', function() + before_each(function() + clear() + end) + + describe('au TextDeletePost', function() + it('is executed after delete', function() + feed('ifoo') + execute('let g:foo = 0') + execute('autocmd! TextDeletePost * let g:foo = 1') + feed('dd') + eq(1, eval('g:foo')) + end) + it('is not executed after yank', function() + feed('ifoo') + execute('let g:foo = 0') + execute('autocmd! TextDeletePost * let g:foo = 1') + feed('yy') + eq(0, eval('g:foo')) + end) + end) +end) diff --git a/test/functional/autocmd/text_yankpost.lua b/test/functional/autocmd/text_yankpost.lua new file mode 100644 index 0000000000..67f3735fa2 --- /dev/null +++ b/test/functional/autocmd/text_yankpost.lua @@ -0,0 +1,27 @@ +local helpers = require('test.functional.helpers') +local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq +local feed, execute = helpers.feed, helpers.execute + + +describe('TextYankPost', function() + before_each(function() + clear() + end) + + describe('autocmd TextYankPost', function() + it('is executed after yank', function() + feed('ifoo') + execute('let g:foo = 0') + execute('autocmd! TextYankPost * let g:foo = 1') + feed('yy') + eq(1, eval('g:foo')) + end) + it('is not executed after delete', function() + feed('ifoo') + execute('let g:foo = 0') + execute('autocmd! TextYankPost * let g:foo = 1') + feed('dd') + eq(0, eval('g:foo')) + end) + end) +end)