mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #25806 from zeertzjq/vim-9.0.2074
vim-patch:9.0.{2074,2077}: Completion menu may be wrong
This commit is contained in:
commit
d2e7cc68e9
@ -2702,10 +2702,41 @@ static int info_add_completion_info(list_T *li)
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool forward = compl_dir_forward();
|
||||
compl_T *match = compl_first_match;
|
||||
// There are four cases to consider here:
|
||||
// 1) when just going forward through the menu,
|
||||
// compl_first_match should point to the initial entry with
|
||||
// number zero and CP_ORIGINAL_TEXT flag set
|
||||
// 2) when just going backwards,
|
||||
// compl-first_match should point to the last entry before
|
||||
// the entry with the CP_ORIGINAL_TEXT flag set
|
||||
// 3) when first going forwards and then backwards, e.g.
|
||||
// pressing C-N, C-P, compl_first_match points to the
|
||||
// last entry before the entry with the CP_ORIGINAL_TEXT
|
||||
// flag set and next-entry moves opposite through the list
|
||||
// compared to case 2, so pretend the direction is forward again
|
||||
// 4) when first going backwards and then forwards, e.g.
|
||||
// pressing C-P, C-N, compl_first_match points to the
|
||||
// first entry with the CP_ORIGINAL_TEXT
|
||||
// flag set and next-entry moves in opposite direction through the list
|
||||
// compared to case 1, so pretend the direction is backwards again
|
||||
//
|
||||
// But only do this when the 'noselect' option is not active!
|
||||
|
||||
if (!compl_no_select) {
|
||||
if (forward && !match_at_original_text(match)) {
|
||||
forward = false;
|
||||
} else if (!forward && match_at_original_text(match)) {
|
||||
forward = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip the element with the CP_ORIGINAL_TEXT flag at the beginning, in case of
|
||||
// forward completion, or at the end, in case of backward completion.
|
||||
compl_T *match = compl_dir_forward() ? compl_first_match->cp_next
|
||||
: compl_first_match->cp_prev->cp_prev;
|
||||
match = forward ? match->cp_next
|
||||
: (compl_no_select ? match->cp_prev : match->cp_prev->cp_prev);
|
||||
|
||||
while (match != NULL && !match_at_original_text(match)) {
|
||||
dict_T *di = tv_dict_alloc();
|
||||
|
||||
@ -2722,7 +2753,7 @@ static int info_add_completion_info(list_T *li)
|
||||
tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data);
|
||||
}
|
||||
|
||||
match = compl_dir_forward() ? match->cp_next : match->cp_prev;
|
||||
match = forward ? match->cp_next : match->cp_prev;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -2315,17 +2315,72 @@ func Test_complete_info_index()
|
||||
" Ensure 'index' in complete_info() is coherent with the 'items' array.
|
||||
|
||||
set completeopt=menu,preview
|
||||
" Search forward.
|
||||
" Search forward
|
||||
call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("aaa", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("bbb", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("ccc", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("ddd", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("eee", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("fff", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
" Search forward: unselected item
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call assert_equal(-1 , g:compl_info['selected'])
|
||||
|
||||
" Search backward.
|
||||
" Search backward
|
||||
call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("fff", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("eee", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("ddd", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("ccc", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("bbb", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("aaa", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
" search backwards: unselected item
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call assert_equal(-1 , g:compl_info['selected'])
|
||||
|
||||
" switch direction: forwards, then backwards
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("fff", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
" switch direction: forwards, then backwards, then forwards again
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-P>\<C-P>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("aaa", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
|
||||
" switch direction: backwards, then forwards
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("aaa", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
" switch direction: backwards, then forwards, then backwards again
|
||||
call feedkeys("Go\<C-X>\<C-P>\<C-P>\<C-N>\<C-N>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("fff", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
|
||||
" Add 'noselect', check that 'selected' is -1 when nothing is selected.
|
||||
set completeopt+=noselect
|
||||
@ -2337,6 +2392,16 @@ func Test_complete_info_index()
|
||||
call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal(-1, g:compl_info['selected'])
|
||||
|
||||
" Check if index out of range
|
||||
" https://github.com/vim/vim/pull/12971
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal(0, g:compl_info['selected'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
call assert_equal("fff", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
||||
call assert_equal("aaa", g:compl_info['items'][g:compl_info['selected']]['word'])
|
||||
call assert_equal(6 , len(g:compl_info['items']))
|
||||
|
||||
set completeopt&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
Loading…
Reference in New Issue
Block a user