patch 9.1.1797: completion: autocompletion can be improved
Problem: completion: autocompletion can be improved
Solution: Add support for "longest" and "preinsert" in 'autocomplete';
add preinserted() (Girish Palya)
* Add support for "longest" in 'completeopt' when 'autocomplete'
is enabled. (Note: the cursor position does not change automatically
when 'autocomplete' is enabled.)
* Add support for "preinsert" when 'autocomplete' is enabled. Ensure
"preinsert" works the same with and without 'autocomplete'
* introduce the preinserted() Vim script function, useful for defining
custom key mappings.
fixes: #18314
closes: #18387
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
3fc1f2a00e
commit
c05335082a
@ -453,6 +453,7 @@ popup_setoptions({id}, {options})
|
|||||||
popup_settext({id}, {text}) none set the text of popup window {id}
|
popup_settext({id}, {text}) none set the text of popup window {id}
|
||||||
popup_show({id}) Number unhide popup window {id}
|
popup_show({id}) Number unhide popup window {id}
|
||||||
pow({x}, {y}) Float {x} to the power of {y}
|
pow({x}, {y}) Float {x} to the power of {y}
|
||||||
|
preinserted() Number whether text is inserted after cursor
|
||||||
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
|
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
|
||||||
printf({fmt}, {expr1}...) String format text
|
printf({fmt}, {expr1}...) String format text
|
||||||
prompt_getprompt({buf}) String get prompt text
|
prompt_getprompt({buf}) String get prompt text
|
||||||
@ -8033,6 +8034,15 @@ pow({x}, {y}) *pow()*
|
|||||||
Return type: |Number|
|
Return type: |Number|
|
||||||
|
|
||||||
|
|
||||||
|
preinserted() *preinserted()*
|
||||||
|
Returns non-zero if text has been inserted after the cursor
|
||||||
|
because "preinsert" is present in 'completeopt', or if
|
||||||
|
"longest" is present in 'completeopt' while 'autocomplete'
|
||||||
|
is enabled. Otherwise returns zero.
|
||||||
|
|
||||||
|
Return type: |Number|
|
||||||
|
|
||||||
|
|
||||||
prevnonblank({lnum}) *prevnonblank()*
|
prevnonblank({lnum}) *prevnonblank()*
|
||||||
Return the line number of the first line at or above {lnum}
|
Return the line number of the first line at or above {lnum}
|
||||||
that is not blank. Example: >
|
that is not blank. Example: >
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
*options.txt* For Vim version 9.1. Last change: 2025 Sep 22
|
*options.txt* For Vim version 9.1. Last change: 2025 Sep 26
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -2256,11 +2256,22 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
to gather more alternatives for your candidate list,
|
to gather more alternatives for your candidate list,
|
||||||
see 'completefuzzycollect'.
|
see 'completefuzzycollect'.
|
||||||
|
|
||||||
longest Only insert the longest common text of the matches. If
|
longest
|
||||||
the menu is displayed you can use CTRL-L to add more
|
When 'autocomplete' is not active, only the longest
|
||||||
characters. Whether case is ignored depends on the kind
|
common prefix of the matches is inserted. If the popup
|
||||||
of completion. For buffer text the 'ignorecase' option is
|
menu is displayed, you can use CTRL-L to add more
|
||||||
used.
|
characters. Whether case is ignored depends on the type
|
||||||
|
of completion. For buffer text the 'ignorecase' option
|
||||||
|
applies.
|
||||||
|
|
||||||
|
When 'autocomplete' is active and no completion item is
|
||||||
|
selected, the longest common prefix of the matches is
|
||||||
|
inserted after the cursor. The prefix is taken either
|
||||||
|
from all displayed items or only from items in the current
|
||||||
|
buffer. The inserted text is highlighted with
|
||||||
|
|hl-PreInsert|, and the cursor position does not change
|
||||||
|
(similar to `"preinsert"`). Press CTRL-Y to accept.
|
||||||
|
See also |preinserted()|.
|
||||||
|
|
||||||
menu Use a popup menu to show the possible completions. The
|
menu Use a popup menu to show the possible completions. The
|
||||||
menu is only shown when there is more than one match and
|
menu is only shown when there is more than one match and
|
||||||
@ -2302,22 +2313,21 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
{only works when compiled with the |+textprop| feature}
|
{only works when compiled with the |+textprop| feature}
|
||||||
|
|
||||||
preinsert
|
preinsert
|
||||||
When 'autocomplete' is not active, inserts the part of the
|
Inserts the text of the first completion candidate
|
||||||
first candidate word beyond the current completion leader,
|
beyond the current leader, highlighted with |hl-PreInsert|.
|
||||||
highlighted with |hl-PreInsert|. The cursor doesn't move.
|
The cursor does not move.
|
||||||
Requires "fuzzy" unset and "menuone" in 'completeopt'.
|
Requires "fuzzy" to be unset, and either "menuone" in
|
||||||
|
'completeopt' or 'autocomplete' enabled. When
|
||||||
When 'autocomplete' is active, inserts the longest common
|
'autocomplete' is enabled, this does not work if
|
||||||
prefix of matches (from all shown items or from the
|
'ignorecase' is set without 'infercase'.
|
||||||
current buffer items). This occurs only when no menu item
|
See also |preinserted()|.
|
||||||
is selected. Press CTRL-Y to accept.
|
|
||||||
|
|
||||||
preview Show extra information about the currently selected
|
preview Show extra information about the currently selected
|
||||||
completion in the preview window. Only works in
|
completion in the preview window. Only works in
|
||||||
combination with "menu" or "menuone".
|
combination with "menu" or "menuone".
|
||||||
|
|
||||||
Only "fuzzy", "popup", "popuphidden", "preinsert" and "preview" have
|
Only "fuzzy", "longest", "popup", "popuphidden", "preinsert" and
|
||||||
an effect when 'autocomplete' is enabled.
|
"preview" have an effect when 'autocomplete' is enabled.
|
||||||
|
|
||||||
This option does not apply to |cmdline-completion|. See 'wildoptions'
|
This option does not apply to |cmdline-completion|. See 'wildoptions'
|
||||||
for that.
|
for that.
|
||||||
|
|||||||
@ -9774,6 +9774,7 @@ postscript-print-util print.txt /*postscript-print-util*
|
|||||||
postscript-printing print.txt /*postscript-printing*
|
postscript-printing print.txt /*postscript-printing*
|
||||||
pow() builtin.txt /*pow()*
|
pow() builtin.txt /*pow()*
|
||||||
ppwiz.vim syntax.txt /*ppwiz.vim*
|
ppwiz.vim syntax.txt /*ppwiz.vim*
|
||||||
|
preinserted() builtin.txt /*preinserted()*
|
||||||
press-enter message.txt /*press-enter*
|
press-enter message.txt /*press-enter*
|
||||||
press-return message.txt /*press-return*
|
press-return message.txt /*press-return*
|
||||||
prevcount-variable eval.txt /*prevcount-variable*
|
prevcount-variable eval.txt /*prevcount-variable*
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
*usr_41.txt* For Vim version 9.1. Last change: 2025 Aug 23
|
*usr_41.txt* For Vim version 9.1. Last change: 2025 Sep 26
|
||||||
|
|
||||||
VIM USER MANUAL - by Bram Moolenaar
|
VIM USER MANUAL - by Bram Moolenaar
|
||||||
|
|
||||||
@ -1135,6 +1135,7 @@ Insert mode completion: *completion-functions*
|
|||||||
complete_info() get current completion information
|
complete_info() get current completion information
|
||||||
complete_match() get insert completion start match col and
|
complete_match() get insert completion start match col and
|
||||||
trigger text
|
trigger text
|
||||||
|
preinserted() check if text is inserted after cursor
|
||||||
pumvisible() check if the popup menu is displayed
|
pumvisible() check if the popup menu is displayed
|
||||||
pum_getpos() position and size of popup menu if visible
|
pum_getpos() position and size of popup menu if visible
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
*version9.txt* For Vim version 9.1. Last change: 2025 Sep 22
|
*version9.txt* For Vim version 9.1. Last change: 2025 Sep 26
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -41803,6 +41803,8 @@ Functions: ~
|
|||||||
|matchstrlist()| all the matches of a pattern in a List of strings
|
|matchstrlist()| all the matches of a pattern in a List of strings
|
||||||
|ngettext()| lookup single/plural message translation
|
|ngettext()| lookup single/plural message translation
|
||||||
|popup_setbuf()| switch to a different buffer in a popup
|
|popup_setbuf()| switch to a different buffer in a popup
|
||||||
|
|preinserted()| whether preinserted text has been inserted during
|
||||||
|
completion (see 'completeopt')
|
||||||
|str2blob()| convert a List of strings into a blob
|
|str2blob()| convert a List of strings into a blob
|
||||||
|test_null_tuple()| return a null tuple
|
|test_null_tuple()| return a null tuple
|
||||||
|tuple2list()| turn a Tuple of items into a List
|
|tuple2list()| turn a Tuple of items into a List
|
||||||
|
|||||||
@ -156,7 +156,7 @@ syn keyword vimFuncName contained abs acos add and append appendbufline argc arg
|
|||||||
syn keyword vimFuncName contained char2nr charclass charcol charidx chdir cindent clearmatches cmdcomplete_info col complete complete_add complete_check complete_info complete_match confirm copy cos cosh count cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set digraph_setlist echoraw empty environ err_teapot escape eval eventhandler executable execute exepath exists exists_compiled exp expand expandcmd extend extendnew feedkeys filecopy filereadable filewritable filter finddir findfile flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand funcref function garbagecollect
|
syn keyword vimFuncName contained char2nr charclass charcol charidx chdir cindent clearmatches cmdcomplete_info col complete complete_add complete_check complete_info complete_match confirm copy cos cosh count cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set digraph_setlist echoraw empty environ err_teapot escape eval eventhandler executable execute exepath exists exists_compiled exp expand expandcmd extend extendnew feedkeys filecopy filereadable filewritable filter finddir findfile flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand funcref function garbagecollect
|
||||||
syn keyword vimFuncName contained get getbufinfo getbufline getbufoneline getbufvar getcellpixels getcellwidths getchangelist getchar getcharmod getcharpos getcharsearch getcharstr getcmdcomplpat getcmdcompltype getcmdline getcmdpos getcmdprompt getcmdscreenpos getcmdtype getcmdwintype getcompletion getcompletiontype getcurpos getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos getqflist getreg getreginfo getregion getregionpos getregtype getscriptinfo getstacktrace gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key haslocaldir hasmapto
|
syn keyword vimFuncName contained get getbufinfo getbufline getbufoneline getbufvar getcellpixels getcellwidths getchangelist getchar getcharmod getcharpos getcharsearch getcharstr getcmdcomplpat getcmdcompltype getcmdline getcmdpos getcmdprompt getcmdscreenpos getcmdtype getcmdwintype getcompletion getcompletiontype getcurpos getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos getqflist getreg getreginfo getregion getregionpos getregtype getscriptinfo getstacktrace gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key haslocaldir hasmapto
|
||||||
syn keyword vimFuncName contained histadd histdel histget histnr hlID hlexists hlget hlset hostname iconv id indent index indexof input inputdialog inputlist inputrestore inputsave inputsecret insert instanceof interrupt invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel job_info job_setoptions job_start job_status job_stop join js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr line line2byte lispindent list2blob list2str list2tuple listener_add listener_flush listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min mkdir mode
|
syn keyword vimFuncName contained histadd histdel histget histnr hlID hlexists hlget hlset hostname iconv id indent index indexof input inputdialog inputlist inputrestore inputsave inputsecret insert instanceof interrupt invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel job_info job_setoptions job_start job_status job_stop join js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr line line2byte lispindent list2blob list2str list2tuple listener_add listener_flush listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min mkdir mode
|
||||||
syn keyword vimFuncName contained mzeval nextnonblank ngettext nr2char or pathshorten perleval popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog popup_filter_menu popup_filter_yesno popup_findecho popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf popup_setoptions popup_settext popup_show pow prevnonblank printf prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex readfile reduce reg_executing
|
syn keyword vimFuncName contained mzeval nextnonblank ngettext nr2char or pathshorten perleval popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog popup_filter_menu popup_filter_yesno popup_findecho popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf popup_setoptions popup_settext popup_show pow preinserted prevnonblank printf prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex readfile reduce reg_executing
|
||||||
syn keyword vimFuncName contained reg_recording reltime reltimefloat reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remote_startserver remove rename repeat resolve reverse round rubyeval screenattr screenchar screenchars screencol screenpos screenrow screenstring search searchcount searchdecl searchpair searchpairpos searchpos server2client serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh slice
|
syn keyword vimFuncName contained reg_recording reltime reltimefloat reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remote_startserver remove rename repeat resolve reverse round rubyeval screenattr screenchar screenchars screencol screenpos screenrow screenstring search searchcount searchdecl searchpair searchpairpos searchpos server2client serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh slice
|
||||||
syn keyword vimFuncName contained sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2blob str2float str2list str2nr strcharlen strcharpart strchars strdisplaywidth strftime strgetchar stridx string strlen strpart strptime strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob term_getline term_getscrolled term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape term_sendkeys term_setansicolors
|
syn keyword vimFuncName contained sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2blob str2float str2list str2nr strcharlen strcharpart strchars strdisplaywidth strftime strgetchar stridx string strlen strpart strptime strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob term_getline term_getscrolled term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape term_sendkeys term_setansicolors
|
||||||
syn keyword vimFuncName contained term_setapi term_setkill term_setrestore term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now test_garbagecollect_soon test_getvalue test_gui_event test_ignore_error test_mswin_event test_null_blob test_null_channel test_null_dict test_null_function test_null_job test_null_list test_null_partial test_null_string test_null_tuple test_option_not_set test_override test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr trim trunc tuple2list type typename undofile undotree uniq uri_decode uri_encode utf16idx values virtcol virtcol2col visualmode wildmenumode wildtrigger
|
syn keyword vimFuncName contained term_setapi term_setkill term_setrestore term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now test_garbagecollect_soon test_getvalue test_gui_event test_ignore_error test_mswin_event test_null_blob test_null_channel test_null_dict test_null_function test_null_job test_null_list test_null_partial test_null_string test_null_tuple test_option_not_set test_override test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr trim trunc tuple2list type typename undofile undotree uniq uri_decode uri_encode utf16idx values virtcol virtcol2col visualmode wildmenumode wildtrigger
|
||||||
|
|||||||
11
src/edit.c
11
src/edit.c
@ -693,11 +693,12 @@ edit(
|
|||||||
&& stop_arrow() == OK)
|
&& stop_arrow() == OK)
|
||||||
{
|
{
|
||||||
ins_compl_delete();
|
ins_compl_delete();
|
||||||
if (ins_compl_has_preinsert()
|
ins_compl_insert(FALSE, !ins_compl_has_preinsert());
|
||||||
&& ins_compl_autocomplete_enabled())
|
if (ins_compl_preinsert_longest())
|
||||||
(void)ins_compl_insert(FALSE, TRUE);
|
{
|
||||||
else
|
ins_compl_init_get_longest();
|
||||||
(void)ins_compl_insert(FALSE, FALSE);
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Delete preinserted text when typing special chars
|
// Delete preinserted text when typing special chars
|
||||||
else if (IS_WHITE_NL_OR_NUL(c) && ins_compl_preinsert_effect())
|
else if (IS_WHITE_NL_OR_NUL(c) && ins_compl_preinsert_effect())
|
||||||
|
|||||||
@ -2655,6 +2655,8 @@ static const funcentry_T global_functions[] =
|
|||||||
ret_number, PROP_FUNC(f_popup_show)},
|
ret_number, PROP_FUNC(f_popup_show)},
|
||||||
{"pow", 2, 2, FEARG_1, arg2_float_or_nr,
|
{"pow", 2, 2, FEARG_1, arg2_float_or_nr,
|
||||||
ret_float, f_pow},
|
ret_float, f_pow},
|
||||||
|
{"preinserted", 0, 0, 0, NULL,
|
||||||
|
ret_number_bool, f_preinserted},
|
||||||
{"prevnonblank", 1, 1, FEARG_1, arg1_lnum,
|
{"prevnonblank", 1, 1, FEARG_1, arg1_lnum,
|
||||||
ret_number, f_prevnonblank},
|
ret_number, f_prevnonblank},
|
||||||
{"printf", 1, 19, FEARG_2, arg119_printf,
|
{"printf", 1, 19, FEARG_2, arg119_printf,
|
||||||
|
|||||||
161
src/insexpand.c
161
src/insexpand.c
@ -210,7 +210,7 @@ static int compl_autocomplete = FALSE; // whether autocompletion is active
|
|||||||
static int compl_timeout_ms = COMPL_INITIAL_TIMEOUT_MS;
|
static int compl_timeout_ms = COMPL_INITIAL_TIMEOUT_MS;
|
||||||
static int compl_time_slice_expired = FALSE; // time budget exceeded for current source
|
static int compl_time_slice_expired = FALSE; // time budget exceeded for current source
|
||||||
static int compl_from_nonkeyword = FALSE; // completion started from non-keyword
|
static int compl_from_nonkeyword = FALSE; // completion started from non-keyword
|
||||||
static int compl_autocomplete_preinsert = FALSE; // apply preinsert highlight
|
static int compl_hi_on_autocompl_longest = FALSE; // apply "PreInsert" highlight
|
||||||
|
|
||||||
// Halve the current completion timeout, simulating exponential decay.
|
// Halve the current completion timeout, simulating exponential decay.
|
||||||
#define COMPL_MIN_TIMEOUT_MS 5
|
#define COMPL_MIN_TIMEOUT_MS 5
|
||||||
@ -853,6 +853,18 @@ is_nearest_active(void)
|
|||||||
&& !(flags & COT_FUZZY);
|
&& !(flags & COT_FUZZY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if autocomplete is active and the pre-insert effect targets the
|
||||||
|
* longest prefix.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ins_compl_preinsert_longest(void)
|
||||||
|
{
|
||||||
|
return compl_autocomplete
|
||||||
|
&& (get_cot_flags() & (COT_LONGEST | COT_PREINSERT | COT_FUZZY))
|
||||||
|
== COT_LONGEST;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a match to the list of matches. The arguments are:
|
* Add a match to the list of matches. The arguments are:
|
||||||
* str - text of the match to add
|
* str - text of the match to add
|
||||||
@ -1025,7 +1037,8 @@ ins_compl_add(
|
|||||||
compl_curr_match = match;
|
compl_curr_match = match;
|
||||||
|
|
||||||
// Find the longest common string if still doing that.
|
// Find the longest common string if still doing that.
|
||||||
if (compl_get_longest && (flags & CP_ORIGINAL_TEXT) == 0 && !cfc_has_mode())
|
if (compl_get_longest && (flags & CP_ORIGINAL_TEXT) == 0 && !cfc_has_mode()
|
||||||
|
&& !ins_compl_preinsert_longest())
|
||||||
ins_compl_longest_match(match);
|
ins_compl_longest_match(match);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@ -1084,17 +1097,14 @@ ins_compl_leader_len(void)
|
|||||||
ins_compl_col_range_attr(linenr_T lnum, int col)
|
ins_compl_col_range_attr(linenr_T lnum, int col)
|
||||||
{
|
{
|
||||||
int start_col;
|
int start_col;
|
||||||
|
int has_preinsert = ins_compl_has_preinsert()
|
||||||
|
|| ins_compl_preinsert_longest();
|
||||||
int attr;
|
int attr;
|
||||||
int has_preinsert = ins_compl_has_preinsert();
|
|
||||||
|
|
||||||
if ((get_cot_flags() & COT_FUZZY)
|
if ((get_cot_flags() & COT_FUZZY)
|
||||||
|| (!has_preinsert
|
|| (!compl_hi_on_autocompl_longest && ins_compl_preinsert_longest())
|
||||||
&& (attr = syn_name2attr((char_u *)"ComplMatchIns")) == 0)
|
|| (attr = syn_name2attr(has_preinsert
|
||||||
|| (!compl_autocomplete && has_preinsert
|
? (char_u *)"PreInsert" : (char_u *)"ComplMatchIns")) == 0)
|
||||||
&& (attr = syn_name2attr((char_u *)"PreInsert")) == 0)
|
|
||||||
|| (compl_autocomplete
|
|
||||||
&& (!compl_autocomplete_preinsert
|
|
||||||
|| (attr = syn_name2attr((char_u *)"PreInsert")) == 0)))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
start_col = compl_col + (int)ins_compl_leader_len();
|
start_col = compl_col + (int)ins_compl_leader_len();
|
||||||
@ -1613,7 +1623,7 @@ ins_compl_build_pum(void)
|
|||||||
int cur = -1;
|
int cur = -1;
|
||||||
unsigned int cur_cot_flags = get_cot_flags();
|
unsigned int cur_cot_flags = get_cot_flags();
|
||||||
int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0
|
int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0
|
||||||
|| compl_autocomplete;
|
|| (compl_autocomplete && !ins_compl_has_preinsert());
|
||||||
int fuzzy_filter = (cur_cot_flags & COT_FUZZY) != 0;
|
int fuzzy_filter = (cur_cot_flags & COT_FUZZY) != 0;
|
||||||
compl_T *match_head = NULL;
|
compl_T *match_head = NULL;
|
||||||
compl_T *match_tail = NULL;
|
compl_T *match_tail = NULL;
|
||||||
@ -2352,6 +2362,8 @@ ins_compl_len(void)
|
|||||||
ins_compl_has_preinsert(void)
|
ins_compl_has_preinsert(void)
|
||||||
{
|
{
|
||||||
int cur_cot_flags = get_cot_flags();
|
int cur_cot_flags = get_cot_flags();
|
||||||
|
if (compl_autocomplete && p_ic && !p_inf)
|
||||||
|
return FALSE;
|
||||||
return !compl_autocomplete
|
return !compl_autocomplete
|
||||||
? (cur_cot_flags & (COT_PREINSERT | COT_FUZZY | COT_MENUONE))
|
? (cur_cot_flags & (COT_PREINSERT | COT_FUZZY | COT_MENUONE))
|
||||||
== (COT_PREINSERT | COT_MENUONE)
|
== (COT_PREINSERT | COT_MENUONE)
|
||||||
@ -2365,21 +2377,12 @@ ins_compl_has_preinsert(void)
|
|||||||
int
|
int
|
||||||
ins_compl_preinsert_effect(void)
|
ins_compl_preinsert_effect(void)
|
||||||
{
|
{
|
||||||
if (!ins_compl_has_preinsert())
|
if (!ins_compl_has_preinsert() && !ins_compl_preinsert_longest())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return curwin->w_cursor.col < compl_ins_end_col;
|
return curwin->w_cursor.col < compl_ins_end_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns TRUE if autocompletion is active.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ins_compl_autocomplete_enabled(void)
|
|
||||||
{
|
|
||||||
return compl_autocomplete;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete one character before the cursor and show the subset of the matches
|
* Delete one character before the cursor and show the subset of the matches
|
||||||
* that match the word that is now before the cursor.
|
* that match the word that is now before the cursor.
|
||||||
@ -2425,7 +2428,7 @@ ins_compl_bs(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear selection if a menu item is currently selected in autocompletion
|
// Clear selection if a menu item is currently selected in autocompletion
|
||||||
if (compl_autocomplete && compl_first_match)
|
if (compl_autocomplete && compl_first_match && !ins_compl_has_preinsert())
|
||||||
compl_shown_match = compl_first_match;
|
compl_shown_match = compl_first_match;
|
||||||
|
|
||||||
ins_compl_new_leader();
|
ins_compl_new_leader();
|
||||||
@ -2538,21 +2541,14 @@ ins_compl_new_leader(void)
|
|||||||
if (!compl_interrupted)
|
if (!compl_interrupted)
|
||||||
show_pum(save_w_wrow, save_w_leftcol);
|
show_pum(save_w_wrow, save_w_leftcol);
|
||||||
|
|
||||||
compl_autocomplete_preinsert = FALSE;
|
|
||||||
// Don't let Enter select the original text when there is no popup menu.
|
// Don't let Enter select the original text when there is no popup menu.
|
||||||
if (compl_match_array == NULL)
|
if (compl_match_array == NULL)
|
||||||
compl_enter_selects = FALSE;
|
compl_enter_selects = FALSE;
|
||||||
else if (ins_compl_has_preinsert() && compl_leader.length > 0)
|
else if (ins_compl_has_preinsert() && compl_leader.length > 0)
|
||||||
{
|
ins_compl_insert(TRUE, FALSE);
|
||||||
if (compl_started && compl_autocomplete
|
else if (compl_started && ins_compl_preinsert_longest()
|
||||||
&& !ins_compl_preinsert_effect())
|
&& compl_leader.length > 0 && !ins_compl_preinsert_effect())
|
||||||
{
|
ins_compl_insert(TRUE, TRUE);
|
||||||
if (ins_compl_insert(TRUE, TRUE) == OK)
|
|
||||||
compl_autocomplete_preinsert = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(void)ins_compl_insert(TRUE, FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2602,14 +2598,14 @@ ins_compl_addleader(int c)
|
|||||||
ins_compl_restart();
|
ins_compl_restart();
|
||||||
|
|
||||||
// When 'always' is set, don't reset compl_leader. While completing,
|
// When 'always' is set, don't reset compl_leader. While completing,
|
||||||
// cursor doesn't point original position, changing compl_leader would
|
// cursor doesn't point to the original position, changing compl_leader
|
||||||
// break redo.
|
// would break redo.
|
||||||
if (!compl_opt_refresh_always)
|
if (!compl_opt_refresh_always)
|
||||||
{
|
{
|
||||||
VIM_CLEAR_STRING(compl_leader);
|
VIM_CLEAR_STRING(compl_leader);
|
||||||
compl_leader.length = (size_t)(curwin->w_cursor.col - compl_col);
|
compl_leader.length = (size_t)(curwin->w_cursor.col - compl_col);
|
||||||
compl_leader.string = vim_strnsave(ml_get_curline() + compl_col,
|
compl_leader.string = vim_strnsave(ml_get_curline() + compl_col,
|
||||||
compl_leader.length);
|
compl_leader.length);
|
||||||
if (compl_leader.string == NULL)
|
if (compl_leader.string == NULL)
|
||||||
{
|
{
|
||||||
compl_leader.length = 0;
|
compl_leader.length = 0;
|
||||||
@ -5104,7 +5100,7 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
|
|||||||
if (!in_fuzzy_collect)
|
if (!in_fuzzy_collect)
|
||||||
ptr = ins_compl_get_next_word_or_line(st->ins_buf,
|
ptr = ins_compl_get_next_word_or_line(st->ins_buf,
|
||||||
st->cur_match_pos, &len, &cont_s_ipos);
|
st->cur_match_pos, &len, &cont_s_ipos);
|
||||||
if (ptr == NULL || (!compl_autocomplete && ins_compl_has_preinsert()
|
if (ptr == NULL || (ins_compl_has_preinsert()
|
||||||
&& STRCMP(ptr, compl_pattern.string) == 0))
|
&& STRCMP(ptr, compl_pattern.string) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -5666,7 +5662,7 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
}
|
}
|
||||||
may_trigger_modechanged();
|
may_trigger_modechanged();
|
||||||
|
|
||||||
if (is_nearest_active())
|
if (is_nearest_active() && !ins_compl_has_preinsert())
|
||||||
sort_compl_match_list(cp_compare_nearest);
|
sort_compl_match_list(cp_compare_nearest);
|
||||||
|
|
||||||
return match_count;
|
return match_count;
|
||||||
@ -5907,6 +5903,22 @@ find_common_prefix(size_t *prefix_len, int curbuf_only)
|
|||||||
|
|
||||||
if (len > (int)ins_compl_leader_len())
|
if (len > (int)ins_compl_leader_len())
|
||||||
{
|
{
|
||||||
|
// Avoid inserting text that duplicates the text already present
|
||||||
|
// after the cursor.
|
||||||
|
if (len == (int)STRLEN(first))
|
||||||
|
{
|
||||||
|
char_u *line = ml_get_curline();
|
||||||
|
char_u *p = line + curwin->w_cursor.col;
|
||||||
|
if (p && !IS_WHITE_OR_NUL(*p))
|
||||||
|
{
|
||||||
|
char_u *end = find_word_end(p);
|
||||||
|
int text_len = end - p;
|
||||||
|
if (text_len > 0
|
||||||
|
&& text_len < (len - (int)ins_compl_leader_len())
|
||||||
|
&& STRNCMP(first + len - text_len, p, text_len) == 0)
|
||||||
|
len -= text_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
*prefix_len = (size_t)len;
|
*prefix_len = (size_t)len;
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
@ -5917,11 +5929,11 @@ find_common_prefix(size_t *prefix_len, int curbuf_only)
|
|||||||
* Insert the new text being completed.
|
* Insert the new text being completed.
|
||||||
* "move_cursor" is used when 'completeopt' includes "preinsert" and when TRUE
|
* "move_cursor" is used when 'completeopt' includes "preinsert" and when TRUE
|
||||||
* cursor needs to move back from the inserted text to the compl_leader.
|
* cursor needs to move back from the inserted text to the compl_leader.
|
||||||
* When "preinsert_prefix" is TRUE the longest common prefix is inserted
|
* When "insert_prefix" is TRUE the longest common prefix is inserted instead
|
||||||
* instead of shown match.
|
* of shown match.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
ins_compl_insert(int move_cursor, int preinsert_prefix)
|
ins_compl_insert(int move_cursor, int insert_prefix)
|
||||||
{
|
{
|
||||||
int compl_len = get_compl_len();
|
int compl_len = get_compl_len();
|
||||||
int preinsert = ins_compl_has_preinsert();
|
int preinsert = ins_compl_has_preinsert();
|
||||||
@ -5930,14 +5942,17 @@ ins_compl_insert(int move_cursor, int preinsert_prefix)
|
|||||||
size_t leader_len = ins_compl_leader_len();
|
size_t leader_len = ins_compl_leader_len();
|
||||||
char_u *has_multiple = vim_strchr(cp_str, '\n');
|
char_u *has_multiple = vim_strchr(cp_str, '\n');
|
||||||
|
|
||||||
if (preinsert_prefix)
|
if (insert_prefix)
|
||||||
{
|
{
|
||||||
cp_str = find_common_prefix(&cp_str_len, FALSE);
|
cp_str = find_common_prefix(&cp_str_len, FALSE);
|
||||||
if (cp_str == NULL)
|
if (cp_str == NULL)
|
||||||
{
|
{
|
||||||
cp_str = find_common_prefix(&cp_str_len, TRUE);
|
cp_str = find_common_prefix(&cp_str_len, TRUE);
|
||||||
if (cp_str == NULL)
|
if (cp_str == NULL)
|
||||||
return FAIL;
|
{
|
||||||
|
cp_str = compl_shown_match->cp_str.string;
|
||||||
|
cp_str_len = compl_shown_match->cp_str.length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Since completion sources may provide matches with varying start
|
// Since completion sources may provide matches with varying start
|
||||||
@ -5970,13 +5985,13 @@ ins_compl_insert(int move_cursor, int preinsert_prefix)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ins_compl_insert_bytes(cp_str + compl_len,
|
ins_compl_insert_bytes(cp_str + compl_len,
|
||||||
preinsert_prefix ? (int)cp_str_len - compl_len : -1);
|
insert_prefix ? (int)cp_str_len - compl_len : -1);
|
||||||
if (preinsert && move_cursor)
|
if ((preinsert || insert_prefix) && move_cursor)
|
||||||
curwin->w_cursor.col -= (colnr_T)(cp_str_len - leader_len);
|
curwin->w_cursor.col -= (colnr_T)(cp_str_len - leader_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (match_at_original_text(compl_shown_match)
|
if (match_at_original_text(compl_shown_match)
|
||||||
|| (preinsert && !compl_autocomplete))
|
|| (preinsert && !insert_prefix))
|
||||||
compl_used_match = FALSE;
|
compl_used_match = FALSE;
|
||||||
else
|
else
|
||||||
compl_used_match = TRUE;
|
compl_used_match = TRUE;
|
||||||
@ -5987,7 +6002,7 @@ ins_compl_insert(int move_cursor, int preinsert_prefix)
|
|||||||
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
|
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return OK;
|
compl_hi_on_autocompl_longest = insert_prefix && move_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6071,7 +6086,7 @@ find_next_completion_match(
|
|||||||
compl_T *found_compl = NULL;
|
compl_T *found_compl = NULL;
|
||||||
unsigned int cur_cot_flags = get_cot_flags();
|
unsigned int cur_cot_flags = get_cot_flags();
|
||||||
int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0
|
int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0
|
||||||
|| compl_autocomplete;
|
|| (compl_autocomplete && !ins_compl_has_preinsert());
|
||||||
int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
|
int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
|
||||||
string_T *leader;
|
string_T *leader;
|
||||||
|
|
||||||
@ -6201,7 +6216,7 @@ ins_compl_next(
|
|||||||
buf_T *orig_curbuf = curbuf;
|
buf_T *orig_curbuf = curbuf;
|
||||||
unsigned int cur_cot_flags = get_cot_flags();
|
unsigned int cur_cot_flags = get_cot_flags();
|
||||||
int compl_no_insert = (cur_cot_flags & COT_NOINSERT) != 0
|
int compl_no_insert = (cur_cot_flags & COT_NOINSERT) != 0
|
||||||
|| compl_autocomplete;
|
|| (compl_autocomplete && !ins_compl_has_preinsert());
|
||||||
int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
|
int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
|
||||||
int compl_preinsert = ins_compl_has_preinsert();
|
int compl_preinsert = ins_compl_has_preinsert();
|
||||||
|
|
||||||
@ -6245,38 +6260,22 @@ ins_compl_next(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
compl_autocomplete_preinsert = FALSE;
|
|
||||||
|
|
||||||
// Insert the text of the new completion, or the compl_leader.
|
// Insert the text of the new completion, or the compl_leader.
|
||||||
if (compl_no_insert && !started)
|
if (!started && ins_compl_preinsert_longest())
|
||||||
|
ins_compl_insert(TRUE, TRUE);
|
||||||
|
else if (compl_no_insert && !started && !compl_preinsert)
|
||||||
{
|
{
|
||||||
int insert_orig = !compl_preinsert;
|
ins_compl_insert_bytes(compl_orig_text.string + get_compl_len(), -1);
|
||||||
if (compl_preinsert && compl_autocomplete)
|
|
||||||
{
|
|
||||||
if (ins_compl_insert(TRUE, TRUE) == OK)
|
|
||||||
compl_autocomplete_preinsert = TRUE;
|
|
||||||
else
|
|
||||||
insert_orig = TRUE;
|
|
||||||
}
|
|
||||||
if (insert_orig)
|
|
||||||
ins_compl_insert_bytes(compl_orig_text.string + get_compl_len(), -1);
|
|
||||||
compl_used_match = FALSE;
|
compl_used_match = FALSE;
|
||||||
}
|
}
|
||||||
else if (insert_match)
|
else if (insert_match)
|
||||||
{
|
{
|
||||||
if (!compl_get_longest || compl_used_match)
|
if (!compl_get_longest || compl_used_match)
|
||||||
{
|
{
|
||||||
int none_selected = match_at_original_text(compl_shown_match);
|
int preinsert_longest = ins_compl_preinsert_longest()
|
||||||
if (compl_preinsert && compl_autocomplete
|
&& match_at_original_text(compl_shown_match); // none selected
|
||||||
&& none_selected)
|
ins_compl_insert(compl_preinsert || preinsert_longest,
|
||||||
{
|
preinsert_longest);
|
||||||
if (ins_compl_insert(none_selected, TRUE) == OK)
|
|
||||||
compl_autocomplete_preinsert = none_selected;
|
|
||||||
else
|
|
||||||
(void)ins_compl_insert(FALSE, FALSE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(void)ins_compl_insert(!compl_autocomplete, FALSE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ins_compl_insert_bytes(compl_leader.string + get_compl_len(), -1);
|
ins_compl_insert_bytes(compl_leader.string + get_compl_len(), -1);
|
||||||
@ -6417,8 +6416,8 @@ ins_compl_check_keys(int frequency, int in_compl_func)
|
|||||||
check_elapsed_time();
|
check_elapsed_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compl_pending != 0 && !got_int && !(cot_flags & COT_NOINSERT)
|
if (compl_pending && !got_int && !(cot_flags & COT_NOINSERT)
|
||||||
&& !compl_autocomplete)
|
&& (!compl_autocomplete || ins_compl_has_preinsert()))
|
||||||
{
|
{
|
||||||
// Insert the first match immediately and advance compl_shown_match,
|
// Insert the first match immediately and advance compl_shown_match,
|
||||||
// before finding other matches.
|
// before finding other matches.
|
||||||
@ -7750,3 +7749,13 @@ cpt_compl_refresh(void)
|
|||||||
compl_matches = ins_compl_make_cyclic();
|
compl_matches = ins_compl_make_cyclic();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "preinserted()" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_preinserted(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
if (ins_compl_preinsert_effect())
|
||||||
|
rettv->vval.v_number = 1;
|
||||||
|
}
|
||||||
|
|||||||
@ -48,7 +48,6 @@ colnr_T ins_compl_col(void);
|
|||||||
int ins_compl_len(void);
|
int ins_compl_len(void);
|
||||||
int ins_compl_has_preinsert(void);
|
int ins_compl_has_preinsert(void);
|
||||||
int ins_compl_preinsert_effect(void);
|
int ins_compl_preinsert_effect(void);
|
||||||
int ins_compl_autocomplete_enabled(void);
|
|
||||||
int ins_compl_bs(void);
|
int ins_compl_bs(void);
|
||||||
void ins_compl_addleader(int c);
|
void ins_compl_addleader(int c);
|
||||||
void ins_compl_addfrommatch(void);
|
void ins_compl_addfrommatch(void);
|
||||||
@ -70,10 +69,12 @@ void f_complete_check(typval_T *argvars, typval_T *rettv);
|
|||||||
void f_complete_match(typval_T *argvars, typval_T *rettv);
|
void f_complete_match(typval_T *argvars, typval_T *rettv);
|
||||||
void f_complete_info(typval_T *argvars, typval_T *rettv);
|
void f_complete_info(typval_T *argvars, typval_T *rettv);
|
||||||
void ins_compl_delete(void);
|
void ins_compl_delete(void);
|
||||||
int ins_compl_insert(int move_cursor, int preinsert_prefix);
|
void ins_compl_insert(int move_cursor, int insert_longest);
|
||||||
void ins_compl_check_keys(int frequency, int in_compl_func);
|
void ins_compl_check_keys(int frequency, int in_compl_func);
|
||||||
int ins_complete(int c, int enable_pum);
|
int ins_complete(int c, int enable_pum);
|
||||||
void ins_compl_enable_autocomplete(void);
|
void ins_compl_enable_autocomplete(void);
|
||||||
void free_insexpand_stuff(void);
|
void free_insexpand_stuff(void);
|
||||||
int ins_compl_has_autocomplete(void);
|
int ins_compl_has_autocomplete(void);
|
||||||
|
int ins_compl_preinsert_longest(void);
|
||||||
|
void f_preinserted(typval_T *argvars UNUSED, typval_T *rettv UNUSED);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
|f+0&#ffffff0|o@1| @71
|
|f+0&#ffffff0|o@1| @71
|
||||||
|f|o@1|b|a|r| @68
|
|f|o@1|b|a|r| @68
|
||||||
|f|o@1|b|a|r|b|a|z| @65
|
|f|o@1|b|a|r|b|a|z| @65
|
||||||
|f>o+0#00e0003&@1| +0#0000000&@71
|
|f|o@1> @71
|
||||||
|f+0#0000001#e0e0e08|o@1| @11| +0#4040ff13#ffffff0@59
|
|f+0#0000001#ffd7ff255|o@1| @11| +0#4040ff13#ffffff0@59
|
||||||
|f+0#0000001#ffd7ff255|o@1|b|a|r| @8| +0#4040ff13#ffffff0@59
|
|f+0#0000001#ffd7ff255|o@1|b|a|r| @8| +0#4040ff13#ffffff0@59
|
||||||
|f+0#0000001#ffd7ff255|o@1|b|a|r|b|a|z| @5| +0#4040ff13#ffffff0@59
|
|f+0#0000001#ffd7ff255|o@1|b|a|r|b|a|z| @5| +0#4040ff13#ffffff0@59
|
||||||
|~| @73
|
|~| @73
|
||||||
|~| @73
|
|~| @73
|
||||||
|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@33
|
|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |B+0#e000002&|a|c|k| |a|t| |o|r|i|g|i|n|a|l| +0#0000000&@29
|
||||||
|
|||||||
@ -119,10 +119,9 @@ endfunc
|
|||||||
func Test_omni_dash()
|
func Test_omni_dash()
|
||||||
func Omni(findstart, base)
|
func Omni(findstart, base)
|
||||||
if a:findstart
|
if a:findstart
|
||||||
return 5
|
return 5
|
||||||
else
|
else
|
||||||
echom a:base
|
return ['-help', '-v']
|
||||||
return ['-help', '-v']
|
|
||||||
endif
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
set omnifunc=Omni
|
set omnifunc=Omni
|
||||||
@ -4120,6 +4119,145 @@ func Test_completeopt_preinsert()
|
|||||||
delfunc Omni_test
|
delfunc Omni_test
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_autocomplete_completeopt_preinsert()
|
||||||
|
func Omni_test(findstart, base)
|
||||||
|
if a:findstart
|
||||||
|
return col(".") - 1
|
||||||
|
endif
|
||||||
|
return [#{word: "fobar"}, #{word: "foobar"}]
|
||||||
|
endfunc
|
||||||
|
set omnifunc=Omni_test complete+=o
|
||||||
|
set completeopt=preinsert autocomplete
|
||||||
|
" set completeopt=preinsert,menuone autocomplete
|
||||||
|
func GetLine()
|
||||||
|
let g:line = getline('.')
|
||||||
|
let g:col = col('.')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
call test_override("char_avail", 1)
|
||||||
|
new
|
||||||
|
inoremap <buffer><F5> <C-R>=GetLine()<CR>
|
||||||
|
call feedkeys("Sfo\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("fobar", g:line)
|
||||||
|
call assert_equal(3, g:col)
|
||||||
|
|
||||||
|
call feedkeys("Sfoo\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("foobar", g:line)
|
||||||
|
|
||||||
|
call feedkeys("Sfoo\<BS>\<BS>\<BS>", 'tx')
|
||||||
|
call assert_equal("", getline('.'))
|
||||||
|
|
||||||
|
" delete a character
|
||||||
|
call feedkeys("Sfoo\<BS>b\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("fobar", g:line)
|
||||||
|
call assert_equal(4, g:col)
|
||||||
|
|
||||||
|
set complete&
|
||||||
|
%d
|
||||||
|
call setline(1, ['fobar', 'foobar'])
|
||||||
|
|
||||||
|
call feedkeys("Gofoo\<BS>\<BS>\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("fobar", g:line)
|
||||||
|
call assert_equal(2, g:col)
|
||||||
|
|
||||||
|
call feedkeys("Shello wo\<Left>\<Left>\<Left>f\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("hello fobar wo", g:line)
|
||||||
|
call assert_equal(9, g:col)
|
||||||
|
|
||||||
|
call feedkeys("Shello wo\<Left>\<Left>\<Left>f\<BS>\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("hello wo", g:line)
|
||||||
|
call assert_equal(8, g:col)
|
||||||
|
|
||||||
|
call feedkeys("Shello wo\<Left>\<Left>\<Left>foo\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("hello foobar wo", g:line)
|
||||||
|
call assert_equal(11, g:col)
|
||||||
|
|
||||||
|
call feedkeys("Shello wo\<Left>\<Left>\<Left>foo\<BS>b\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("hello fobar wo", g:line)
|
||||||
|
call assert_equal(11, g:col)
|
||||||
|
|
||||||
|
" confirm
|
||||||
|
call feedkeys("Sf\<C-Y>", 'tx')
|
||||||
|
call assert_equal("fobar", getline('.'))
|
||||||
|
call assert_equal(5, col('.'))
|
||||||
|
|
||||||
|
" cancel
|
||||||
|
call feedkeys("Sfo\<C-E>", 'tx')
|
||||||
|
call assert_equal("fo", getline('.'))
|
||||||
|
call assert_equal(2, col('.'))
|
||||||
|
|
||||||
|
" delete preinsert part
|
||||||
|
call feedkeys("Sfo ", 'tx')
|
||||||
|
call assert_equal("fo ", getline('.'))
|
||||||
|
call assert_equal(3, col('.'))
|
||||||
|
|
||||||
|
" can not work with fuzzy
|
||||||
|
set cot+=fuzzy
|
||||||
|
call feedkeys("Sf", 'tx')
|
||||||
|
call assert_equal("f", getline('.'))
|
||||||
|
set cot-=fuzzy
|
||||||
|
|
||||||
|
" does not work with 'ignorecase' unless 'infercase' is also enabled
|
||||||
|
%d
|
||||||
|
call setline(1, ['FIX', 'fobar', 'foobar'])
|
||||||
|
set ignorecase
|
||||||
|
call feedkeys("Gof\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("f", g:line) " should not produce 'FIX'
|
||||||
|
set infercase
|
||||||
|
call feedkeys("Gof\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal("fix", g:line)
|
||||||
|
set ignorecase& infercase&
|
||||||
|
|
||||||
|
%delete _
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
normal! ifoo
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
normal! obar
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
normal! obaz
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
|
||||||
|
func CheckUndo()
|
||||||
|
let g:errmsg = ''
|
||||||
|
call assert_equal(['foo', 'bar', 'baz'], getline(1, '$'))
|
||||||
|
undo
|
||||||
|
call assert_equal(['foo', 'bar'], getline(1, '$'))
|
||||||
|
undo
|
||||||
|
call assert_equal(['foo'], getline(1, '$'))
|
||||||
|
undo
|
||||||
|
call assert_equal([''], getline(1, '$'))
|
||||||
|
later 3
|
||||||
|
call assert_equal(['foo', 'bar', 'baz'], getline(1, '$'))
|
||||||
|
call assert_equal('', v:errmsg)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Check that switching buffer with "preinsert" doesn't corrupt undo.
|
||||||
|
new
|
||||||
|
setlocal bufhidden=wipe
|
||||||
|
inoremap <buffer> <F2> <Cmd>enew!<CR>
|
||||||
|
call feedkeys("if\<F2>\<Esc>", 'tx')
|
||||||
|
bwipe!
|
||||||
|
call CheckUndo()
|
||||||
|
|
||||||
|
" Check that closing window with "preinsert" doesn't corrupt undo.
|
||||||
|
new
|
||||||
|
setlocal bufhidden=wipe
|
||||||
|
inoremap <buffer> <F2> <Cmd>close!<CR>
|
||||||
|
call feedkeys("if\<F2>\<Esc>", 'tx')
|
||||||
|
call CheckUndo()
|
||||||
|
|
||||||
|
%delete _
|
||||||
|
delfunc CheckUndo
|
||||||
|
|
||||||
|
bw!
|
||||||
|
set cot&
|
||||||
|
set omnifunc&
|
||||||
|
set autocomplete&
|
||||||
|
call test_override("char_avail", 0)
|
||||||
|
delfunc Omni_test
|
||||||
|
delfunc GetLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Check that mark positions are correct after triggering multiline completion.
|
" Check that mark positions are correct after triggering multiline completion.
|
||||||
func Test_complete_multiline_marks()
|
func Test_complete_multiline_marks()
|
||||||
func Omni_test(findstart, base)
|
func Omni_test(findstart, base)
|
||||||
@ -5583,7 +5721,7 @@ func Test_autocompletedelay()
|
|||||||
call VerifyScreenDump(buf, 'Test_autocompletedelay_6', {})
|
call VerifyScreenDump(buf, 'Test_autocompletedelay_6', {})
|
||||||
|
|
||||||
" During delay wait, user can open menu using CTRL_N completion
|
" During delay wait, user can open menu using CTRL_N completion
|
||||||
call term_sendkeys(buf, "\<Esc>:set completeopt=menuone,preinsert\<CR>")
|
call term_sendkeys(buf, "\<Esc>:set completeopt=menuone,longest\<CR>")
|
||||||
call term_sendkeys(buf, "Sf\<C-N>")
|
call term_sendkeys(buf, "Sf\<C-N>")
|
||||||
call VerifyScreenDump(buf, 'Test_autocompletedelay_7', {})
|
call VerifyScreenDump(buf, 'Test_autocompletedelay_7', {})
|
||||||
|
|
||||||
@ -5607,16 +5745,18 @@ func Test_autocompletedelay()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_autocomplete_completeopt_preinsert()
|
" Preinsert longest prefix when autocomplete
|
||||||
|
func Test_autocomplete_longest()
|
||||||
func GetLine()
|
func GetLine()
|
||||||
let g:line = getline('.')
|
let g:line = getline('.')
|
||||||
let g:col = col('.')
|
let g:col = col('.')
|
||||||
|
let g:preinserted = preinserted()
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
call test_override("char_avail", 1)
|
call test_override("char_avail", 1)
|
||||||
new
|
new
|
||||||
inoremap <buffer><F5> <C-R>=GetLine()<CR>
|
inoremap <buffer><F5> <C-R>=GetLine()<CR>
|
||||||
set completeopt=preinsert autocomplete
|
set completeopt=longest autocomplete
|
||||||
call setline(1, ["foobar", "foozbar"])
|
call setline(1, ["foobar", "foozbar"])
|
||||||
call feedkeys("Go\<ESC>", 'tx')
|
call feedkeys("Go\<ESC>", 'tx')
|
||||||
|
|
||||||
@ -5648,10 +5788,15 @@ func Test_autocomplete_completeopt_preinsert()
|
|||||||
call DoTest("f\<C-P>", 'foobar', 7)
|
call DoTest("f\<C-P>", 'foobar', 7)
|
||||||
call DoTest("fo\<BS>\<C-P>", 'foobar', 7)
|
call DoTest("fo\<BS>\<C-P>", 'foobar', 7)
|
||||||
|
|
||||||
|
" <C-Y> to accept preinserted text
|
||||||
|
inoremap <buffer><F6> <C-R>=pumvisible()<CR>
|
||||||
call DoTest("zar\<C-O>0f", 'foozar', 2)
|
call DoTest("zar\<C-O>0f", 'foozar', 2)
|
||||||
call DoTest("zar\<C-O>0f\<C-Y>", 'foozar', 4)
|
call DoTest("zar\<C-O>0f\<C-Y>", 'foozar', 4)
|
||||||
|
call DoTest("zar\<C-O>0f\<C-Y>\<F6>", 'foo1zar', 5)
|
||||||
call DoTest("zar\<C-O>0f\<C-Y>\<BS>", 'foozar', 3)
|
call DoTest("zar\<C-O>0f\<C-Y>\<BS>", 'foozar', 3)
|
||||||
|
call DoTest("zar\<C-O>0f\<C-Y>\<BS>\<F6>", 'fo1zar', 4)
|
||||||
|
|
||||||
|
" Select items in menu
|
||||||
call DoTest("zar\<C-O>0f\<C-N>", 'foozbarzar', 8)
|
call DoTest("zar\<C-O>0f\<C-N>", 'foozbarzar', 8)
|
||||||
call DoTest("zar\<C-O>0f\<C-N>\<C-N>", 'foobarzar', 7)
|
call DoTest("zar\<C-O>0f\<C-N>\<C-N>", 'foobarzar', 7)
|
||||||
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>", 'foozar', 2)
|
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>", 'foozar', 2)
|
||||||
@ -5665,6 +5810,34 @@ func Test_autocomplete_completeopt_preinsert()
|
|||||||
call DoTest("f", 'f', 2)
|
call DoTest("f", 'f', 2)
|
||||||
set cot-=fuzzy
|
set cot-=fuzzy
|
||||||
|
|
||||||
|
" preinserted()
|
||||||
|
call DoTest("f", 'foo', 2)
|
||||||
|
call assert_equal(1, g:preinserted)
|
||||||
|
call assert_equal(0, preinserted())
|
||||||
|
call DoTest("f\<BS>", '', 1)
|
||||||
|
call assert_equal(0, g:preinserted)
|
||||||
|
call DoTest("f ", 'f ', 3)
|
||||||
|
call assert_equal(0, g:preinserted)
|
||||||
|
call DoTest("foob", 'foobar', 5)
|
||||||
|
call assert_equal(1, g:preinserted)
|
||||||
|
call DoTest("foob\<BS>\<BS>x", 'fox', 4)
|
||||||
|
call assert_equal(0, g:preinserted)
|
||||||
|
|
||||||
|
" Complete non-keyword
|
||||||
|
func Omni(findstart, base)
|
||||||
|
if a:findstart
|
||||||
|
return 5
|
||||||
|
else
|
||||||
|
return ['xyz:']
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
set omnifunc=Omni
|
||||||
|
set cpt+=o
|
||||||
|
call DoTest("xyz:", "xyz:xyz:", 5)
|
||||||
|
call DoTest("xyz:\<BS>\<BS>", "xyz:", 3)
|
||||||
|
set omnifunc& cpt&
|
||||||
|
delfunc Omni
|
||||||
|
|
||||||
" leader should match prefix of inserted word
|
" leader should match prefix of inserted word
|
||||||
%delete
|
%delete
|
||||||
set smartcase ignorecase
|
set smartcase ignorecase
|
||||||
@ -5675,6 +5848,16 @@ func Test_autocomplete_completeopt_preinsert()
|
|||||||
call assert_equal('FOO', g:line)
|
call assert_equal('FOO', g:line)
|
||||||
set smartcase& ignorecase&
|
set smartcase& ignorecase&
|
||||||
|
|
||||||
|
" avoid repeating text that is already present after the cursor
|
||||||
|
%delete
|
||||||
|
call setline(1, ["foobarbaz", ""])
|
||||||
|
call feedkeys($"G", 'tx')
|
||||||
|
call DoTest("baz\<C-O>0f", "foobarbaz", 2)
|
||||||
|
call feedkeys($"Sxfoozar\<CR>\<Esc>", 'tx')
|
||||||
|
call DoTest("baz\<C-O>0f", "foobarbaz", 2)
|
||||||
|
call feedkeys($"Sfoozar\<CR>\<Esc>", 'tx')
|
||||||
|
call DoTest("baz\<C-O>0f", "foobaz", 2)
|
||||||
|
|
||||||
" Verify that redo (dot) works
|
" Verify that redo (dot) works
|
||||||
%delete
|
%delete
|
||||||
call setline(1, ["foobar", "foozbar", "foobaz", "changed", "change"])
|
call setline(1, ["foobar", "foozbar", "foobaz", "changed", "change"])
|
||||||
@ -5711,7 +5894,7 @@ func Test_autocomplete_completeopt_preinsert()
|
|||||||
call assert_equal('', v:errmsg)
|
call assert_equal('', v:errmsg)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Check that switching buffer with "preinsert" doesn't corrupt undo.
|
" Check that switching buffer with "longest" doesn't corrupt undo.
|
||||||
new
|
new
|
||||||
setlocal bufhidden=wipe
|
setlocal bufhidden=wipe
|
||||||
inoremap <buffer> <F2> <Cmd>enew!<CR>
|
inoremap <buffer> <F2> <Cmd>enew!<CR>
|
||||||
@ -5719,7 +5902,7 @@ func Test_autocomplete_completeopt_preinsert()
|
|||||||
bwipe!
|
bwipe!
|
||||||
call CheckUndo()
|
call CheckUndo()
|
||||||
|
|
||||||
" Check that closing window with "preinsert" doesn't corrupt undo.
|
" Check that closing window with "longest" doesn't corrupt undo.
|
||||||
new
|
new
|
||||||
setlocal bufhidden=wipe
|
setlocal bufhidden=wipe
|
||||||
inoremap <buffer> <F2> <Cmd>close!<CR>
|
inoremap <buffer> <F2> <Cmd>close!<CR>
|
||||||
|
|||||||
@ -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 */
|
||||||
|
/**/
|
||||||
|
1797,
|
||||||
/**/
|
/**/
|
||||||
1796,
|
1796,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user