3737# define CTRL_X_SPELL 14
3838# define CTRL_X_LOCAL_MSG 15 // only used in "ctrl_x_msgs"
3939# define CTRL_X_EVAL 16 // for builtin function complete()
40+ # define CTRL_X_CMDLINE_CTRL_X 17 // CTRL-X typed in CTRL_X_CMDLINE
4041
4142# define CTRL_X_MSG (i ) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
4243
@@ -60,6 +61,7 @@ static char *ctrl_x_msgs[] =
6061 N_ (" Spelling suggestion (s^N^P)" ),
6162 N_ (" Keyword Local completion (^N^P)" ),
6263 NULL , // CTRL_X_EVAL doesn't use msg.
64+ N_ (" Command-line completion (^V^N^P)" ),
6365};
6466
6567#if defined(FEAT_COMPL_FUNC ) || defined(FEAT_EVAL )
@@ -80,7 +82,8 @@ static char *ctrl_x_mode_names[] = {
8082 "omni" ,
8183 "spell" ,
8284 NULL , // CTRL_X_LOCAL_MSG only used in "ctrl_x_msgs"
83- "eval"
85+ "eval" ,
86+ "cmdline" ,
8487};
8588#endif
8689
@@ -222,9 +225,7 @@ static int spell_bad_len = 0; // length of located bad word
222225 void
223226ins_ctrl_x (void )
224227{
225- // CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X
226- // CTRL-V works like CTRL-N
227- if (ctrl_x_mode != CTRL_X_CMDLINE )
228+ if (!ctrl_x_mode_cmdline ())
228229 {
229230 // if the next ^X<> won't ADD nothing, then reset
230231 // compl_cont_status
@@ -238,6 +239,10 @@ ins_ctrl_x(void)
238239 edit_submode_pre = NULL ;
239240 showmode ();
240241 }
242+ else
243+ // CTRL-X in CTRL-X CTRL-V mode behaves differently to make CTRL-X
244+ // CTRL-V look like CTRL-N
245+ ctrl_x_mode = CTRL_X_CMDLINE_CTRL_X ;
241246}
242247
243248/*
@@ -255,7 +260,9 @@ int ctrl_x_mode_path_defines(void) {
255260 return ctrl_x_mode == CTRL_X_PATH_DEFINES ; }
256261int ctrl_x_mode_dictionary (void ) { return ctrl_x_mode == CTRL_X_DICTIONARY ; }
257262int ctrl_x_mode_thesaurus (void ) { return ctrl_x_mode == CTRL_X_THESAURUS ; }
258- int ctrl_x_mode_cmdline (void ) { return ctrl_x_mode == CTRL_X_CMDLINE ; }
263+ int ctrl_x_mode_cmdline (void ) {
264+ return ctrl_x_mode == CTRL_X_CMDLINE
265+ || ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X ; }
259266int ctrl_x_mode_function (void ) { return ctrl_x_mode == CTRL_X_FUNCTION ; }
260267int ctrl_x_mode_omni (void ) { return ctrl_x_mode == CTRL_X_OMNI ; }
261268int ctrl_x_mode_spell (void ) { return ctrl_x_mode == CTRL_X_SPELL ; }
@@ -272,7 +279,8 @@ ctrl_x_mode_not_default(void)
272279}
273280
274281/*
275- * Whether CTRL-X was typed without a following character.
282+ * Whether CTRL-X was typed without a following character,
283+ * not including when in CTRL-X CTRL-V mode.
276284 */
277285 int
278286ctrl_x_mode_not_defined_yet (void )
@@ -333,12 +341,14 @@ vim_is_ctrl_x_key(int c)
333341 case 0 : // Not in any CTRL-X mode
334342 return (c == Ctrl_N || c == Ctrl_P || c == Ctrl_X );
335343 case CTRL_X_NOT_DEFINED_YET :
344+ case CTRL_X_CMDLINE_CTRL_X :
336345 return ( c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
337346 || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB
338347 || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P
339348 || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V
340349 || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O
341- || c == Ctrl_S || c == Ctrl_K || c == 's' );
350+ || c == Ctrl_S || c == Ctrl_K || c == 's'
351+ || c == Ctrl_Z );
342352 case CTRL_X_SCROLL :
343353 return (c == Ctrl_Y || c == Ctrl_E );
344354 case CTRL_X_WHOLE_LINE :
@@ -396,6 +406,7 @@ ins_compl_accept_char(int c)
396406 return vim_isfilec (c ) && !vim_ispathsep (c );
397407
398408 case CTRL_X_CMDLINE :
409+ case CTRL_X_CMDLINE_CTRL_X :
399410 case CTRL_X_OMNI :
400411 // Command line and Omni completion can work with just about any
401412 // printable character, but do stop at white space.
@@ -1860,6 +1871,29 @@ ins_compl_prep(int c)
18601871 }
18611872#endif
18621873
1874+ if (ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X && c != Ctrl_X )
1875+ {
1876+ if (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_Z || ins_compl_pum_key (c )
1877+ || !vim_is_ctrl_x_key (c ))
1878+ {
1879+ // Not starting another completion mode.
1880+ ctrl_x_mode = CTRL_X_CMDLINE ;
1881+
1882+ // CTRL-X CTRL-Z should stop completion without inserting anything
1883+ if (c == Ctrl_Z )
1884+ retval = TRUE;
1885+ }
1886+ else
1887+ {
1888+ ctrl_x_mode = CTRL_X_CMDLINE ;
1889+
1890+ // Other CTRL-X keys first stop completion, then start another
1891+ // completion mode.
1892+ ins_compl_prep (' ' );
1893+ ctrl_x_mode = CTRL_X_NOT_DEFINED_YET ;
1894+ }
1895+ }
1896+
18631897 // Set "compl_get_longest" when finding the first matches.
18641898 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
18651899 || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started ))
@@ -1933,6 +1967,12 @@ ins_compl_prep(int c)
19331967 case Ctrl_Q :
19341968 ctrl_x_mode = CTRL_X_CMDLINE ;
19351969 break ;
1970+ case Ctrl_Z :
1971+ ctrl_x_mode = CTRL_X_NORMAL ;
1972+ edit_submode = NULL ;
1973+ showmode ();
1974+ retval = TRUE;
1975+ break ;
19361976 case Ctrl_P :
19371977 case Ctrl_N :
19381978 // ^X^P means LOCAL expansion if nothing interrupted (eg we
@@ -2929,6 +2969,7 @@ ins_compl_get_exp(pos_T *ini)
29292969 break ;
29302970
29312971 case CTRL_X_CMDLINE :
2972+ case CTRL_X_CMDLINE_CTRL_X :
29322973 if (expand_cmdline (& compl_xp , compl_pattern ,
29332974 (int )STRLEN (compl_pattern ),
29342975 & num_matches , & matches ) == EXPAND_OK )
0 commit comments