diff options
author | zeertzjq <zeertzjq@outlook.com> | 2025-01-17 08:38:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-17 08:38:58 +0800 |
commit | 0d3a8e8c1a7778c6c79658f26ba492a5f4a17d18 (patch) | |
tree | fa25b2ada0e41c1084cb3f40f6e3025c52b07cb7 | |
parent | bf098c12e3078df49fd7dee5ba7c2100a211d4c8 (diff) | |
download | rneovim-0d3a8e8c1a7778c6c79658f26ba492a5f4a17d18.tar.gz rneovim-0d3a8e8c1a7778c6c79658f26ba492a5f4a17d18.tar.bz2 rneovim-0d3a8e8c1a7778c6c79658f26ba492a5f4a17d18.zip |
vim-patch:9.1.1020: no way to get current selected item in a async context (#32056)
Problem: no way to get current selected item in a async context
Solution: add completed flag to show the entries of currently selected
index item (glepnir)
closes: vim/vim#16451
https://github.com/vim/vim/commit/037b028a2219d09bc97be04b300b2c0490c4268d
Co-authored-by: glepnir <glephunter@gmail.com>
-rw-r--r-- | runtime/doc/builtin.txt | 3 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/vimfn.lua | 3 | ||||
-rw-r--r-- | src/nvim/eval.lua | 3 | ||||
-rw-r--r-- | src/nvim/insexpand.c | 54 | ||||
-rw-r--r-- | test/old/testdir/test_ins_complete.vim | 30 |
5 files changed, 68 insertions, 25 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 6e05dd24d2..d4a6bbf9d8 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1188,7 +1188,8 @@ complete_info([{what}]) *complete_info()* typed text only, or the last completion after no item is selected when using the <Up> or <Down> keys) - inserted Inserted string. [NOT IMPLEMENTED YET] + completed Return a dictionary containing the entries of + the currently selected index item. preview_winid Info floating preview window id. preview_bufnr Info floating preview buffer id. diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 6316ab2bfc..4b5b276023 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -1037,7 +1037,8 @@ function vim.fn.complete_check() end --- typed text only, or the last completion after --- no item is selected when using the <Up> or --- <Down> keys) ---- inserted Inserted string. [NOT IMPLEMENTED YET] +--- completed Return a dictionary containing the entries of +--- the currently selected index item. --- preview_winid Info floating preview window id. --- preview_bufnr Info floating preview buffer id. --- diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 5c7b2791e8..ecb213c811 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -1398,7 +1398,8 @@ M.funcs = { typed text only, or the last completion after no item is selected when using the <Up> or <Down> keys) - inserted Inserted string. [NOT IMPLEMENTED YET] + completed Return a dictionary containing the entries of + the currently selected index item. preview_winid Info floating preview window id. preview_bufnr Info floating preview buffer id. diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 22643457d6..a5f5a4eda3 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -2884,6 +2884,25 @@ static void ins_compl_update_sequence_numbers(void) } } +/// Fill the dict of complete_info +static void fill_complete_info_dict(dict_T *di, compl_T *match, bool add_match) +{ + tv_dict_add_str(di, S_LEN("word"), match->cp_str.data); + tv_dict_add_str(di, S_LEN("abbr"), match->cp_text[CPT_ABBR]); + tv_dict_add_str(di, S_LEN("menu"), match->cp_text[CPT_MENU]); + tv_dict_add_str(di, S_LEN("kind"), match->cp_text[CPT_KIND]); + tv_dict_add_str(di, S_LEN("info"), match->cp_text[CPT_INFO]); + if (add_match) { + tv_dict_add_bool(di, S_LEN("match"), match->cp_in_match_array); + } + 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); + } +} + /// Get complete information static void get_complete_info(list_T *what_list, dict_T *retdict) { @@ -2891,13 +2910,13 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) #define CI_WHAT_PUM_VISIBLE 0x02 #define CI_WHAT_ITEMS 0x04 #define CI_WHAT_SELECTED 0x08 -#define CI_WHAT_INSERTED 0x10 +#define CI_WHAT_COMPLETED 0x10 #define CI_WHAT_MATCHES 0x20 #define CI_WHAT_ALL 0xff int what_flag; if (what_list == NULL) { - what_flag = CI_WHAT_ALL & ~CI_WHAT_MATCHES; + what_flag = CI_WHAT_ALL & ~(CI_WHAT_MATCHES|CI_WHAT_COMPLETED); } else { what_flag = 0; for (listitem_T *item = tv_list_first(what_list) @@ -2913,8 +2932,8 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) what_flag |= CI_WHAT_ITEMS; } else if (strcmp(what, "selected") == 0) { what_flag |= CI_WHAT_SELECTED; - } else if (strcmp(what, "inserted") == 0) { - what_flag |= CI_WHAT_INSERTED; + } else if (strcmp(what, "completed") == 0) { + what_flag |= CI_WHAT_COMPLETED; } else if (strcmp(what, "matches") == 0) { what_flag |= CI_WHAT_MATCHES; } @@ -2930,12 +2949,13 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) ret = tv_dict_add_nr(retdict, S_LEN("pum_visible"), pum_visible()); } - if (ret == OK && (what_flag & CI_WHAT_ITEMS || what_flag & CI_WHAT_SELECTED - || what_flag & CI_WHAT_MATCHES)) { + if (ret == OK && (what_flag & (CI_WHAT_ITEMS|CI_WHAT_SELECTED + |CI_WHAT_MATCHES|CI_WHAT_COMPLETED))) { list_T *li = NULL; int selected_idx = -1; bool has_items = what_flag & CI_WHAT_ITEMS; bool has_matches = what_flag & CI_WHAT_MATCHES; + bool has_completed = what_flag & CI_WHAT_COMPLETED; if (has_items || has_matches) { li = tv_list_alloc(kListLenMayKnow); const char *key = (has_matches && !has_items) ? "matches" : "items"; @@ -2954,20 +2974,7 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) if (has_items || (has_matches && match->cp_in_match_array)) { dict_T *di = tv_dict_alloc(); tv_list_append_dict(li, di); - tv_dict_add_str(di, S_LEN("word"), match->cp_str.data); - tv_dict_add_str(di, S_LEN("abbr"), match->cp_text[CPT_ABBR]); - tv_dict_add_str(di, S_LEN("menu"), match->cp_text[CPT_MENU]); - tv_dict_add_str(di, S_LEN("kind"), match->cp_text[CPT_KIND]); - tv_dict_add_str(di, S_LEN("info"), match->cp_text[CPT_INFO]); - if (has_matches && has_items) { - tv_dict_add_bool(di, S_LEN("match"), match->cp_in_match_array); - } - 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); - } + fill_complete_info_dict(di, match, has_matches && has_items); } if (compl_curr_match != NULL && compl_curr_match->cp_number == match->cp_number) { @@ -2986,11 +2993,14 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) tv_dict_add_nr(retdict, S_LEN("preview_bufnr"), wp->w_buffer->handle); } } + if (ret == OK && selected_idx != -1 && has_completed) { + dict_T *di = tv_dict_alloc(); + fill_complete_info_dict(di, compl_curr_match, false); + ret = tv_dict_add_dict(retdict, S_LEN("completed"), di); + } } (void)ret; - // TODO(vim): - // if (ret == OK && (what_flag & CI_WHAT_INSERTED)) } /// "complete_info()" function diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index 52fd24881c..f1ff45ff90 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2914,4 +2914,34 @@ func Test_complete_info_matches() set cot& endfunc +func Test_complete_info_completed() + func ShownInfo() + let g:compl_info = complete_info(['completed']) + return '' + endfunc + set completeopt+=noinsert + + new + call setline(1, ['aaa', 'aab', 'aba', 'abb']) + inoremap <buffer><F5> <C-R>=ShownInfo()<CR> + + call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>dd", 'tx') + call assert_equal({'word': 'aaa', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, g:compl_info['completed']) + + call feedkeys("Go\<C-X>\<C-N>\<C-N>\<F5>\<Esc>dd", 'tx') + call assert_equal({'word': 'aab', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, g:compl_info['completed']) + + call feedkeys("Go\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<F5>\<Esc>dd", 'tx') + call assert_equal({'word': 'abb', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, g:compl_info['completed']) + + set completeopt+=noselect + call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>dd", 'tx') + call assert_equal({}, g:compl_info) + + bw! + bw! + delfunc ShownInfo + set cot& +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable |