aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglepnir <glephunter@gmail.com>2024-12-31 19:12:50 +0800
committerGitHub <noreply@github.com>2024-12-31 19:12:50 +0800
commitbdc0b5f5054afb8ba3418f9d6c9b1b3e944f3e3a (patch)
tree5c0326a9ffb1b03bb6db73cf37f4e9478665874f
parent57f10abbc2c17453ffe584833abb7596e9897a6e (diff)
downloadrneovim-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.txt9
-rw-r--r--runtime/doc/insert.txt1
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua9
-rw-r--r--src/nvim/eval.lua9
-rw-r--r--src/nvim/insexpand.c23
-rw-r--r--test/old/testdir/test_ins_complete.vim44
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