aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-08-31 04:03:30 +0800
committerGitHub <noreply@github.com>2024-08-31 04:03:30 +0800
commit55dc482e757e1d8f7713daa61a2deddfdaca4e42 (patch)
treea66615fae1d725e0fdad5c21630fd8fb58df4a34
parent42ed0ffad9851f3794a9dff080a2789c87c6d7c8 (diff)
downloadrneovim-55dc482e757e1d8f7713daa61a2deddfdaca4e42.tar.gz
rneovim-55dc482e757e1d8f7713daa61a2deddfdaca4e42.tar.bz2
rneovim-55dc482e757e1d8f7713daa61a2deddfdaca4e42.zip
fix(completion): fix inconsistent Enter behavior (#30196)
Problem: Behavior of Enter in completion depends on typing speed. Solution: Don't make whether Enter selects original text depend on whether completion has been interrupted, which can happen interactively with a slow completion function.
-rw-r--r--src/nvim/insexpand.c13
-rw-r--r--test/functional/editor/completion_spec.lua63
2 files changed, 71 insertions, 5 deletions
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index dd014879eb..1522aeeb75 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -1792,6 +1792,13 @@ int ins_compl_bs(void)
return NUL;
}
+/// Check if the complete function returned "always" in the "refresh" dictionary item.
+static bool ins_compl_refresh_always(void)
+ FUNC_ATTR_PURE
+{
+ return (ctrl_x_mode_function() || ctrl_x_mode_omni()) && compl_opt_refresh_always;
+}
+
/// Check that we need to find matches again, ins_compl_restart() is to
/// be called.
static bool ins_compl_need_restart(void)
@@ -1799,9 +1806,7 @@ static bool ins_compl_need_restart(void)
{
// Return true if we didn't complete finding matches or when the
// "completefunc" returned "always" in the "refresh" dictionary item.
- return compl_was_interrupted
- || ((ctrl_x_mode_function() || ctrl_x_mode_omni())
- && compl_opt_refresh_always);
+ return compl_was_interrupted || ins_compl_refresh_always();
}
/// Called after changing "compl_leader".
@@ -1834,7 +1839,7 @@ static void ins_compl_new_leader(void)
// Don't let Enter select the original text when there is no popup menu.
// Don't let Enter select when use user function and refresh_always is set
- if (compl_match_array == NULL || ins_compl_need_restart()) {
+ if (compl_match_array == NULL || ins_compl_refresh_always()) {
compl_enter_selects = false;
}
}
diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua
index 9d5bda0acc..3f19596bd7 100644
--- a/test/functional/editor/completion_spec.lua
+++ b/test/functional/editor/completion_spec.lua
@@ -327,7 +327,7 @@ describe('completion', function()
end
end)
- describe('refresh:always', function()
+ describe('with refresh:always and noselect', function()
before_each(function()
source([[
function! TestCompletion(findstart, base) abort
@@ -459,6 +459,67 @@ describe('completion', function()
June
June]])
end)
+
+ it('Enter does not select original text', function()
+ feed('iJ<C-x><C-u>')
+ poke_eventloop()
+ feed('u')
+ poke_eventloop()
+ feed('<CR>')
+ expect([[
+ Ju
+ ]])
+ feed('J<C-x><C-u>')
+ poke_eventloop()
+ feed('<CR>')
+ expect([[
+ Ju
+ J
+ ]])
+ end)
+ end)
+
+ describe('with noselect but not refresh:always', function()
+ before_each(function()
+ source([[
+ function! TestCompletion(findstart, base) abort
+ if a:findstart
+ let line = getline('.')
+ let start = col('.') - 1
+ while start > 0 && line[start - 1] =~ '\a'
+ let start -= 1
+ endwhile
+ return start
+ else
+ let ret = []
+ for m in split("January February March April May June July August September October November December")
+ if m =~ a:base " match by regex
+ call add(ret, m)
+ endif
+ endfor
+ return {'words':ret}
+ endif
+ endfunction
+
+ set completeopt=menuone,noselect
+ set completefunc=TestCompletion
+ ]])
+ end)
+
+ it('Enter selects original text after adding leader', function()
+ feed('iJ<C-x><C-u>')
+ poke_eventloop()
+ feed('u')
+ poke_eventloop()
+ feed('<CR>')
+ expect('Ju')
+ feed('<Esc>')
+ poke_eventloop()
+ -- The behavior should be the same when completion has been interrupted,
+ -- which can happen interactively if the completion function is slow.
+ feed('SJ<C-x><C-u>u<CR>')
+ expect('Ju')
+ end)
end)
describe('with a lot of items', function()