0
0
mirror of https://github.com/vim/vim.git synced 2025-11-13 22:54:27 -05:00

patch 9.1.1876: pre-inserted text not exposed in cmdcomplete_info()

Problem:  pre-inserted text not exposed in complete_info()
Solution: Add the pre-inserted text to the complete_info() Vim script
          function (Girish Palya)

closes: #18571

Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Feat: expose preinserted text in complete_info()

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Girish Palya
2025-10-26 18:30:40 +00:00
committed by Christian Brabandt
parent f17f78c557
commit ef5bf58d8c
6 changed files with 61 additions and 21 deletions

View File

@@ -2001,10 +2001,8 @@ complete_info([{what}]) *complete_info()*
Returns a |Dictionary| with information about Insert mode
completion. See |ins-completion|.
The items are:
mode Current completion mode name string.
See |complete_info_mode| for the values.
pum_visible |TRUE| if popup menu is visible.
See |pumvisible()|.
completed Return a dictionary containing the entries of
the currently selected index item.
items List of all completion candidates. Each item
is a dictionary containing the entries "word",
"abbr", "menu", "kind", "info" and
@@ -2015,13 +2013,18 @@ complete_info([{what}]) *complete_info()*
and "items" are in "what", the returned list
will still be named "items", but each item
will have an additional "match" field.
mode Current completion mode name string.
See |complete_info_mode| for the values.
preinserted_text
The actual text that is pre-inserted, see
|preinserted()|.
pum_visible |TRUE| if popup menu is visible.
See |pumvisible()|.
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
no item is selected when using the <Up> or
<Down> keys)
completed Return a dictionary containing the entries of
the currently selected index item.
*complete_info_mode*
mode values are:

View File

@@ -4186,13 +4186,14 @@ get_complete_info(list_T *what_list, dict_T *retdict)
{
int ret = OK;
listitem_T *item;
#define CI_WHAT_MODE 0x01
#define CI_WHAT_PUM_VISIBLE 0x02
#define CI_WHAT_ITEMS 0x04
#define CI_WHAT_SELECTED 0x08
#define CI_WHAT_COMPLETED 0x10
#define CI_WHAT_MATCHES 0x20
#define CI_WHAT_ALL 0xff
#define CI_WHAT_MODE 0x01
#define CI_WHAT_PUM_VISIBLE 0x02
#define CI_WHAT_ITEMS 0x04
#define CI_WHAT_SELECTED 0x08
#define CI_WHAT_COMPLETED 0x10
#define CI_WHAT_MATCHES 0x20
#define CI_WHAT_PREINSERTED_TEXT 0x40
#define CI_WHAT_ALL 0xff
int what_flag;
if (what_list == NULL)
@@ -4215,6 +4216,8 @@ get_complete_info(list_T *what_list, dict_T *retdict)
what_flag |= CI_WHAT_SELECTED;
else if (STRCMP(what, "completed") == 0)
what_flag |= CI_WHAT_COMPLETED;
else if (STRCMP(what, "preinserted_text") == 0)
what_flag |= CI_WHAT_PREINSERTED_TEXT;
else if (STRCMP(what, "matches") == 0)
what_flag |= CI_WHAT_MATCHES;
}
@@ -4226,6 +4229,15 @@ 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_PREINSERTED_TEXT))
{
char_u *line = ml_get_curline();
int len = compl_ins_end_col - curwin->w_cursor.col;
ret = dict_add_string_len(retdict, "preinserted_text",
(len > 0) ? line + curwin->w_cursor.col : (char_u *)"", len);
}
if (ret == OK && (what_flag & (CI_WHAT_ITEMS | CI_WHAT_SELECTED
| CI_WHAT_MATCHES | CI_WHAT_COMPLETED)))
{

View File

@@ -572,15 +572,15 @@ func Test_completefunc_info()
set completeopt=menuone
set completefunc=CompleteTest
call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
call assert_equal("matched{'preinserted_text': '', 'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
%d
set complete=.,FCompleteTest
call feedkeys("i\<C-N>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'keyword', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
call assert_equal("matched{'preinserted_text': '', 'pum_visible': 1, 'mode': 'keyword', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
%d
set complete=.,F
call feedkeys("i\<C-N>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'keyword', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
call assert_equal("matched{'preinserted_text': '', 'pum_visible': 1, 'mode': 'keyword', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
set completeopt&
set complete&
set completefunc&
@@ -698,17 +698,17 @@ func CompleteInfoTestUserDefinedFn(mvmt, idx, noselect)
set completefunc=CompleteInfoUserDefinedFn
call feedkeys("i\<C-X>\<C-U>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
call assert_equal(completed. "{'pum_visible': 1, 'mode': 'function', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
call assert_equal(completed. "{'preinserted_text': '', 'pum_visible': 1, 'mode': 'function', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
%d
set complete=.,FCompleteInfoUserDefinedFn
call feedkeys("i\<C-N>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
call assert_equal(completed. "{'pum_visible': 1, 'mode': 'keyword', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
call assert_equal(completed. "{'preinserted_text': '', 'pum_visible': 1, 'mode': 'keyword', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
%d
set complete=.,F
call feedkeys("i\<C-N>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
let completed = a:idx != -1 ? ['foo', 'bar', 'baz', 'qux']->get(a:idx) : ''
call assert_equal(completed. "{'pum_visible': 1, 'mode': 'keyword', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
call assert_equal(completed. "{'preinserted_text': '', 'pum_visible': 1, 'mode': 'keyword', 'selected': " . a:idx . ", 'items': " . items . "}", getline(1))
bwipe!
set completeopt& completefunc& complete&
endfunc
@@ -5904,6 +5904,26 @@ func Test_autocomplete_longest()
call DoTest("f", 'foobar', 2)
call assert_equal(1, g:preinserted)
" complete_info()
%delete
func GetPreinsert()
let g:cinfo = complete_info(['preinserted_text'])
return ""
endfunc
inoremap <buffer><F6> <C-R>=GetPreinsert()<CR>
call setline(1, ["foo_bar_xyz", "foo__xyz"])
set completeopt& completeopt+=preinsert
call feedkeys("G4li\<F6>\<C-Y>", 'tx')
call assert_equal("bar_xyz", g:cinfo.preinserted_text)
set completeopt& completeopt+=longest
call feedkeys("Gof\<F6>\<ESC>", 'tx')
call assert_equal("oo_bar_xyz", g:cinfo.preinserted_text)
unlet g:cinfo
delfunc GetPreinsert
set completeopt&
" Undo
%delete _
let &l:undolevels = &l:undolevels

View File

@@ -1163,6 +1163,7 @@ func Test_popup_complete_info_02()
\ {'word': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''},
\ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}
\ ],
\ 'preinserted_text': '',
\ 'selected': 0,
\ }
@@ -1170,7 +1171,7 @@ func Test_popup_complete_info_02()
call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
call assert_equal(d, g:compl_info)
let g:compl_what = ['mode', 'pum_visible', 'selected']
let g:compl_what = ['mode', 'pum_visible', 'preinserted_text', 'selected']
call remove(d, 'items')
call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
call assert_equal(d, g:compl_info)
@@ -1178,6 +1179,7 @@ func Test_popup_complete_info_02()
let g:compl_what = ['mode']
call remove(d, 'selected')
call remove(d, 'pum_visible')
call remove(d, 'preinserted_text')
call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
call assert_equal(d, g:compl_info)
bwipe!
@@ -1191,6 +1193,7 @@ func Test_popup_complete_info_no_pum()
\ 'mode': '',
\ 'pum_visible': 0,
\ 'items': [],
\ 'preinserted_text': '',
\ 'selected': -1,
\ }
call assert_equal( d, complete_info() )

View File

@@ -819,7 +819,7 @@ enddef
def Test_complete_info()
v9.CheckSourceDefAndScriptFailure(['complete_info("")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1'])
v9.CheckSourceDefAndScriptFailure(['complete_info({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1211: List required for argument 1'])
assert_equal({'pum_visible': 0, 'mode': '', 'selected': -1, 'items': []}, complete_info())
assert_equal({'pum_visible': 0, 'mode': '', 'preinserted_text': '', 'selected': -1, 'items': []}, complete_info())
assert_equal({'mode': '', 'items': []}, complete_info(['mode', 'items']))
enddef

View File

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