diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-08-31 04:03:30 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-31 04:03:30 +0800 |
commit | 55dc482e757e1d8f7713daa61a2deddfdaca4e42 (patch) | |
tree | a66615fae1d725e0fdad5c21630fd8fb58df4a34 | |
parent | 42ed0ffad9851f3794a9dff080a2789c87c6d7c8 (diff) | |
download | rneovim-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.c | 13 | ||||
-rw-r--r-- | test/functional/editor/completion_spec.lua | 63 |
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() |