patch 9.1.1020: no way to get current selected item in a async context

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: #16451

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir
2025-01-16 14:37:44 +01:00
committed by Christian Brabandt
parent 3058087f6f
commit 037b028a22
5 changed files with 72 additions and 28 deletions

View File

@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2025 Jan 15 *builtin.txt* For Vim version 9.1. Last change: 2025 Jan 16
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -1946,7 +1946,8 @@ complete_info([{what}]) *complete_info()*
typed text only, or the last completion after typed text only, or the last completion after
no item is selected when using the <Up> or no item is selected when using the <Up> or
<Down> keys) <Down> keys)
inserted Inserted string. [NOT IMPLEMENTED YET] completed Return a dictionary containing the entries of
the currently selected index item.
*complete_info_mode* *complete_info_mode*
mode values are: mode values are:

View File

@ -1,4 +1,4 @@
*todo.txt* For Vim version 9.1. Last change: 2024 Dec 30 *todo.txt* For Vim version 9.1. Last change: 2025 Jan 16
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -309,9 +309,6 @@ Problem with Visual highlight when 'linebreak' and 'showbreak' are set.
GUI Scroll test fails on FreeBSD when using Motif. See FIXME in GUI Scroll test fails on FreeBSD when using Motif. See FIXME in
Test_scrollbars in src/test_gui.vim Test_scrollbars in src/test_gui.vim
Selected index returned by complete_info() does not match the index in the
list of items. #12230
Support dark mode for MS-Windows: #12282 Support dark mode for MS-Windows: #12282
Remote command escapes single quote with backslash, should be doubling the Remote command escapes single quote with backslash, should be doubling the

View File

@ -3252,6 +3252,26 @@ ins_compl_update_sequence_numbers(void)
} }
} }
/*
* Fill the dict of complete_info
*/
static void
fill_complete_info_dict(dict_T *di, compl_T *match, int add_match)
{
dict_add_string(di, "word", match->cp_str.string);
dict_add_string(di, "abbr", match->cp_text[CPT_ABBR]);
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 (add_match)
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);
}
/* /*
* Get complete information * Get complete information
*/ */
@ -3264,13 +3284,13 @@ get_complete_info(list_T *what_list, dict_T *retdict)
#define CI_WHAT_PUM_VISIBLE 0x02 #define CI_WHAT_PUM_VISIBLE 0x02
#define CI_WHAT_ITEMS 0x04 #define CI_WHAT_ITEMS 0x04
#define CI_WHAT_SELECTED 0x08 #define CI_WHAT_SELECTED 0x08
#define CI_WHAT_INSERTED 0x10 #define CI_WHAT_COMPLETED 0x10
#define CI_WHAT_MATCHES 0x20 #define CI_WHAT_MATCHES 0x20
#define CI_WHAT_ALL 0xff #define CI_WHAT_ALL 0xff
int what_flag; int what_flag;
if (what_list == NULL) if (what_list == NULL)
what_flag = CI_WHAT_ALL & ~CI_WHAT_MATCHES; what_flag = CI_WHAT_ALL & ~(CI_WHAT_MATCHES | CI_WHAT_COMPLETED);
else else
{ {
what_flag = 0; what_flag = 0;
@ -3287,8 +3307,8 @@ get_complete_info(list_T *what_list, dict_T *retdict)
what_flag |= CI_WHAT_ITEMS; what_flag |= CI_WHAT_ITEMS;
else if (STRCMP(what, "selected") == 0) else if (STRCMP(what, "selected") == 0)
what_flag |= CI_WHAT_SELECTED; what_flag |= CI_WHAT_SELECTED;
else if (STRCMP(what, "inserted") == 0) else if (STRCMP(what, "completed") == 0)
what_flag |= CI_WHAT_INSERTED; what_flag |= CI_WHAT_COMPLETED;
else if (STRCMP(what, "matches") == 0) else if (STRCMP(what, "matches") == 0)
what_flag |= CI_WHAT_MATCHES; what_flag |= CI_WHAT_MATCHES;
} }
@ -3300,8 +3320,8 @@ get_complete_info(list_T *what_list, dict_T *retdict)
if (ret == OK && (what_flag & CI_WHAT_PUM_VISIBLE)) if (ret == OK && (what_flag & CI_WHAT_PUM_VISIBLE))
ret = dict_add_number(retdict, "pum_visible", 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 | CI_WHAT_SELECTED
|| what_flag & CI_WHAT_MATCHES)) | CI_WHAT_MATCHES | CI_WHAT_COMPLETED)))
{ {
list_T *li = NULL; list_T *li = NULL;
dict_T *di; dict_T *di;
@ -3309,6 +3329,7 @@ get_complete_info(list_T *what_list, dict_T *retdict)
int selected_idx = -1; int selected_idx = -1;
int has_items = what_flag & CI_WHAT_ITEMS; int has_items = what_flag & CI_WHAT_ITEMS;
int has_matches = what_flag & CI_WHAT_MATCHES; int has_matches = what_flag & CI_WHAT_MATCHES;
int has_completed = what_flag & CI_WHAT_COMPLETED;
if (has_items || has_matches) if (has_items || has_matches)
{ {
@ -3338,18 +3359,7 @@ get_complete_info(list_T *what_list, dict_T *retdict)
ret = list_append_dict(li, di); ret = list_append_dict(li, di);
if (ret != OK) if (ret != OK)
return; return;
dict_add_string(di, "word", match->cp_str.string); fill_complete_info_dict(di, match, has_matches && has_items);
dict_add_string(di, "abbr", match->cp_text[CPT_ABBR]);
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 if (compl_curr_match != NULL
&& compl_curr_match->cp_number == match->cp_number) && compl_curr_match->cp_number == match->cp_number)
@ -3362,11 +3372,15 @@ get_complete_info(list_T *what_list, dict_T *retdict)
} }
if (ret == OK && (what_flag & CI_WHAT_SELECTED)) if (ret == OK && (what_flag & CI_WHAT_SELECTED))
ret = dict_add_number(retdict, "selected", selected_idx); ret = dict_add_number(retdict, "selected", selected_idx);
}
if (ret == OK && (what_flag & CI_WHAT_INSERTED)) if (ret == OK && selected_idx != -1 && has_completed)
{ {
// TODO di = dict_alloc();
if (di == NULL)
return;
fill_complete_info_dict(di, compl_curr_match, FALSE);
ret = dict_add_dict(retdict, "completed", di);
}
} }
} }

View File

@ -2975,4 +2975,34 @@ func Test_complete_info_matches()
set cot& set cot&
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab nofoldenable

View File

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