aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/autocmd.txt10
-rw-r--r--runtime/doc/news.txt3
-rw-r--r--runtime/doc/vvars.txt1
-rw-r--r--runtime/lua/vim/_meta/vvars.lua1
-rw-r--r--src/nvim/insexpand.c16
-rw-r--r--src/nvim/vvars.lua1
-rw-r--r--test/functional/autocmd/completedone_spec.lua41
7 files changed, 71 insertions, 2 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index bb84966228..ca816851dd 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -466,6 +466,16 @@ CompleteDone After Insert mode completion is done. Either
CompleteDonePre if you need it.
|v:completed_item| gives the completed item.
+ Sets these |v:event| keys:
+ reason Reason for completion being
+ done. Can be one of:
+ - "accept": completion was
+ accepted using |complete_CTRL-Y|.
+ - "cancel": completion was cancelled
+ using |complete_CTRL-E|, pressing
+ a non-keyword character, or
+ triggering a new completion.
+
*CursorHold*
CursorHold When the user doesn't press a key for the time
specified with 'updatetime'. Not triggered
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index f8bc983441..03f6f7f8fd 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -130,6 +130,9 @@ UI
• TODO
+• |CompleteDone| now sets the `reason` key in `v:event` which specifies the reason
+ for completion being done.
+
==============================================================================
CHANGED FEATURES *news-changed*
diff --git a/runtime/doc/vvars.txt b/runtime/doc/vvars.txt
index de7f23a34d..15d836a83d 100644
--- a/runtime/doc/vvars.txt
+++ b/runtime/doc/vvars.txt
@@ -187,6 +187,7 @@ v:event
changed_window Is |v:true| if the event fired while
changing window (or tab) on |DirChanged|.
status Job status or exit code, -1 means "unknown". |TermClose|
+ reason Reason for completion being done. |CompleteDone|
*v:exception* *exception-variable*
v:exception
diff --git a/runtime/lua/vim/_meta/vvars.lua b/runtime/lua/vim/_meta/vvars.lua
index 1660d1dd6c..e00402ab3f 100644
--- a/runtime/lua/vim/_meta/vvars.lua
+++ b/runtime/lua/vim/_meta/vvars.lua
@@ -195,6 +195,7 @@ vim.v.errors = ...
--- changed_window Is `v:true` if the event fired while
--- changing window (or tab) on `DirChanged`.
--- status Job status or exit code, -1 means "unknown". `TermClose`
+--- reason Reason for completion being done. `CompleteDone`
--- @type any
vim.v.event = ...
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index cec1e4a9e3..b557b9802e 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -568,6 +568,18 @@ static bool is_first_match(const compl_T *const match)
return match == compl_first_match;
}
+static void do_autocmd_completedone(int c)
+{
+ save_v_event_T save_v_event;
+ dict_T *v_event = get_v_event(&save_v_event);
+
+ tv_dict_add_str(v_event, S_LEN("reason"), (c == Ctrl_Y ? "accept" : "cancel"));
+ tv_dict_set_keys_readonly(v_event);
+
+ ins_apply_autocmds(EVENT_COMPLETEDONE);
+ restore_v_event(v_event, &save_v_event);
+}
+
/// Check that character "c" is part of the item currently being
/// completed. Used to decide whether to abandon complete mode when the menu
/// is visible.
@@ -2110,7 +2122,7 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval)
}
// Trigger the CompleteDone event to give scripts a chance to act
// upon the end of completion.
- ins_apply_autocmds(EVENT_COMPLETEDONE);
+ do_autocmd_completedone(c);
return retval;
}
@@ -2199,7 +2211,7 @@ bool ins_compl_prep(int c)
} else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) {
// Trigger the CompleteDone event to give scripts a chance to act
// upon the (possibly failed) completion.
- ins_apply_autocmds(EVENT_COMPLETEDONE);
+ do_autocmd_completedone(c);
}
may_trigger_modechanged();
diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua
index 224edfaf6e..2f43f8b32b 100644
--- a/src/nvim/vvars.lua
+++ b/src/nvim/vvars.lua
@@ -215,6 +215,7 @@ M.vars = {
changed_window Is |v:true| if the event fired while
changing window (or tab) on |DirChanged|.
status Job status or exit code, -1 means "unknown". |TermClose|
+ reason Reason for completion being done. |CompleteDone|
]=],
},
exception = {
diff --git a/test/functional/autocmd/completedone_spec.lua b/test/functional/autocmd/completedone_spec.lua
new file mode 100644
index 0000000000..33beb16db2
--- /dev/null
+++ b/test/functional/autocmd/completedone_spec.lua
@@ -0,0 +1,41 @@
+local t = require('test.testutil')
+local n = require('test.functional.testnvim')()
+
+local clear = n.clear
+local command = n.command
+local call = n.call
+local feed = n.feed
+local eval = n.eval
+local eq = t.eq
+
+describe('CompleteDone', function()
+ before_each(clear)
+
+ describe('sets v:event.reason', function()
+ before_each(function()
+ clear()
+ command('autocmd CompleteDone * let g:donereason = v:event.reason')
+ feed('i')
+ call('complete', call('col', '.'), { 'foo', 'bar' })
+ end)
+
+ it('accept', function()
+ feed('<C-y>')
+ eq('accept', eval('g:donereason'))
+ end)
+ describe('cancel', function()
+ it('on <C-e>', function()
+ feed('<C-e>')
+ eq('cancel', eval('g:donereason'))
+ end)
+ it('on non-keyword character', function()
+ feed('<Esc>')
+ eq('cancel', eval('g:donereason'))
+ end)
+ it('when overriden by another complete()', function()
+ call('complete', call('col', '.'), { 'bar', 'baz' })
+ eq('cancel', eval('g:donereason'))
+ end)
+ end)
+ end)
+end)