aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-10-12 08:21:01 +0800
committerGitHub <noreply@github.com>2023-10-12 08:21:01 +0800
commitd2d38858d1f33a2cd92e9a6182ece2459b0d6f75 (patch)
treef59af07c324971a00c0593a718d7601fcf448e10
parent3cbb02ce77087a820decd1a724a6e8b666e0ca36 (diff)
downloadrneovim-d2d38858d1f33a2cd92e9a6182ece2459b0d6f75.tar.gz
rneovim-d2d38858d1f33a2cd92e9a6182ece2459b0d6f75.tar.bz2
rneovim-d2d38858d1f33a2cd92e9a6182ece2459b0d6f75.zip
vim-patch:9.0.2018: complete_info() returns wrong index (#25607)
Problem: complete_info() returns wrong index Solution: Make order of 'info' in completion_info consistent Start the iteration from the same point and follow the same direction as done when assigning the completion numbers. This way we remove the dependence on the completion direction and make the order of 'info' consistent. closes: vim/vim#12230 closes: vim/vim#12971 https://github.com/vim/vim/commit/69fb5afb3bc9da24c2fb0eafb0027ba9c6502fc2 Co-authored-by: LemonBoy <thatlemon@gmail.com>
-rw-r--r--src/nvim/insexpand.c56
-rw-r--r--test/old/testdir/test_ins_complete.vim61
2 files changed, 95 insertions, 22 deletions
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 5ac40d7238..6f99708e1d 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -2693,6 +2693,38 @@ static void ins_compl_update_sequence_numbers(void)
}
}
+static int info_add_completion_info(list_T *li)
+{
+ if (compl_first_match == NULL) {
+ return OK;
+ }
+
+ // 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;
+ while (match != NULL && !match_at_original_text(match)) {
+ dict_T *di = tv_dict_alloc();
+
+ tv_list_append_dict(li, di);
+ tv_dict_add_str(di, S_LEN("word"), EMPTY_IF_NULL(match->cp_str));
+ tv_dict_add_str(di, S_LEN("abbr"), EMPTY_IF_NULL(match->cp_text[CPT_ABBR]));
+ tv_dict_add_str(di, S_LEN("menu"), EMPTY_IF_NULL(match->cp_text[CPT_MENU]));
+ tv_dict_add_str(di, S_LEN("kind"), EMPTY_IF_NULL(match->cp_text[CPT_KIND]));
+ tv_dict_add_str(di, S_LEN("info"), EMPTY_IF_NULL(match->cp_text[CPT_INFO]));
+ if (match->cp_user_data.v_type == VAR_UNKNOWN) {
+ // Add an empty string for backwards compatibility
+ tv_dict_add_str(di, S_LEN("user_data"), "");
+ } else {
+ tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data);
+ }
+
+ match = compl_dir_forward() ? match->cp_next : match->cp_prev;
+ }
+
+ return OK;
+}
+
/// Get complete information
static void get_complete_info(list_T *what_list, dict_T *retdict)
{
@@ -2738,29 +2770,9 @@ static void get_complete_info(list_T *what_list, dict_T *retdict)
if (ret == OK && (what_flag & CI_WHAT_ITEMS)) {
list_T *li = tv_list_alloc(get_compl_len());
-
ret = tv_dict_add_list(retdict, S_LEN("items"), li);
- if (ret == OK && compl_first_match != NULL) {
- compl_T *match = compl_first_match;
- do {
- if (!match_at_original_text(match)) {
- dict_T *di = tv_dict_alloc();
-
- tv_list_append_dict(li, di);
- tv_dict_add_str(di, S_LEN("word"), EMPTY_IF_NULL(match->cp_str));
- tv_dict_add_str(di, S_LEN("abbr"), EMPTY_IF_NULL(match->cp_text[CPT_ABBR]));
- tv_dict_add_str(di, S_LEN("menu"), EMPTY_IF_NULL(match->cp_text[CPT_MENU]));
- tv_dict_add_str(di, S_LEN("kind"), EMPTY_IF_NULL(match->cp_text[CPT_KIND]));
- tv_dict_add_str(di, S_LEN("info"), EMPTY_IF_NULL(match->cp_text[CPT_INFO]));
- if (match->cp_user_data.v_type == VAR_UNKNOWN) {
- // Add an empty string for backwards compatibility
- tv_dict_add_str(di, S_LEN("user_data"), "");
- } else {
- tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data);
- }
- }
- match = match->cp_next;
- } while (match != NULL && !is_first_match(match));
+ if (ret == OK) {
+ ret = info_add_completion_info(li);
}
}
diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim
index d9b2abffab..aeceeea9f1 100644
--- a/test/old/testdir/test_ins_complete.vim
+++ b/test/old/testdir/test_ins_complete.vim
@@ -2252,5 +2252,66 @@ func Test_tagfunc_wipes_out_buffer()
bwipe!
endfunc
+func Test_ins_complete_popup_position()
+ CheckScreendump
+
+ let lines =<< trim END
+ vim9script
+ set nowrap
+ setline(1, ['one', 'two', 'this is line ', 'four'])
+ prop_type_add('test', {highlight: 'Error'})
+ prop_add(3, 0, {
+ text_align: 'above',
+ text: 'The quick brown fox jumps over the lazy dog',
+ type: 'test'
+ })
+ END
+ call writefile(lines, 'XinsPopup', 'D')
+ let buf = RunVimInTerminal('-S XinsPopup', #{rows: 10})
+
+ call term_sendkeys(buf, "3GA\<C-N>")
+ call VerifyScreenDump(buf, 'Test_ins_complete_popup_position_1', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func GetCompleteInfo()
+ let g:compl_info = complete_info()
+ return ''
+endfunc
+
+func Test_complete_info_index()
+ new
+ call setline(1, ["aaa", "bbb", "ccc", "ddd", "eee", "fff"])
+ inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR>
+
+ " Ensure 'index' in complete_info() is coherent with the 'items' array.
+
+ set completeopt=menu,preview
+ " 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 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'])
+
+ " 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 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'])
+
+ " Add 'noselect', check that 'selected' is -1 when nothing is selected.
+ set completeopt+=noselect
+ " Search forward.
+ call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>_dd", 'tx')
+ call assert_equal(-1, g:compl_info['selected'])
+
+ " Search backward.
+ call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
+ call assert_equal(-1, g:compl_info['selected'])
+
+ set completeopt&
+ bwipe!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab