mirror of
https://github.com/vim/vim.git
synced 2025-10-18 07:54:29 -04:00
patch 9.1.1742: complete: preinsert does not work well with preinsert
Problem: complete: preinsert does not work well with preinsert Solution: Make "preinsert" completeopt value work with autocompletion (Girish Palya) This change extends Insert mode autocompletion so that 'preinsert' also works when 'autocomplete' is enabled. Try: `:set ac cot=preinsert` See `:help 'cot'` for more details. closes: #18213 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
4ed19fd336
commit
fa6fd41a94
@@ -1,4 +1,4 @@
|
|||||||
*insert.txt* For Vim version 9.1. Last change: 2025 Aug 25
|
*insert.txt* For Vim version 9.1. Last change: 2025 Sep 08
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -1150,7 +1150,26 @@ any of them at any time by typing |CTRL-X|, which temporarily suspends
|
|||||||
autocompletion. To use |i_CTRL-N| or |i_CTRL-X_CTRL-N| specifically, press
|
autocompletion. To use |i_CTRL-N| or |i_CTRL-X_CTRL-N| specifically, press
|
||||||
|CTRL-E| first to dismiss the popup menu (see |complete_CTRL-E|).
|
|CTRL-E| first to dismiss the popup menu (see |complete_CTRL-E|).
|
||||||
|
|
||||||
See also 'autocomplete', 'autocompletetimeout' and 'autocompletedelay'.
|
*ins-autocompletion-example*
|
||||||
|
Example setup~
|
||||||
|
A typical configuration for automatic completion with a popup menu: >
|
||||||
|
set autocomplete
|
||||||
|
set complete=.^5,w^5,b^5,u^5
|
||||||
|
set completeopt=popup
|
||||||
|
|
||||||
|
inoremap <silent><expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
|
||||||
|
inoremap <silent><expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
|
||||||
|
<
|
||||||
|
This enables automatic completion with suggestions from the current buffer,
|
||||||
|
other windows, and listed buffers, displayed in a popup menu. Each source is
|
||||||
|
limited to 5 candidates. <Tab> and <S-Tab> move through the items when the
|
||||||
|
menu is visible. Optionally, add "preinsert" to 'completeopt' to insert the
|
||||||
|
longest common prefix automatically. You can also add other completion
|
||||||
|
sources to 'complete' as needed.
|
||||||
|
|
||||||
|
See also 'autocomplete', 'autocompletedelay' and 'autocompletetimeout'.
|
||||||
|
|
||||||
|
For command-line autocompletion, see |cmdline-autocompletion|.
|
||||||
|
|
||||||
|
|
||||||
FUNCTIONS FOR FINDING COMPLETIONS *complete-functions*
|
FUNCTIONS FOR FINDING COMPLETIONS *complete-functions*
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
*options.txt* For Vim version 9.1. Last change: 2025 Sep 02
|
*options.txt* For Vim version 9.1. Last change: 2025 Sep 08
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -2124,10 +2124,11 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
*'complete'* *'cpt'* *E535*
|
*'complete'* *'cpt'* *E535*
|
||||||
'complete' 'cpt' string (default: ".,w,b,u,t,i")
|
'complete' 'cpt' string (default: ".,w,b,u,t,i")
|
||||||
local to buffer
|
local to buffer
|
||||||
This option specifies how keyword completion |ins-completion| works
|
This option controls how completion |ins-completion| behaves when
|
||||||
when CTRL-P or CTRL-N are used. It is also used for whole-line
|
using CTRL-P, CTRL-N, or |ins-autocompletion|. It is also used for
|
||||||
completion |i_CTRL-X_CTRL-L|. It indicates the type of completion
|
whole-line completion |i_CTRL-X_CTRL-L|. It indicates the type of
|
||||||
and the places to scan. It is a comma-separated list of flags:
|
completion and the places to scan. It is a comma-separated list of
|
||||||
|
flags:
|
||||||
. scan the current buffer ('wrapscan' is ignored)
|
. scan the current buffer ('wrapscan' is ignored)
|
||||||
w scan buffers from other windows
|
w scan buffers from other windows
|
||||||
b scan other loaded buffers that are in the buffer list
|
b scan other loaded buffers that are in the buffer list
|
||||||
@@ -2179,9 +2180,11 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
5. tags
|
5. tags
|
||||||
6. included files
|
6. included files
|
||||||
|
|
||||||
As you can see, CTRL-N and CTRL-P can be used to do any 'iskeyword'-
|
CTRL-N, CTRL-P, and |ins-autocompletion| can be used for any
|
||||||
based expansion (e.g., dictionary |i_CTRL-X_CTRL-K|, included patterns
|
'iskeyword'-based completion (dictionary |i_CTRL-X_CTRL-K|, included
|
||||||
|i_CTRL-X_CTRL-I|, tags |i_CTRL-X_CTRL-]| and normal expansions).
|
patterns |i_CTRL-X_CTRL-I|, tags |i_CTRL-X_CTRL-]|, and normal
|
||||||
|
expansions). With the "F" and "o" flags in 'complete', non-keywords
|
||||||
|
can also be completed.
|
||||||
|
|
||||||
An optional match limit can be specified for a completion source by
|
An optional match limit can be specified for a completion source by
|
||||||
appending a caret ("^") followed by a {count} to the source flag.
|
appending a caret ("^") followed by a {count} to the source flag.
|
||||||
@@ -2298,17 +2301,22 @@ 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
|
||||||
Preinsert the portion of the first candidate word that is
|
When autocompletion is not enabled, inserts the part of the
|
||||||
not part of the current completion leader and using the
|
first candidate word beyond the current completion leader,
|
||||||
|hl-ComplMatchIns| highlight group. In order for it to
|
highlighted with |hl-ComplMatchIns|. The cursor does not
|
||||||
work, "fuzzy" must not be set and "menuone" must be set.
|
move. Requires 'fuzzy' unset and 'menuone' in 'completeopt'.
|
||||||
|
|
||||||
|
When 'autocomplete' is enabled, inserts the longest common
|
||||||
|
prefix of matches (from all shown items or buffer-specific
|
||||||
|
matches), highlighted with |hl-PreInsert|. This occurs only
|
||||||
|
when no menu item 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" and "preview" have an effect when
|
Only "fuzzy", "popup", "popuphidden", "preinsert" and "preview" have
|
||||||
'autocomplete' is enabled.
|
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.
|
||||||
@@ -4654,7 +4662,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
#:TabLineSel,_:TabLineFill,!:CursorColumn,
|
#:TabLineSel,_:TabLineFill,!:CursorColumn,
|
||||||
.:CursorLine,o:ColorColumn,q:QuickFixLine,
|
.:CursorLine,o:ColorColumn,q:QuickFixLine,
|
||||||
z:StatusLineTerm,Z:StatusLineTermNC,
|
z:StatusLineTerm,Z:StatusLineTermNC,
|
||||||
g:MsgArea,h:ComplMatchIns")
|
g:MsgArea,h:ComplMatchIns,I:PreInsert")
|
||||||
global
|
global
|
||||||
This option can be used to set highlighting mode for various
|
This option can be used to set highlighting mode for various
|
||||||
occasions. It is a comma-separated list of character pairs. The
|
occasions. It is a comma-separated list of character pairs. The
|
||||||
@@ -4717,6 +4725,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
|hl-PmenuThumb| X popup menu scrollbar thumb
|
|hl-PmenuThumb| X popup menu scrollbar thumb
|
||||||
|hl-PmenuMatch| k popup menu matched text
|
|hl-PmenuMatch| k popup menu matched text
|
||||||
|hl-PmenuMatchSel| < popup menu matched text in selected line
|
|hl-PmenuMatchSel| < popup menu matched text in selected line
|
||||||
|
|hl-PreInsert| I text inserted when "preinsert" and 'autocomplete'
|
||||||
|
|
||||||
The display modes are:
|
The display modes are:
|
||||||
r reverse (termcap entry "mr" and "me")
|
r reverse (termcap entry "mr" and "me")
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
*syntax.txt* For Vim version 9.1. Last change: 2025 Aug 18
|
*syntax.txt* For Vim version 9.1. Last change: 2025 Sep 08
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -5998,6 +5998,8 @@ PmenuMatchSel Popup menu: Matched text in selected item. Applied in
|
|||||||
combination with |hl-PmenuSel|.
|
combination with |hl-PmenuSel|.
|
||||||
*hl-ComplMatchIns*
|
*hl-ComplMatchIns*
|
||||||
ComplMatchIns Matched text of the currently inserted completion.
|
ComplMatchIns Matched text of the currently inserted completion.
|
||||||
|
*hl-PreInsert*
|
||||||
|
PreInsert Text inserted during autocompletion when "preinsert".
|
||||||
*hl-PopupSelected*
|
*hl-PopupSelected*
|
||||||
PopupSelected Popup window created with |popup_menu()|. Linked to
|
PopupSelected Popup window created with |popup_menu()|. Linked to
|
||||||
|hl-PmenuSel| by default.
|
|hl-PmenuSel| by default.
|
||||||
|
@@ -8366,6 +8366,7 @@ hl-PmenuSel syntax.txt /*hl-PmenuSel*
|
|||||||
hl-PmenuThumb syntax.txt /*hl-PmenuThumb*
|
hl-PmenuThumb syntax.txt /*hl-PmenuThumb*
|
||||||
hl-PopupNotification syntax.txt /*hl-PopupNotification*
|
hl-PopupNotification syntax.txt /*hl-PopupNotification*
|
||||||
hl-PopupSelected syntax.txt /*hl-PopupSelected*
|
hl-PopupSelected syntax.txt /*hl-PopupSelected*
|
||||||
|
hl-PreInsert syntax.txt /*hl-PreInsert*
|
||||||
hl-Question syntax.txt /*hl-Question*
|
hl-Question syntax.txt /*hl-Question*
|
||||||
hl-QuickFixLine syntax.txt /*hl-QuickFixLine*
|
hl-QuickFixLine syntax.txt /*hl-QuickFixLine*
|
||||||
hl-Scrollbar syntax.txt /*hl-Scrollbar*
|
hl-Scrollbar syntax.txt /*hl-Scrollbar*
|
||||||
@@ -8627,6 +8628,7 @@ inputrestore() builtin.txt /*inputrestore()*
|
|||||||
inputsave() builtin.txt /*inputsave()*
|
inputsave() builtin.txt /*inputsave()*
|
||||||
inputsecret() builtin.txt /*inputsecret()*
|
inputsecret() builtin.txt /*inputsecret()*
|
||||||
ins-autocompletion insert.txt /*ins-autocompletion*
|
ins-autocompletion insert.txt /*ins-autocompletion*
|
||||||
|
ins-autocompletion-example insert.txt /*ins-autocompletion-example*
|
||||||
ins-completion insert.txt /*ins-completion*
|
ins-completion insert.txt /*ins-completion*
|
||||||
ins-completion-menu insert.txt /*ins-completion-menu*
|
ins-completion-menu insert.txt /*ins-completion-menu*
|
||||||
ins-expandtab insert.txt /*ins-expandtab*
|
ins-expandtab insert.txt /*ins-expandtab*
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
" Language: Vim script
|
" Language: Vim script
|
||||||
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
|
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
|
||||||
" Doug Kearns <dougkearns@gmail.com>
|
" Doug Kearns <dougkearns@gmail.com>
|
||||||
" Last Change: 2025 Aug 29
|
" Last Change: 2025 Sep 08
|
||||||
" Former Maintainer: Charles E. Campbell
|
" Former Maintainer: Charles E. Campbell
|
||||||
|
|
||||||
" DO NOT CHANGE DIRECTLY.
|
" DO NOT CHANGE DIRECTLY.
|
||||||
@@ -145,8 +145,8 @@ syn keyword vimGroup contained Added Bold BoldItalic Boolean Changed Character C
|
|||||||
|
|
||||||
" Default highlighting groups {{{2
|
" Default highlighting groups {{{2
|
||||||
" GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained', END_STR=''
|
" GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained', END_STR=''
|
||||||
syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit VisualNOS DiffText DiffTextAdd PmenuSbar TabLineSel TabLineFill TabPanel TabPanelSel TabPanelFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuMatch PmenuMatchSel PmenuExtra PmenuExtraSel PopupSelected MessageWindow PopupNotification Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen StatusLineTerm StatusLineTermNC ToolbarLine ToolbarButton Menu Tooltip Scrollbar CursorIM
|
syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit VisualNOS DiffText DiffTextAdd PmenuSbar TabLineSel TabLineFill TabPanel TabPanelSel TabPanelFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuMatch PmenuMatchSel PmenuExtra PmenuExtraSel PopupSelected MessageWindow PopupNotification PreInsert Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen StatusLineTerm StatusLineTermNC ToolbarLine ToolbarButton Menu Tooltip Scrollbar
|
||||||
syn keyword vimHLGroup contained ComplMatchIns LineNrAbove LineNrBelow MsgArea Terminal User1 User2 User3 User4 User5 User6 User7 User8 User9
|
syn keyword vimHLGroup contained CursorIM ComplMatchIns LineNrAbove LineNrBelow MsgArea Terminal User1 User2 User3 User4 User5 User6 User7 User8 User9
|
||||||
syn match vimHLGroup contained "\<Conceal\>"
|
syn match vimHLGroup contained "\<Conceal\>"
|
||||||
syn case match
|
syn case match
|
||||||
|
|
||||||
|
@@ -693,7 +693,11 @@ edit(
|
|||||||
&& stop_arrow() == OK)
|
&& stop_arrow() == OK)
|
||||||
{
|
{
|
||||||
ins_compl_delete();
|
ins_compl_delete();
|
||||||
ins_compl_insert(FALSE);
|
if (ins_compl_has_preinsert()
|
||||||
|
&& ins_compl_has_autocomplete())
|
||||||
|
(void)ins_compl_insert(FALSE, TRUE);
|
||||||
|
else
|
||||||
|
(void)ins_compl_insert(FALSE, FALSE);
|
||||||
}
|
}
|
||||||
// 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())
|
||||||
|
@@ -269,6 +269,7 @@ static char *(highlight_init_both[]) = {
|
|||||||
"default link PopupSelected PmenuSel",
|
"default link PopupSelected PmenuSel",
|
||||||
"default link MessageWindow WarningMsg",
|
"default link MessageWindow WarningMsg",
|
||||||
"default link PopupNotification WarningMsg",
|
"default link PopupNotification WarningMsg",
|
||||||
|
"default link PreInsert Added",
|
||||||
CENT("Normal cterm=NONE", "Normal gui=NONE"),
|
CENT("Normal cterm=NONE", "Normal gui=NONE"),
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
214
src/insexpand.c
214
src/insexpand.c
@@ -154,8 +154,9 @@ static string_T compl_leader = {NULL, 0};
|
|||||||
static int compl_get_longest = FALSE; // put longest common string
|
static int compl_get_longest = FALSE; // put longest common string
|
||||||
// in compl_leader
|
// in compl_leader
|
||||||
|
|
||||||
// Selected one of the matches. When FALSE the match was edited or using the
|
// This flag indicates that one of the items in the match list is currently
|
||||||
// longest common string.
|
// selected. FALSE when no match is selected or the match was edited or using
|
||||||
|
// the longest common string.
|
||||||
static int compl_used_match;
|
static int compl_used_match;
|
||||||
|
|
||||||
// didn't finish finding completions.
|
// didn't finish finding completions.
|
||||||
@@ -210,6 +211,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
|
||||||
|
|
||||||
// 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
|
||||||
@@ -252,6 +254,7 @@ typedef struct cpt_source_T
|
|||||||
#ifdef ELAPSED_FUNC
|
#ifdef ELAPSED_FUNC
|
||||||
elapsed_T compl_start_tv; // Timestamp when match collection starts
|
elapsed_T compl_start_tv; // Timestamp when match collection starts
|
||||||
#endif
|
#endif
|
||||||
|
char_u cs_flag; // flag indicating the type of source
|
||||||
} cpt_source_T;
|
} cpt_source_T;
|
||||||
|
|
||||||
static cpt_source_T *cpt_sources_array; // Pointer to the array of completion sources
|
static cpt_source_T *cpt_sources_array; // Pointer to the array of completion sources
|
||||||
@@ -1067,7 +1070,11 @@ ins_compl_col_range_attr(linenr_T lnum, int col)
|
|||||||
int attr;
|
int attr;
|
||||||
|
|
||||||
if ((get_cot_flags() & COT_FUZZY)
|
if ((get_cot_flags() & COT_FUZZY)
|
||||||
|| (attr = syn_name2attr((char_u *)"ComplMatchIns")) == 0)
|
|| (!compl_autocomplete
|
||||||
|
&& (attr = syn_name2attr((char_u *)"ComplMatchIns")) == 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();
|
||||||
@@ -1624,13 +1631,13 @@ ins_compl_build_pum(void)
|
|||||||
{
|
{
|
||||||
compl->cp_in_match_array = FALSE;
|
compl->cp_in_match_array = FALSE;
|
||||||
|
|
||||||
// Apply 'smartcase' behavior during normal mode
|
|
||||||
if (ctrl_x_mode_normal() && !p_inf && compl_leader.string
|
|
||||||
&& !ignorecase(compl_leader.string) && !fuzzy_filter)
|
|
||||||
compl->cp_flags &= ~CP_ICASE;
|
|
||||||
|
|
||||||
leader = get_leader_for_startcol(compl, TRUE);
|
leader = get_leader_for_startcol(compl, TRUE);
|
||||||
|
|
||||||
|
// Apply 'smartcase' behavior during normal mode
|
||||||
|
if (ctrl_x_mode_normal() && !p_inf && leader->string
|
||||||
|
&& !ignorecase(leader->string) && !fuzzy_filter)
|
||||||
|
compl->cp_flags &= ~CP_ICASE;
|
||||||
|
|
||||||
if (!match_at_original_text(compl)
|
if (!match_at_original_text(compl)
|
||||||
&& (leader->string == NULL
|
&& (leader->string == NULL
|
||||||
|| ins_compl_equal(compl, leader->string,
|
|| ins_compl_equal(compl, leader->string,
|
||||||
@@ -2339,12 +2346,14 @@ ins_compl_len(void)
|
|||||||
* Return TRUE when the 'completeopt' "preinsert" flag is in effect,
|
* Return TRUE when the 'completeopt' "preinsert" flag is in effect,
|
||||||
* otherwise return FALSE.
|
* otherwise return FALSE.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
ins_compl_has_preinsert(void)
|
ins_compl_has_preinsert(void)
|
||||||
{
|
{
|
||||||
int cur_cot_flags = get_cot_flags();
|
int cur_cot_flags = get_cot_flags();
|
||||||
return (cur_cot_flags & (COT_PREINSERT | COT_FUZZY | COT_MENUONE))
|
return !compl_autocomplete
|
||||||
== (COT_PREINSERT | COT_MENUONE) && !compl_autocomplete;
|
? (cur_cot_flags & (COT_PREINSERT | COT_FUZZY | COT_MENUONE))
|
||||||
|
== (COT_PREINSERT | COT_MENUONE)
|
||||||
|
: (cur_cot_flags & (COT_PREINSERT | COT_FUZZY)) == COT_PREINSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2360,6 +2369,15 @@ ins_compl_preinsert_effect(void)
|
|||||||
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_has_autocomplete(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.
|
||||||
@@ -2505,11 +2523,23 @@ 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);
|
{
|
||||||
|
if (compl_started && compl_autocomplete
|
||||||
|
&& !ins_compl_preinsert_effect())
|
||||||
|
{
|
||||||
|
if (ins_compl_insert(TRUE, TRUE) != OK)
|
||||||
|
(void)ins_compl_insert(FALSE, FALSE);
|
||||||
|
else
|
||||||
|
compl_autocomplete_preinsert = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(void)ins_compl_insert(TRUE, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2956,6 +2986,7 @@ ins_compl_stop(int c, int prev_mode, int retval)
|
|||||||
compl_autocomplete = FALSE;
|
compl_autocomplete = FALSE;
|
||||||
compl_from_nonkeyword = FALSE;
|
compl_from_nonkeyword = FALSE;
|
||||||
compl_best_matches = 0;
|
compl_best_matches = 0;
|
||||||
|
compl_ins_end_col = 0;
|
||||||
|
|
||||||
if (c == Ctrl_C && cmdwin_type != 0)
|
if (c == Ctrl_C && cmdwin_type != 0)
|
||||||
// Avoid the popup menu remains displayed when leaving the
|
// Avoid the popup menu remains displayed when leaving the
|
||||||
@@ -5057,9 +5088,10 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!in_fuzzy_collect)
|
if (!in_fuzzy_collect)
|
||||||
ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos,
|
ptr = ins_compl_get_next_word_or_line(st->ins_buf,
|
||||||
&len, &cont_s_ipos);
|
st->cur_match_pos, &len, &cont_s_ipos);
|
||||||
if (ptr == NULL || (ins_compl_has_preinsert() && STRCMP(ptr, compl_pattern.string) == 0))
|
if (ptr == NULL || (!compl_autocomplete && ins_compl_has_preinsert()
|
||||||
|
&& STRCMP(ptr, compl_pattern.string) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (is_nearest_active() && in_curbuf)
|
if (is_nearest_active() && in_curbuf)
|
||||||
@@ -5677,8 +5709,8 @@ ins_compl_delete(void)
|
|||||||
int col = compl_col + (compl_status_adding() ? compl_length : 0);
|
int col = compl_col + (compl_status_adding() ? compl_length : 0);
|
||||||
string_T remaining = {NULL, 0};
|
string_T remaining = {NULL, 0};
|
||||||
int orig_col;
|
int orig_col;
|
||||||
int has_preinsert = ins_compl_preinsert_effect();
|
|
||||||
if (has_preinsert)
|
if (ins_compl_preinsert_effect())
|
||||||
{
|
{
|
||||||
col += (int)ins_compl_leader_len();
|
col += (int)ins_compl_leader_len();
|
||||||
curwin->w_cursor.col = compl_ins_end_col;
|
curwin->w_cursor.col = compl_ins_end_col;
|
||||||
@@ -5770,13 +5802,111 @@ ins_compl_expand_multiple(char_u *str)
|
|||||||
compl_ins_end_col = curwin->w_cursor.col;
|
compl_ins_end_col = curwin->w_cursor.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the longest common prefix among the current completion matches.
|
||||||
|
* Returns a pointer to the first match string, with *prefix_len set to
|
||||||
|
* the length of the common prefix.
|
||||||
|
* If "curbuf_only" is TRUE, restrict matches to the current buffer
|
||||||
|
* ('.' source in 'complete').
|
||||||
|
*/
|
||||||
|
static char_u *
|
||||||
|
find_common_prefix(size_t *prefix_len, int curbuf_only)
|
||||||
|
{
|
||||||
|
compl_T *compl;
|
||||||
|
int *match_count;
|
||||||
|
char_u *first = NULL;
|
||||||
|
int len = -1;
|
||||||
|
int is_cpt_completion = (cpt_sources_array != NULL);
|
||||||
|
|
||||||
|
if (!is_cpt_completion)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
match_count = ALLOC_CLEAR_MULT(int, cpt_sources_count);
|
||||||
|
if (match_count == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
(void)get_leader_for_startcol(NULL, TRUE); // Clear the cache
|
||||||
|
|
||||||
|
compl = compl_first_match;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string_T *leader = get_leader_for_startcol(compl, TRUE);
|
||||||
|
|
||||||
|
// Apply 'smartcase' behavior during normal mode
|
||||||
|
if (ctrl_x_mode_normal() && !p_inf && leader->string
|
||||||
|
&& !ignorecase(leader->string))
|
||||||
|
compl->cp_flags &= ~CP_ICASE;
|
||||||
|
|
||||||
|
if (!match_at_original_text(compl)
|
||||||
|
&& (leader->string == NULL
|
||||||
|
|| ins_compl_equal(compl, leader->string,
|
||||||
|
(int)leader->length)))
|
||||||
|
{
|
||||||
|
// Limit number of items from each source if max_items is set.
|
||||||
|
int match_limit_exceeded = FALSE;
|
||||||
|
int cur_source = compl->cp_cpt_source_idx;
|
||||||
|
|
||||||
|
if (cur_source != -1)
|
||||||
|
{
|
||||||
|
match_count[cur_source]++;
|
||||||
|
int max_matches = cpt_sources_array[cur_source].cs_max_matches;
|
||||||
|
if (max_matches > 0 && match_count[cur_source] > max_matches)
|
||||||
|
match_limit_exceeded = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match_limit_exceeded && (!curbuf_only
|
||||||
|
|| cpt_sources_array[cur_source].cs_flag == '.'))
|
||||||
|
{
|
||||||
|
if (first == NULL)
|
||||||
|
{
|
||||||
|
first = compl->cp_str.string;
|
||||||
|
len = (int)STRLEN(first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int j = 0; // count in bytes
|
||||||
|
char_u *s1 = first;
|
||||||
|
char_u *s2 = compl->cp_str.string;
|
||||||
|
|
||||||
|
while (j < len && *s1 != NUL && *s2 != NUL)
|
||||||
|
{
|
||||||
|
if (MB_BYTE2LEN(*s1) != MB_BYTE2LEN(*s2)
|
||||||
|
|| memcmp(s1, s2, MB_BYTE2LEN(*s1)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
j += MB_BYTE2LEN(*s1);
|
||||||
|
MB_PTR_ADV(s1);
|
||||||
|
MB_PTR_ADV(s2);
|
||||||
|
}
|
||||||
|
len = j;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compl = compl->cp_next;
|
||||||
|
} while (compl != NULL && !is_first_match(compl));
|
||||||
|
|
||||||
|
vim_free(match_count);
|
||||||
|
|
||||||
|
if (len > get_compl_len())
|
||||||
|
{
|
||||||
|
*prefix_len = (size_t)len;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
* instead of shown match.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
ins_compl_insert(int move_cursor)
|
ins_compl_insert(int move_cursor, int preinsert_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();
|
||||||
@@ -5785,10 +5915,20 @@ ins_compl_insert(int move_cursor)
|
|||||||
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)
|
||||||
|
{
|
||||||
|
cp_str = find_common_prefix(&cp_str_len, FALSE);
|
||||||
|
if (cp_str == NULL)
|
||||||
|
{
|
||||||
|
cp_str = find_common_prefix(&cp_str_len, TRUE);
|
||||||
|
if (cp_str == NULL)
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Since completion sources may provide matches with varying start
|
// Since completion sources may provide matches with varying start
|
||||||
// positions, insert only the portion of the match that corresponds to the
|
// positions, insert only the portion of the match that corresponds to the
|
||||||
// intended replacement range.
|
// intended replacement range.
|
||||||
if (cpt_sources_array != NULL)
|
else if (cpt_sources_array != NULL)
|
||||||
{
|
{
|
||||||
int cpt_idx = compl_shown_match->cp_cpt_source_idx;
|
int cpt_idx = compl_shown_match->cp_cpt_source_idx;
|
||||||
if (cpt_idx >= 0 && compl_col >= 0)
|
if (cpt_idx >= 0 && compl_col >= 0)
|
||||||
@@ -5814,7 +5954,8 @@ ins_compl_insert(int move_cursor)
|
|||||||
ins_compl_expand_multiple(cp_str + compl_len);
|
ins_compl_expand_multiple(cp_str + compl_len);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ins_compl_insert_bytes(cp_str + compl_len, -1);
|
ins_compl_insert_bytes(cp_str + compl_len,
|
||||||
|
preinsert_prefix ? (int)cp_str_len - compl_len : -1);
|
||||||
if (preinsert && move_cursor)
|
if (preinsert && move_cursor)
|
||||||
curwin->w_cursor.col -= (colnr_T)(cp_str_len - leader_len);
|
curwin->w_cursor.col -= (colnr_T)(cp_str_len - leader_len);
|
||||||
}
|
}
|
||||||
@@ -5830,6 +5971,7 @@ ins_compl_insert(int move_cursor)
|
|||||||
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
|
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6084,16 +6226,39 @@ 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 && !compl_preinsert)
|
if (compl_no_insert && !started)
|
||||||
{
|
{
|
||||||
ins_compl_insert_bytes(compl_orig_text.string + get_compl_len(), -1);
|
int insert_orig = !compl_preinsert;
|
||||||
|
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)
|
||||||
ins_compl_insert(TRUE);
|
{
|
||||||
|
int none_selected = match_at_original_text(compl_shown_match);
|
||||||
|
if (compl_preinsert && compl_autocomplete
|
||||||
|
&& none_selected)
|
||||||
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -7360,6 +7525,7 @@ setup_cpt_sources(void)
|
|||||||
p++;
|
p++;
|
||||||
if (*p) // If not end of string, count this segment
|
if (*p) // If not end of string, count this segment
|
||||||
{
|
{
|
||||||
|
cpt_sources_array[idx].cs_flag = *p;
|
||||||
slen = copy_option_part(&p, buf, LSIZE, ","); // Advance p
|
slen = copy_option_part(&p, buf, LSIZE, ","); // Advance p
|
||||||
if (slen > 0)
|
if (slen > 0)
|
||||||
{
|
{
|
||||||
|
@@ -309,7 +309,7 @@ struct vimoption
|
|||||||
# define ISP_LATIN1 (char_u *)"@,161-255"
|
# define ISP_LATIN1 (char_u *)"@,161-255"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,E:DiffTextAdd,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea,h:ComplMatchIns,%:TabPanel,^:TabPanelSel,&:TabPanelFill"
|
# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,E:DiffTextAdd,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea,h:ComplMatchIns,%:TabPanel,^:TabPanelSel,&:TabPanelFill,I:PreInsert"
|
||||||
|
|
||||||
// Default python version for pyx* commands
|
// Default python version for pyx* commands
|
||||||
#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
@@ -69,9 +69,11 @@ 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);
|
||||||
void ins_compl_insert(int move_cursor);
|
int ins_compl_insert(int move_cursor, int insert_longest_prefix);
|
||||||
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_preinsert(void);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -489,6 +489,7 @@ func Test_highlight_completion()
|
|||||||
call assert_equal("\"hi link Aardig NONE", getreg(':'))
|
call assert_equal("\"hi link Aardig NONE", getreg(':'))
|
||||||
|
|
||||||
" A cleared group does not show up in completions.
|
" A cleared group does not show up in completions.
|
||||||
|
hi clear Added
|
||||||
hi Anders ctermfg=green
|
hi Anders ctermfg=green
|
||||||
call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
|
call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
|
||||||
hi clear Aardig
|
hi clear Aardig
|
||||||
|
@@ -5359,7 +5359,7 @@ func Test_autocomplete_timer()
|
|||||||
call assert_equal(-1, b:selected)
|
call assert_equal(-1, b:selected)
|
||||||
|
|
||||||
" Test 7: Following 'cot' option values have no effect
|
" Test 7: Following 'cot' option values have no effect
|
||||||
set completeopt=menu,menuone,noselect,noinsert,longest,preinsert
|
set completeopt=menu,menuone,noselect,noinsert,longest
|
||||||
set complete=.,Ffunction('TestComplete'\\,\ [0\\,\ 0\\,\ 0])
|
set complete=.,Ffunction('TestComplete'\\,\ [0\\,\ 0\\,\ 0])
|
||||||
let g:CallCount = 0
|
let g:CallCount = 0
|
||||||
call feedkeys("Sab\<c-n>\<F2>\<F3>\<Esc>0", 'tx!')
|
call feedkeys("Sab\<c-n>\<F2>\<F3>\<Esc>0", 'tx!')
|
||||||
@@ -5578,4 +5578,109 @@ func Test_autocompletedelay()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_autocomplete_completeopt_preinsert()
|
||||||
|
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>
|
||||||
|
set completeopt=preinsert autocomplete
|
||||||
|
call setline(1, ["foobar", "foozbar"])
|
||||||
|
call feedkeys("Go\<ESC>", 'tx')
|
||||||
|
|
||||||
|
func DoTest(typed, line, col)
|
||||||
|
call feedkeys($"S{a:typed}\<F5>\<ESC>", 'tx')
|
||||||
|
call assert_equal(a:line, g:line)
|
||||||
|
call assert_equal(a:col, g:col)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
call DoTest("f", 'foo', 2)
|
||||||
|
call DoTest("fo", 'foo', 3)
|
||||||
|
call DoTest("foo", 'foo', 4)
|
||||||
|
call DoTest("foob", 'foobar', 5)
|
||||||
|
call DoTest("foob\<BS>", 'foo', 4)
|
||||||
|
call DoTest("foob\<BS>\<BS>", 'foo', 3)
|
||||||
|
call DoTest("foo\<BS>", 'foo', 3)
|
||||||
|
call DoTest("foo\<BS>\<BS>", 'foo', 2)
|
||||||
|
call DoTest("foo\<BS>\<BS>\<BS>", '', 1)
|
||||||
|
|
||||||
|
call DoTest("foo \<BS>", 'foo', 4)
|
||||||
|
call DoTest("foo \<BS>\<BS>", 'foo', 3)
|
||||||
|
|
||||||
|
call DoTest("f\<C-N>", 'foozbar', 8)
|
||||||
|
call DoTest("f\<C-N>\<C-N>", 'foobar', 7)
|
||||||
|
call DoTest("f\<C-N>\<C-N>\<C-N>", 'foo', 2)
|
||||||
|
call DoTest("f\<C-N>\<C-N>\<C-N>\<C-N>", 'foozbar', 8)
|
||||||
|
call DoTest("f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'foo', 2)
|
||||||
|
call DoTest("f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>\<C-P>", 'foobar', 7)
|
||||||
|
call DoTest("f\<C-P>", 'foobar', 7)
|
||||||
|
call DoTest("fo\<BS>\<C-P>", 'foobar', 7)
|
||||||
|
|
||||||
|
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>\<BS>", 'foozar', 3)
|
||||||
|
|
||||||
|
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>\<C-N>", 'foozar', 2)
|
||||||
|
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>\<C-N>", 'foozbarzar', 8)
|
||||||
|
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'foozar', 2)
|
||||||
|
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>\<C-P>", 'foobarzar', 7)
|
||||||
|
call DoTest("zar\<C-O>0f\<C-P>", 'foobarzar', 7)
|
||||||
|
|
||||||
|
" Should not work with fuzzy
|
||||||
|
set cot+=fuzzy
|
||||||
|
call DoTest("f", 'f', 2)
|
||||||
|
|
||||||
|
%delete _
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
normal! ifoo
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
normal! ofoobar
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
normal! ofoobaz
|
||||||
|
let &l:undolevels = &l:undolevels
|
||||||
|
|
||||||
|
func CheckUndo()
|
||||||
|
let g:errmsg = ''
|
||||||
|
call assert_equal(['foo', 'foobar', 'foobaz'], getline(1, '$'))
|
||||||
|
undo
|
||||||
|
call assert_equal(['foo', 'foobar'], getline(1, '$'))
|
||||||
|
undo
|
||||||
|
call assert_equal(['foo'], getline(1, '$'))
|
||||||
|
undo
|
||||||
|
call assert_equal([''], getline(1, '$'))
|
||||||
|
later 3
|
||||||
|
call assert_equal(['foo', 'foobar', 'foobaz'], 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& autocomplete&
|
||||||
|
delfunc GetLine
|
||||||
|
delfunc DoTest
|
||||||
|
call test_override("char_avail", 0)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
|
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
|
||||||
|
@@ -724,6 +724,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 */
|
||||||
|
/**/
|
||||||
|
1742,
|
||||||
/**/
|
/**/
|
||||||
1741,
|
1741,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -1587,6 +1587,7 @@ typedef enum
|
|||||||
, HLF_TPL // tabpanel
|
, HLF_TPL // tabpanel
|
||||||
, HLF_TPLS // tabpanel selected
|
, HLF_TPLS // tabpanel selected
|
||||||
, HLF_TPLF // tabpanel filler
|
, HLF_TPLF // tabpanel filler
|
||||||
|
, HLF_PRI // "preinsert" in 'completeopt'
|
||||||
, HLF_COUNT // MUST be the last one
|
, HLF_COUNT // MUST be the last one
|
||||||
} hlf_T;
|
} hlf_T;
|
||||||
|
|
||||||
@@ -1599,7 +1600,7 @@ typedef enum
|
|||||||
'+', '=', 'k', '<','[', ']', '{', '}', 'x', 'X', \
|
'+', '=', 'k', '<','[', ']', '{', '}', 'x', 'X', \
|
||||||
'*', '#', '_', '!', '.', 'o', 'q', \
|
'*', '#', '_', '!', '.', 'o', 'q', \
|
||||||
'z', 'Z', 'g', \
|
'z', 'Z', 'g', \
|
||||||
'%', '^', '&' }
|
'%', '^', '&', 'I'}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Values for behaviour in spell_move_to
|
* Values for behaviour in spell_move_to
|
||||||
|
Reference in New Issue
Block a user