diff options
author | glepnir <glephunter@gmail.com> | 2024-12-31 19:12:50 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-31 19:12:50 +0800 |
commit | bdc0b5f5054afb8ba3418f9d6c9b1b3e944f3e3a (patch) | |
tree | 5c0326a9ffb1b03bb6db73cf37f4e9478665874f | |
parent | 57f10abbc2c17453ffe584833abb7596e9897a6e (diff) | |
download | rneovim-bdc0b5f5054afb8ba3418f9d6c9b1b3e944f3e3a.tar.gz rneovim-bdc0b5f5054afb8ba3418f9d6c9b1b3e944f3e3a.tar.bz2 rneovim-bdc0b5f5054afb8ba3418f9d6c9b1b3e944f3e3a.zip |
vim-patch:9.1.0983: not able to get the displayed items in complete_i… (#31796)
vim-patch:9.1.0983: not able to get the displayed items in complete_info()
Problem: not able to get the displayed items in complete_info()
(Evgeni Chasnovski)
Solution: return the visible items via the "matches" key for
complete_info() (glepnir)
fixes: vim/vim#10007
closes: vim/vim#16307
https://github.com/vim/vim/commit/d4088edae21659e14ab5f763c820f4eab9d36981
-rw-r--r-- | runtime/doc/builtin.txt | 9 | ||||
-rw-r--r-- | runtime/doc/insert.txt | 1 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/vimfn.lua | 9 | ||||
-rw-r--r-- | src/nvim/eval.lua | 9 | ||||
-rw-r--r-- | src/nvim/insexpand.c | 23 | ||||
-rw-r--r-- | test/old/testdir/test_ins_complete.vim | 44 |
6 files changed, 84 insertions, 11 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 0e9c1c8512..f321c880a4 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1174,10 +1174,15 @@ complete_info([{what}]) *complete_info()* See |complete_info_mode| for the values. pum_visible |TRUE| if popup menu is visible. See |pumvisible()|. - items List of completion matches. Each item is a - dictionary containing the entries "word", + items List of all completion candidates. Each item + is a dictionary containing the entries "word", "abbr", "menu", "kind", "info" and "user_data". See |complete-items|. + matches Same as "items", but only returns items that + are matching current query. If both "matches" + and "items" are in "what", the returned list + will still be named "items", but each item + will have an additional "match" field. selected Selected item index. First index is zero. Index is -1 if no item is selected (showing typed text only, or the last completion after diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index d3b822e72b..bc0e9ba314 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -1189,6 +1189,7 @@ items: |hl-PmenuKind| highlight group, allowing for the customization of ctermfg and guifg properties for the completion kind + match See "matches" in |complete_info()|. All of these except "icase", "equal", "dup" and "empty" must be a string. If an item does not meet these requirements then an error message is given and diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index b580357c85..6662fca84f 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -1023,10 +1023,15 @@ function vim.fn.complete_check() end --- See |complete_info_mode| for the values. --- pum_visible |TRUE| if popup menu is visible. --- See |pumvisible()|. ---- items List of completion matches. Each item is a ---- dictionary containing the entries "word", +--- items List of all completion candidates. Each item +--- is a dictionary containing the entries "word", --- "abbr", "menu", "kind", "info" and "user_data". --- See |complete-items|. +--- matches Same as "items", but only returns items that +--- are matching current query. If both "matches" +--- and "items" are in "what", the returned list +--- will still be named "items", but each item +--- will have an additional "match" field. --- selected Selected item index. First index is zero. --- Index is -1 if no item is selected (showing --- typed text only, or the last completion after diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 72dabd53e9..c650dee306 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -1384,10 +1384,15 @@ M.funcs = { See |complete_info_mode| for the values. pum_visible |TRUE| if popup menu is visible. See |pumvisible()|. - items List of completion matches. Each item is a - dictionary containing the entries "word", + items List of all completion candidates. Each item + is a dictionary containing the entries "word", "abbr", "menu", "kind", "info" and "user_data". See |complete-items|. + matches Same as "items", but only returns items that + are matching current query. If both "matches" + and "items" are in "what", the returned list + will still be named "items", but each item + will have an additional "match" field. selected Selected item index. First index is zero. Index is -1 if no item is selected (showing typed text only, or the last completion after diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 7245b0d6ce..9b77644085 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -164,6 +164,7 @@ struct compl_S { int cp_flags; ///< CP_ values int cp_number; ///< sequence number int cp_score; ///< fuzzy match score + bool cp_in_match_array; ///< collected by compl_match_array int cp_user_abbr_hlattr; ///< highlight attribute for abbr int cp_user_kind_hlattr; ///< highlight attribute for kind }; @@ -1223,6 +1224,7 @@ static int ins_compl_build_pum(void) int cur = -1; do { + comp->cp_in_match_array = false; // When 'completeopt' contains "fuzzy" and leader is not NULL or empty, // set the cp_score for later comparisons. if (compl_fuzzy_match && compl_leader != NULL && lead_len > 0) { @@ -1234,6 +1236,7 @@ static int ins_compl_build_pum(void) || ins_compl_equal(comp, compl_leader, (size_t)lead_len) || (compl_fuzzy_match && comp->cp_score > 0))) { compl_match_arraysize++; + comp->cp_in_match_array = true; if (match_head == NULL) { match_head = comp; } else { @@ -2875,11 +2878,12 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) #define CI_WHAT_ITEMS 0x04 #define CI_WHAT_SELECTED 0x08 #define CI_WHAT_INSERTED 0x10 +#define CI_WHAT_MATCHES 0x20 #define CI_WHAT_ALL 0xff int what_flag; if (what_list == NULL) { - what_flag = CI_WHAT_ALL; + what_flag = CI_WHAT_ALL & ~CI_WHAT_MATCHES; } else { what_flag = 0; for (listitem_T *item = tv_list_first(what_list) @@ -2897,6 +2901,8 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) what_flag |= CI_WHAT_SELECTED; } else if (strcmp(what, "inserted") == 0) { what_flag |= CI_WHAT_INSERTED; + } else if (strcmp(what, "matches") == 0) { + what_flag |= CI_WHAT_MATCHES; } } } @@ -2910,12 +2916,16 @@ 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)) { + if (ret == OK && (what_flag & CI_WHAT_ITEMS || what_flag & CI_WHAT_SELECTED + || what_flag & CI_WHAT_MATCHES)) { list_T *li = NULL; int selected_idx = -1; - if (what_flag & CI_WHAT_ITEMS) { + bool has_items = what_flag & CI_WHAT_ITEMS; + bool has_matches = what_flag & CI_WHAT_MATCHES; + if (has_items || has_matches) { li = tv_list_alloc(kListLenMayKnow); - ret = tv_dict_add_list(retdict, S_LEN("items"), li); + const char *key = (has_matches && !has_items) ? "matches" : "items"; + ret = tv_dict_add_list(retdict, key, strlen(key), li); } if (ret == OK && what_flag & CI_WHAT_SELECTED) { if (compl_curr_match != NULL && compl_curr_match->cp_number == -1) { @@ -2927,7 +2937,7 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) compl_T *match = compl_first_match; do { if (!match_at_original_text(match)) { - if (what_flag & CI_WHAT_ITEMS) { + 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); @@ -2935,6 +2945,9 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) 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"), ""); diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index bf7477f088..52fd24881c 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2870,4 +2870,48 @@ func Test_complete_fuzzy_match_tie() set completeopt& endfunc +func Test_complete_info_matches() + let g:what = ['matches'] + func ShownInfo() + let g:compl_info = complete_info(g:what) + 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': ''}, + \ {'word': 'aab', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, + \ {'word': 'aba', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, + \ {'word': 'abb', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, + \], g:compl_info['matches']) + + call feedkeys("Goa\<C-X>\<C-N>b\<F5>\<Esc>dd", 'tx') + call assert_equal([ + \ {'word': 'aba', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, + \ {'word': 'abb', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, + \], g:compl_info['matches']) + + " items and matches both in what + let g:what = ['items', 'matches'] + call feedkeys("Goa\<C-X>\<C-N>b\<F5>\<Esc>dd", 'tx') + call assert_equal([ + \ {'word': 'aaa', 'menu': '', 'user_data': '', 'match': v:false, 'info': '', 'kind': '', 'abbr': ''}, + \ {'word': 'aab', 'menu': '', 'user_data': '', 'match': v:false, 'info': '', 'kind': '', 'abbr': ''}, + \ {'word': 'aba', 'menu': '', 'user_data': '', 'match': v:true, 'info': '', 'kind': '', 'abbr': ''}, + \ {'word': 'abb', 'menu': '', 'user_data': '', 'match': v:true, 'info': '', 'kind': '', 'abbr': ''}, + \], g:compl_info['items']) + call assert_false(has_key(g:compl_info, 'matches')) + + bw! + bw! + unlet g:what + delfunc ShownInfo + set cot& +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable |