mirror of
https://github.com/neovim/neovim.git
synced 2025-11-04 17:54:30 +00: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:
@@ -2702,10 +2702,41 @@ static int info_add_completion_info(list_T *li)
|
|||||||
return OK;
|
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
|
// 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.
|
// forward completion, or at the end, in case of backward completion.
|
||||||
compl_T *match = compl_dir_forward() ? compl_first_match->cp_next
|
match = forward ? match->cp_next
|
||||||
: compl_first_match->cp_prev->cp_prev;
|
: (compl_no_select ? match->cp_prev : match->cp_prev->cp_prev);
|
||||||
|
|
||||||
while (match != NULL && !match_at_original_text(match)) {
|
while (match != NULL && !match_at_original_text(match)) {
|
||||||
dict_T *di = tv_dict_alloc();
|
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);
|
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;
|
return OK;
|
||||||
|
|||||||
@@ -2315,17 +2315,72 @@ func Test_complete_info_index()
|
|||||||
" Ensure 'index' in complete_info() is coherent with the 'items' array.
|
" Ensure 'index' in complete_info() is coherent with the 'items' array.
|
||||||
|
|
||||||
set completeopt=menu,preview
|
set completeopt=menu,preview
|
||||||
" Search forward.
|
" Search forward
|
||||||
call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>_dd", 'tx')
|
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("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 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("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 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("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 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("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.
|
" Add 'noselect', check that 'selected' is -1 when nothing is selected.
|
||||||
set completeopt+=noselect
|
set completeopt+=noselect
|
||||||
@@ -2337,6 +2392,16 @@ func Test_complete_info_index()
|
|||||||
call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
|
||||||
call assert_equal(-1, g:compl_info['selected'])
|
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&
|
set completeopt&
|
||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|||||||
Reference in New Issue
Block a user