patch 9.1.0956: completion may crash, completion highlight wrong with preview window
Commit: https://github.com/vim/vim/commit/8d0bb6dc9f2e5d94ebb59671d592c1b7fa325ca6 Author: glepnir <glephun...@gmail.com> Date: Tue Dec 24 09:44:35 2024 +0100 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: #16284 closes: #16283 Signed-off-by: glepnir <glephun...@gmail.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/drawline.c b/src/drawline.c index bc8e4d2ad..f3838572c 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -1869,7 +1869,7 @@ win_line( } #endif - if ((State & MODE_INSERT) && in_curline && ins_compl_active()) + if ((State & MODE_INSERT) && in_curline && ins_compl_win_active(wp)) area_highlighting = TRUE; #ifdef FEAT_SYN_HL @@ -2415,7 +2415,8 @@ win_line( #endif // 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)); diff --git a/src/insexpand.c b/src/insexpand.c index 2d1490428..522b7f73e 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -1864,6 +1864,23 @@ ins_compl_active(void) return compl_started; } +/* + * Return True when wp is the actual completion window + */ + int +ins_compl_win_active(win_T *wp UNUSED) +{ + return ins_compl_active() +#if defined(FEAT_QUICKFIX) + && (!wp->w_p_pvw +# ifdef FEAT_PROP_POPUP + && !(wp->w_popup_flags & POPF_INFO) +# endif + ) +#endif + ; +} + /* * Selected one of the matches. When FALSE the match was edited or using the * longest common string. diff --git a/src/popupmenu.c b/src/popupmenu.c index 6298b5cb6..ea2edca9a 100644 --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -917,7 +917,7 @@ pum_set_selected(int n, int repeat UNUSED) { int resized = FALSE; int context = pum_height / 2; - int scroll_offset = pum_selected - pum_height; + int scroll_offset; #ifdef FEAT_QUICKFIX int prev_selected = pum_selected; unsigned cur_cot_flags = get_cot_flags(); @@ -927,6 +927,7 @@ pum_set_selected(int n, int repeat UNUSED) #endif pum_selected = n; + scroll_offset = pum_selected - pum_height; if (pum_selected >= 0 && pum_selected < pum_size) { @@ -950,7 +951,7 @@ pum_set_selected(int n, int repeat UNUSED) // 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; } diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro index 2e769b89f..24c325fe6 100644 --- a/src/proto/insexpand.pro +++ b/src/proto/insexpand.pro @@ -36,6 +36,7 @@ char_u *find_word_start(char_u *ptr); char_u *find_word_end(char_u *ptr); void ins_compl_clear(void); int ins_compl_active(void); +int ins_compl_win_active(win_T *wp); int ins_compl_used_match(void); void ins_compl_init_get_longest(void); int ins_compl_interrupted(void); diff --git a/src/testdir/dumps/Test_pum_matchins_11.dump b/src/testdir/dumps/Test_pum_matchins_11.dump new file mode 100644 index 000000000..a44a6ee56 --- /dev/null +++ b/src/testdir/dumps/Test_pum_matchins_11.dump @@ -0,0 +1,20 @@ +|i+0&#ffffff0|n|f|o| @70 +|~+0#4040ff13&| @73 +|~| @73 +|[+1#0000000&|S|c|r|a|t|c|h|]| |[|P|r|e|v|i|e|w|]| @37|1|,|1| @11|A|l@1 +|f+0&&|o@1> @71 +|f+0#0000001#e0e0e08|o@1| @11| +0#4040ff13#ffffff0@59 +|b+0#0000001#ffd7ff255|a|r| @11| +0#4040ff13#ffffff0@59 +|你*0#0000001#ffd7ff255|好| +&@10| +0#4040ff13#ffffff0@59 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1|,|1| @11|A|l@1 +|-+2&&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@34 diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim index 8f053fab8..729fbecff 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -1715,11 +1715,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 @@ -1766,6 +1770,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 @@ -1811,4 +1819,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 diff --git a/src/version.c b/src/version.c index d668ad77a..700603962 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 956, /**/ 955, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1tQ0lr-000LvN-Mu%40256bit.org.