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: #10007
closes: #16307

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir
2024-12-31 10:55:22 +01:00
committed by Christian Brabandt
parent 34e271b321
commit d4088edae2
6 changed files with 79 additions and 11 deletions

View File

@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2024 Dec 30
*builtin.txt* For Vim version 9.1. Last change: 2024 Dec 31
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1896,10 +1896,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

View File

@ -1,4 +1,4 @@
*insert.txt* For Vim version 9.1. Last change: 2024 Dec 28
*insert.txt* For Vim version 9.1. Last change: 2024 Dec 31
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1195,6 +1195,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

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2024 Dec 30
*version9.txt* For Vim version 9.1. Last change: 2024 Dec 31
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41621,6 +41621,8 @@ Changed~
instead of the "sh" filetype
- the default value of the 'keyprotocol' option has been updated by support
for the ghostty terminal emulator (using kitty protocol)
- |complete_info()| returns the list of matches shown in the poppu menu via
the "matches" key
*added-9.2*
Added ~

View File

@ -106,6 +106,7 @@ struct compl_S
int cp_flags; // CP_ values
int cp_number; // sequence number
int cp_score; // fuzzy match score
int 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
};
@ -1282,6 +1283,7 @@ ins_compl_build_pum(void)
do
{
compl->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.string != NULL && compl_leader.length > 0)
@ -1293,6 +1295,7 @@ ins_compl_build_pum(void)
|| (compl_fuzzy_match && compl->cp_score > 0)))
{
++compl_match_arraysize;
compl->cp_in_match_array = TRUE;
if (match_head == NULL)
match_head = compl;
else
@ -3259,11 +3262,12 @@ 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;
@ -3282,6 +3286,8 @@ 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;
}
}
@ -3291,19 +3297,23 @@ get_complete_info(list_T *what_list, dict_T *retdict)
if (ret == OK && (what_flag & CI_WHAT_PUM_VISIBLE))
ret = dict_add_number(retdict, "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;
dict_T *di;
compl_T *match;
int selected_idx = -1;
int has_items = what_flag & CI_WHAT_ITEMS;
int has_matches = what_flag & CI_WHAT_MATCHES;
if (what_flag & CI_WHAT_ITEMS)
if (has_items || has_matches)
{
li = list_alloc();
if (li == NULL)
return;
ret = dict_add_list(retdict, "items", li);
ret = dict_add_list(retdict, (has_matches && !has_items)
? "matches" : "items", li);
}
if (ret == OK && what_flag & CI_WHAT_SELECTED)
if (compl_curr_match != NULL && compl_curr_match->cp_number == -1)
@ -3316,7 +3326,8 @@ get_complete_info(list_T *what_list, dict_T *retdict)
{
if (!match_at_original_text(match))
{
if (what_flag & CI_WHAT_ITEMS)
if (has_items
|| (has_matches && match->cp_in_match_array))
{
di = dict_alloc();
if (di == NULL)
@ -3329,13 +3340,16 @@ get_complete_info(list_T *what_list, dict_T *retdict)
dict_add_string(di, "menu", match->cp_text[CPT_MENU]);
dict_add_string(di, "kind", match->cp_text[CPT_KIND]);
dict_add_string(di, "info", match->cp_text[CPT_INFO]);
if (has_matches && has_items)
dict_add_bool(di, "match", match->cp_in_match_array);
if (match->cp_user_data.v_type == VAR_UNKNOWN)
// Add an empty string for backwards compatibility
dict_add_string(di, "user_data", (char_u *)"");
else
dict_add_tv(di, "user_data", &match->cp_user_data);
}
if (compl_curr_match != NULL && compl_curr_match->cp_number == match->cp_number)
if (compl_curr_match != NULL
&& compl_curr_match->cp_number == match->cp_number)
selected_idx = list_idx;
list_idx += 1;
}

View File

@ -2931,4 +2931,48 @@ func Test_complete_backwards_default()
bw!
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

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
983,
/**/
982,
/**/