0
0
mirror of https://github.com/vim/vim.git synced 2025-11-14 23:04:02 -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 Returns a |Dictionary| with information about Insert mode
completion. See |ins-completion|. completion. See |ins-completion|.
The items are: The items are:
mode Current completion mode name string. completed Return a dictionary containing the entries of
See |complete_info_mode| for the values. the currently selected index item.
pum_visible |TRUE| if popup menu is visible.
See |pumvisible()|.
items List of all completion candidates. Each item items List of all completion candidates. Each item
is a dictionary containing the entries "word", is a dictionary containing the entries "word",
"abbr", "menu", "kind", "info" and "abbr", "menu", "kind", "info" and
@@ -2015,13 +2013,18 @@ complete_info([{what}]) *complete_info()*
and "items" are in "what", the returned list and "items" are in "what", the returned list
will still be named "items", but each item will still be named "items", but each item
will have an additional "match" field. 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. selected Selected item index. First index is zero.
Index is -1 if no item is selected (showing Index is -1 if no item is selected (showing
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)
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

@@ -4192,6 +4192,7 @@ get_complete_info(list_T *what_list, dict_T *retdict)
#define CI_WHAT_SELECTED 0x08 #define CI_WHAT_SELECTED 0x08
#define CI_WHAT_COMPLETED 0x10 #define CI_WHAT_COMPLETED 0x10
#define CI_WHAT_MATCHES 0x20 #define CI_WHAT_MATCHES 0x20
#define CI_WHAT_PREINSERTED_TEXT 0x40
#define CI_WHAT_ALL 0xff #define CI_WHAT_ALL 0xff
int what_flag; int what_flag;
@@ -4215,6 +4216,8 @@ get_complete_info(list_T *what_list, dict_T *retdict)
what_flag |= CI_WHAT_SELECTED; what_flag |= CI_WHAT_SELECTED;
else if (STRCMP(what, "completed") == 0) else if (STRCMP(what, "completed") == 0)
what_flag |= CI_WHAT_COMPLETED; what_flag |= CI_WHAT_COMPLETED;
else if (STRCMP(what, "preinserted_text") == 0)
what_flag |= CI_WHAT_PREINSERTED_TEXT;
else if (STRCMP(what, "matches") == 0) else if (STRCMP(what, "matches") == 0)
what_flag |= CI_WHAT_MATCHES; 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)) 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_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 if (ret == OK && (what_flag & (CI_WHAT_ITEMS | CI_WHAT_SELECTED
| CI_WHAT_MATCHES | CI_WHAT_COMPLETED))) | CI_WHAT_MATCHES | CI_WHAT_COMPLETED)))
{ {

View File

@@ -572,15 +572,15 @@ func Test_completefunc_info()
set completeopt=menuone set completeopt=menuone
set completefunc=CompleteTest set completefunc=CompleteTest
call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx") 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 %d
set complete=.,FCompleteTest set complete=.,FCompleteTest
call feedkeys("i\<C-N>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx") 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 %d
set complete=.,F set complete=.,F
call feedkeys("i\<C-N>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx") 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 completeopt&
set complete& set complete&
set completefunc& set completefunc&
@@ -698,17 +698,17 @@ func CompleteInfoTestUserDefinedFn(mvmt, idx, noselect)
set completefunc=CompleteInfoUserDefinedFn set completefunc=CompleteInfoUserDefinedFn
call feedkeys("i\<C-X>\<C-U>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx") 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) : '' 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 %d
set complete=.,FCompleteInfoUserDefinedFn set complete=.,FCompleteInfoUserDefinedFn
call feedkeys("i\<C-N>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx") 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) : '' 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 %d
set complete=.,F set complete=.,F
call feedkeys("i\<C-N>" . a:mvmt . "\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx") 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) : '' 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! bwipe!
set completeopt& completefunc& complete& set completeopt& completefunc& complete&
endfunc endfunc
@@ -5904,6 +5904,26 @@ func Test_autocomplete_longest()
call DoTest("f", 'foobar', 2) call DoTest("f", 'foobar', 2)
call assert_equal(1, g:preinserted) 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 " Undo
%delete _ %delete _
let &l:undolevels = &l:undolevels 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': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''},
\ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''} \ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}
\ ], \ ],
\ 'preinserted_text': '',
\ 'selected': 0, \ 'selected': 0,
\ } \ }
@@ -1170,7 +1171,7 @@ func Test_popup_complete_info_02()
call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
call assert_equal(d, g:compl_info) 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 remove(d, 'items')
call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
call assert_equal(d, g:compl_info) call assert_equal(d, g:compl_info)
@@ -1178,6 +1179,7 @@ func Test_popup_complete_info_02()
let g:compl_what = ['mode'] let g:compl_what = ['mode']
call remove(d, 'selected') call remove(d, 'selected')
call remove(d, 'pum_visible') call remove(d, 'pum_visible')
call remove(d, 'preinserted_text')
call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
call assert_equal(d, g:compl_info) call assert_equal(d, g:compl_info)
bwipe! bwipe!
@@ -1191,6 +1193,7 @@ func Test_popup_complete_info_no_pum()
\ 'mode': '', \ 'mode': '',
\ 'pum_visible': 0, \ 'pum_visible': 0,
\ 'items': [], \ 'items': [],
\ 'preinserted_text': '',
\ 'selected': -1, \ 'selected': -1,
\ } \ }
call assert_equal( d, complete_info() ) call assert_equal( d, complete_info() )

View File

@@ -819,7 +819,7 @@ enddef
def Test_complete_info() 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 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']) 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'])) assert_equal({'mode': '', 'items': []}, complete_info(['mode', 'items']))
enddef enddef

View File

@@ -729,6 +729,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 */
/**/
1876,
/**/ /**/
1875, 1875,
/**/ /**/