aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglepnir <glephunter@gmail.com>2024-12-24 18:12:50 +0800
committerzeertzjq <zeertzjq@outlook.com>2024-12-24 18:56:40 +0800
commit05eca4c04d4d2cc6ad3a2af69d76085135e9b16c (patch)
treefe4fea9e86bcd74a70b2e0ea7590bd07f69a412b
parenta103ec7449c4a318788b519cdeac2e525136b66b (diff)
downloadrneovim-05eca4c04d4d2cc6ad3a2af69d76085135e9b16c.tar.gz
rneovim-05eca4c04d4d2cc6ad3a2af69d76085135e9b16c.tar.bz2
rneovim-05eca4c04d4d2cc6ad3a2af69d76085135e9b16c.zip
vim-patch:9.1.0956: completion may crash, completion highlight wrong with preview window
Problem: completion may crash, completion highlight wrong with preview window (after v9.1.0954) Solution: correctly calculate scroll offset, check for preview window when adding extra highlighting (glepnir) when there have a preview window prepare_tagpreview will change curwin to preview window and this may cause ComplMatchIns check condition not correct. check wp is curwin and also the type of wp is not a preview or poup info fixes: https://github.com/vim/vim/issues/16284 closes: https://github.com/vim/vim/pull/16283 https://github.com/vim/vim/commit/8d0bb6dc9f2e5d94ebb59671d592c1b7fa325ca6
-rw-r--r--src/nvim/drawline.c4
-rw-r--r--src/nvim/insexpand.c6
-rw-r--r--src/nvim/popupmenu.c6
-rw-r--r--test/functional/ui/popupmenu_spec.lua21
-rw-r--r--test/old/testdir/test_popup.vim21
5 files changed, 51 insertions, 7 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 35a41f840d..3062b0f2a3 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -1495,7 +1495,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
ptr = line + v; // "line" may have been updated
}
- if ((State & MODE_INSERT) && in_curline && ins_compl_active()) {
+ if ((State & MODE_INSERT) && in_curline && ins_compl_win_active(wp)) {
area_highlighting = true;
}
@@ -1746,7 +1746,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
}
// Check if ComplMatchIns highlight is needed.
- if ((State & MODE_INSERT) && in_curline && ins_compl_active()) {
+ if ((State & MODE_INSERT) && in_curline && ins_compl_win_active(wp)) {
int ins_match_attr = ins_compl_col_range_attr((int)(ptr - line));
if (ins_match_attr > 0) {
search_attr = hl_combine_attr(search_attr, ins_match_attr);
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index aee3603d75..7245b0d6ce 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -1722,6 +1722,12 @@ bool ins_compl_active(void)
return compl_started;
}
+/// Return true when wp is the actual completion window
+bool ins_compl_win_active(win_T *wp)
+{
+ return ins_compl_active() && !(wp->w_p_pvw || wp->w_float_is_info);
+}
+
/// Selected one of the matches. When false the match was edited or using the
/// longest common string.
bool ins_compl_used_match(void)
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index 70a479239e..75e5a52829 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -906,10 +906,10 @@ static bool pum_set_selected(int n, int repeat)
{
bool resized = false;
int context = pum_height / 2;
- int scroll_offset = pum_selected - pum_height;
int prev_selected = pum_selected;
pum_selected = n;
+ int scroll_offset = pum_selected - pum_height;
unsigned cur_cot_flags = get_cot_flags();
bool use_float = (cur_cot_flags & kOptCotFlagPopup) != 0;
@@ -940,7 +940,7 @@ static bool pum_set_selected(int n, int repeat)
// scroll up; when we did a jump it's probably a PageDown then
// scroll a whole page
if (pum_first < scroll_offset + 3) {
- pum_first = MAX(pum_first, scroll_offset + 1);
+ pum_first = MAX(pum_first + pum_height - 2, scroll_offset + 1);
} else {
pum_first = scroll_offset + 1;
}
@@ -953,7 +953,7 @@ static bool pum_set_selected(int n, int repeat)
if (pum_first > pum_selected - context) {
pum_first = MAX(pum_selected - context, 0); // scroll down
} else if (pum_first < pum_selected + context - pum_height + 1) {
- pum_first = pum_selected + context - pum_height + 1; // up
+ pum_first = pum_selected + context - pum_height + 1; // up
}
}
// adjust for the number of lines displayed
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 75421c6998..d1228d3607 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -5567,11 +5567,15 @@ describe('builtin popupmenu', function()
-- oldtest: Test_pum_matchins_highlight()
it('with ComplMatchIns highlight', function()
exec([[
+ let g:change = 0
func Omni_test(findstart, base)
if a:findstart
return col(".")
endif
- return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
+ if g:change == 0
+ return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
+ endif
+ return [#{word: "foo", info: "info"}, #{word: "bar"}, #{word: "你好"}]
endfunc
set omnifunc=Omni_test
hi ComplMatchIns guifg=red
@@ -5663,6 +5667,21 @@ describe('builtin popupmenu', function()
{2:-- INSERT --} |
]])
feed('<Esc>')
+
+ feed(':let g:change=1<CR>S<C-X><C-O>')
+ screen:expect([[
+ info |
+ {1:~ }|*2
+ {3:[Scratch] [Preview] }|
+ {8:foo}^ |
+ {s:foo }{1: }|
+ {n:bar }{1: }|
+ {n:你好 }{1: }|
+ {1:~ }|*10
+ {4:[No Name] [+] }|
+ {2:-- }{5:match 1 of 3} |
+ ]])
+ feed('<Esc>')
end)
-- oldtest: Test_pum_matchins_highlight_combine()
diff --git a/test/old/testdir/test_popup.vim b/test/old/testdir/test_popup.vim
index f16a897b07..e902ea3bc2 100644
--- a/test/old/testdir/test_popup.vim
+++ b/test/old/testdir/test_popup.vim
@@ -1716,11 +1716,15 @@ endfunc
func Test_pum_matchins_highlight()
CheckScreendump
let lines =<< trim END
+ let g:change = 0
func Omni_test(findstart, base)
if a:findstart
return col(".")
endif
- return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
+ if g:change == 0
+ return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
+ endif
+ return [#{word: "foo", info: "info"}, #{word: "bar"}, #{word: "你好"}]
endfunc
set omnifunc=Omni_test
hi ComplMatchIns ctermfg=red
@@ -1767,6 +1771,10 @@ func Test_pum_matchins_highlight()
call VerifyScreenDump(buf, 'Test_pum_matchins_10', {})
call term_sendkeys(buf, "\<Esc>")
+ call term_sendkeys(buf, ":let g:change=1\<CR>S\<C-X>\<C-O>")
+ call VerifyScreenDump(buf, 'Test_pum_matchins_11', {})
+ call term_sendkeys(buf, "\<Esc>")
+
call StopVimInTerminal(buf)
endfunc
@@ -1812,4 +1820,15 @@ func Test_pum_matchins_highlight_combine()
call StopVimInTerminal(buf)
endfunc
+" this used to crash
+func Test_popup_completion_many_ctrlp()
+ new
+ let candidates=repeat(['a0'], 99)
+ call setline(1, candidates)
+ exe ":norm! VGg\<C-A>"
+ norm! G
+ call feedkeys("o" .. repeat("\<c-p>", 100), 'tx')
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab