1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
11 * ex_getln.c: Functions for entering and editing an Ex command line.
17 * Variables shared between getcmdline(), redrawcmdline() and others.
18 * These need to be saved when using CTRL-R |, that's why they are in a
23 char_u
*cmdbuff
; /* pointer to command line buffer */
24 int cmdbufflen
; /* length of cmdbuff */
25 int cmdlen
; /* number of chars in command line */
26 int cmdpos
; /* current cursor position */
27 int cmdspos
; /* cursor column on screen */
28 int cmdfirstc
; /* ':', '/', '?', '=' or NUL */
29 int cmdindent
; /* number of spaces before cmdline */
30 char_u
*cmdprompt
; /* message in front of cmdline */
31 int cmdattr
; /* attributes for prompt */
32 int overstrike
; /* Typing mode on the command line. Shared by
33 getcmdline() and put_on_cmdline(). */
34 expand_T
*xpc
; /* struct being used for expansion, xp_pattern
35 may point into cmdbuff */
36 int xp_context
; /* type of expansion */
38 char_u
*xp_arg
; /* user-defined expansion arg */
39 int input_fn
; /* when TRUE Invoked for input() function */
43 /* The current cmdline_info. It is initialized in getcmdline() and after that
44 * used by other functions. When invoking getcmdline() recursively it needs
45 * to be saved with save_cmdline() and restored with restore_cmdline().
46 * TODO: make it local to getcmdline() and pass it around. */
47 static struct cmdline_info ccline
;
49 static int cmd_showtail
; /* Only show path tail in lists ? */
52 static int new_cmdpos
; /* position set by set_cmdline_pos() */
56 typedef struct hist_entry
58 int hisnum
; /* identifying number */
59 char_u
*hisstr
; /* actual entry, separator char after the NUL */
62 static histentry_T
*(history
[HIST_COUNT
]) = {NULL
, NULL
, NULL
, NULL
, NULL
};
63 static int hisidx
[HIST_COUNT
] = {-1, -1, -1, -1, -1}; /* lastused entry */
64 static int hisnum
[HIST_COUNT
] = {0, 0, 0, 0, 0};
65 /* identifying (unique) number of newest history entry */
66 static int hislen
= 0; /* actual length of history tables */
68 static int hist_char2type
__ARGS((int c
));
70 static int in_history
__ARGS((int, char_u
*, int));
72 static int calc_hist_idx
__ARGS((int histype
, int num
));
77 static int cmd_hkmap
= 0; /* Hebrew mapping during command line */
81 static int cmd_fkmap
= 0; /* Farsi mapping during command line */
84 static int cmdline_charsize
__ARGS((int idx
));
85 static void set_cmdspos
__ARGS((void));
86 static void set_cmdspos_cursor
__ARGS((void));
88 static void correct_cmdspos
__ARGS((int idx
, int cells
));
90 static void alloc_cmdbuff
__ARGS((int len
));
91 static int realloc_cmdbuff
__ARGS((int len
));
92 static void draw_cmdline
__ARGS((int start
, int len
));
93 static void save_cmdline
__ARGS((struct cmdline_info
*ccp
));
94 static void restore_cmdline
__ARGS((struct cmdline_info
*ccp
));
95 static int cmdline_paste
__ARGS((int regname
, int literally
, int remcr
));
96 #if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
97 static void redrawcmd_preedit
__ARGS((void));
100 static void cmdline_del
__ARGS((int from
));
102 static void redrawcmdprompt
__ARGS((void));
103 static void cursorcmd
__ARGS((void));
104 static int ccheck_abbr
__ARGS((int));
105 static int nextwild
__ARGS((expand_T
*xp
, int type
, int options
));
106 static void escape_fname
__ARGS((char_u
**pp
));
107 static int showmatches
__ARGS((expand_T
*xp
, int wildmenu
));
108 static void set_expand_context
__ARGS((expand_T
*xp
));
109 static int ExpandFromContext
__ARGS((expand_T
*xp
, char_u
*, int *, char_u
***, int));
110 static int expand_showtail
__ARGS((expand_T
*xp
));
111 #ifdef FEAT_CMDL_COMPL
112 static int expand_shellcmd
__ARGS((char_u
*filepat
, int *num_file
, char_u
***file
, int flagsarg
));
113 static int ExpandRTDir
__ARGS((char_u
*pat
, int *num_file
, char_u
***file
, char *dirname
));
114 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
115 static int ExpandUserDefined
__ARGS((expand_T
*xp
, regmatch_T
*regmatch
, int *num_file
, char_u
***file
));
116 static int ExpandUserList
__ARGS((expand_T
*xp
, int *num_file
, char_u
***file
));
121 static int ex_window
__ARGS((void));
125 * getcmdline() - accept a command line starting with firstc.
127 * firstc == ':' get ":" command line.
128 * firstc == '/' or '?' get search pattern
129 * firstc == '=' get expression
130 * firstc == '@' get text for input() function
131 * firstc == '>' get text for debug mode
132 * firstc == NUL get text for :insert command
133 * firstc == -1 like NUL, and break on CTRL-C
135 * The line is collected in ccline.cmdbuff, which is reallocated to fit the
138 * Careful: getcmdline() can be called recursively!
140 * Return pointer to allocated string if there is a commandline, NULL
144 getcmdline(firstc
, count
, indent
)
146 long count UNUSED
; /* only used for incremental search */
147 int indent
; /* indent for inside conditionals */
152 int gotesc
= FALSE
; /* TRUE when <ESC> just typed */
153 int do_abbr
; /* when TRUE check for abbr. */
155 char_u
*lookfor
= NULL
; /* string to match */
156 int hiscnt
; /* current history line in use */
157 int histype
; /* history type to be used */
159 #ifdef FEAT_SEARCH_EXTRA
161 colnr_T old_curswant
;
163 linenr_T old_topline
;
167 linenr_T old_botline
;
168 int did_incsearch
= FALSE
;
169 int incsearch_postponed
= FALSE
;
171 int did_wild_list
= FALSE
; /* did wild_list() recently */
172 int wim_index
= 0; /* index in wim_flags[] */
174 int save_msg_scroll
= msg_scroll
;
175 int save_State
= State
; /* remember State when called */
176 int some_key_typed
= FALSE
; /* one of the keys was typed */
178 /* mouse drag and release events are ignored, unless they are
179 * preceded with a mouse down event */
180 int ignore_drag_release
= TRUE
;
183 int break_ctrl_c
= FALSE
;
186 long *b_im_ptr
= NULL
;
187 #if defined(FEAT_WILDMENU) || defined(FEAT_EVAL) || defined(FEAT_SEARCH_EXTRA)
188 /* Everything that may work recursively should save and restore the
189 * current command line in save_ccline. That includes update_screen(), a
190 * custom status line may invoke ":normal". */
191 struct cmdline_info save_ccline
;
195 want_sniff_request
= 0;
204 #ifdef FEAT_RIGHTLEFT
205 /* start without Hebrew mapping for a command line */
206 if (firstc
== ':' || firstc
== '=' || firstc
== '>')
210 ccline
.overstrike
= FALSE
; /* always start in insert mode */
211 #ifdef FEAT_SEARCH_EXTRA
212 old_cursor
= curwin
->w_cursor
; /* needs to be restored later */
213 old_curswant
= curwin
->w_curswant
;
214 old_leftcol
= curwin
->w_leftcol
;
215 old_topline
= curwin
->w_topline
;
217 old_topfill
= curwin
->w_topfill
;
219 old_botline
= curwin
->w_botline
;
223 * set some variables for redrawcmd()
225 ccline
.cmdfirstc
= (firstc
== '@' ? 0 : firstc
);
226 ccline
.cmdindent
= (firstc
> 0 ? indent
: 0);
228 /* alloc initial ccline.cmdbuff */
229 alloc_cmdbuff(exmode_active
? 250 : indent
+ 1);
230 if (ccline
.cmdbuff
== NULL
)
231 return NULL
; /* out of memory */
232 ccline
.cmdlen
= ccline
.cmdpos
= 0;
233 ccline
.cmdbuff
[0] = NUL
;
235 /* autoindent for :insert and :append */
238 copy_spaces(ccline
.cmdbuff
, indent
);
239 ccline
.cmdbuff
[indent
] = NUL
;
240 ccline
.cmdpos
= indent
;
241 ccline
.cmdspos
= indent
;
242 ccline
.cmdlen
= indent
;
248 #ifdef FEAT_RIGHTLEFT
249 if (curwin
->w_p_rl
&& *curwin
->w_p_rlc
== 's'
250 && (firstc
== '/' || firstc
== '?'))
256 redir_off
= TRUE
; /* don't redirect the typed command */
260 msg_scrolled
= 0; /* avoid wait_return message */
263 redrawcmdprompt(); /* draw prompt or indent */
266 xpc
.xp_context
= EXPAND_NOTHING
;
267 xpc
.xp_backslash
= XP_BS_NONE
;
268 #ifndef BACKSLASH_IN_FILENAME
269 xpc
.xp_shell
= FALSE
;
272 #if defined(FEAT_EVAL)
275 xpc
.xp_context
= ccline
.xp_context
;
276 xpc
.xp_pattern
= ccline
.cmdbuff
;
277 # if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
278 xpc
.xp_arg
= ccline
.xp_arg
;
284 * Avoid scrolling when called by a recursive do_cmdline(), e.g. when
285 * doing ":@0" when register 0 doesn't contain a CR.
291 if (firstc
== '/' || firstc
== '?' || firstc
== '@')
293 /* Use ":lmap" mappings for search pattern and input(). */
294 if (curbuf
->b_p_imsearch
== B_IMODE_USE_INSERT
)
295 b_im_ptr
= &curbuf
->b_p_iminsert
;
297 b_im_ptr
= &curbuf
->b_p_imsearch
;
298 if (*b_im_ptr
== B_IMODE_LMAP
)
300 #ifdef USE_IM_CONTROL
301 im_set_active(*b_im_ptr
== B_IMODE_IM
);
304 #ifdef USE_IM_CONTROL
305 else if (p_imcmdline
)
313 ui_cursor_shape(); /* may show different cursor shape */
316 /* When inside an autocommand for writing "exiting" may be set and
317 * terminal mode set to cooked. Need to set raw mode here then. */
322 hiscnt
= hislen
; /* set hiscnt to impossible history value */
323 histype
= hist_char2type(firstc
);
327 do_digraph(-1); /* init digraph typeahead */
331 * Collect the command string, handling editing keys.
335 redir_off
= TRUE
; /* Don't redirect the typed command.
336 Repeated, because a ":redir" inside
337 completion may switch it on. */
338 #ifdef USE_ON_FLY_SCROLL
339 dont_scroll
= FALSE
; /* allow scrolling here */
341 quit_more
= FALSE
; /* reset after CTRL-D which had a more-prompt */
343 cursorcmd(); /* set the cursor on the right spot */
345 /* Get a character. Ignore K_IGNORE, it should not do anything, such
346 * as stop completion. */
350 } while (c
== K_IGNORE
);
354 some_key_typed
= TRUE
;
355 #ifdef FEAT_RIGHTLEFT
362 if (cmdmsg_rl
&& !KeyStuffed
)
364 /* Invert horizontal movements and operations. Only when
365 * typed by the user directly, not when the result of a
369 case K_RIGHT
: c
= K_LEFT
; break;
370 case K_S_RIGHT
: c
= K_S_LEFT
; break;
371 case K_C_RIGHT
: c
= K_C_LEFT
; break;
372 case K_LEFT
: c
= K_RIGHT
; break;
373 case K_S_LEFT
: c
= K_S_RIGHT
; break;
374 case K_C_LEFT
: c
= K_C_RIGHT
; break;
381 * Ignore got_int when CTRL-C was typed here.
382 * Don't ignore it in :global, we really need to break then, e.g., for
383 * ":g/pat/normal /pat" (without the <CR>).
384 * Don't ignore it for the input() function.
391 #if defined(FEAT_EVAL) || defined(FEAT_CRYPT)
401 /* free old command line when finished moving around in the history
404 && c
!= K_S_DOWN
&& c
!= K_S_UP
405 && c
!= K_DOWN
&& c
!= K_UP
406 && c
!= K_PAGEDOWN
&& c
!= K_PAGEUP
407 && c
!= K_KPAGEDOWN
&& c
!= K_KPAGEUP
408 && c
!= K_LEFT
&& c
!= K_RIGHT
409 && (xpc
.xp_numfiles
> 0 || (c
!= Ctrl_P
&& c
!= Ctrl_N
)))
417 * When there are matching completions to select <S-Tab> works like
418 * CTRL-P (unless 'wc' is <S-Tab>).
420 if (c
!= p_wc
&& c
== K_S_TAB
&& xpc
.xp_numfiles
> 0)
424 /* Special translations for 'wildmenu' */
425 if (did_wild_list
&& p_wmnu
)
429 else if (c
== K_RIGHT
)
432 /* Hitting CR after "emenu Name.": complete submenu */
433 if (xpc
.xp_context
== EXPAND_MENUNAMES
&& p_wmnu
435 && ccline
.cmdbuff
[ccline
.cmdpos
- 1] == '.'
436 && ccline
.cmdbuff
[ccline
.cmdpos
- 2] != '\\'
437 && (c
== '\n' || c
== '\r' || c
== K_KENTER
))
441 /* free expanded names when finished walking through matches */
442 if (xpc
.xp_numfiles
!= -1
443 && !(c
== p_wc
&& KeyTyped
) && c
!= p_wcm
444 && c
!= Ctrl_N
&& c
!= Ctrl_P
&& c
!= Ctrl_A
447 (void)ExpandOne(&xpc
, NULL
, NULL
, 0, WILD_FREE
);
448 did_wild_list
= FALSE
;
450 if (!p_wmnu
|| (c
!= K_UP
&& c
!= K_DOWN
))
452 xpc
.xp_context
= EXPAND_NOTHING
;
455 if (p_wmnu
&& wild_menu_showing
!= 0)
458 int old_RedrawingDisabled
= RedrawingDisabled
;
461 RedrawingDisabled
= 0;
463 if (wild_menu_showing
== WM_SCROLLED
)
465 /* Entered command line, move it up */
469 else if (save_p_ls
!= -1)
471 /* restore 'laststatus' and 'winminheight' */
475 save_cmdline(&save_ccline
);
476 update_screen(VALID
); /* redraw the screen NOW */
477 restore_cmdline(&save_ccline
);
483 # ifdef FEAT_VERTSPLIT
484 win_redraw_last_status(topframe
);
486 lastwin
->w_redr_status
= TRUE
;
488 redraw_statuslines();
491 wild_menu_showing
= 0;
493 RedrawingDisabled
= old_RedrawingDisabled
;
499 /* Special translations for 'wildmenu' */
500 if (xpc
.xp_context
== EXPAND_MENUNAMES
&& p_wmnu
)
502 /* Hitting <Down> after "emenu Name.": complete submenu */
503 if (c
== K_DOWN
&& ccline
.cmdpos
> 0
504 && ccline
.cmdbuff
[ccline
.cmdpos
- 1] == '.')
508 /* Hitting <Up>: Remove one submenu name in front of the
512 j
= (int)(xpc
.xp_pattern
- ccline
.cmdbuff
);
516 /* check for start of menu name */
517 if (ccline
.cmdbuff
[j
] == ' '
518 && ccline
.cmdbuff
[j
- 1] != '\\')
523 /* check for start of submenu name */
524 if (ccline
.cmdbuff
[j
] == '.'
525 && ccline
.cmdbuff
[j
- 1] != '\\')
539 xpc
.xp_context
= EXPAND_NOTHING
;
542 if ((xpc
.xp_context
== EXPAND_FILES
543 || xpc
.xp_context
== EXPAND_DIRECTORIES
544 || xpc
.xp_context
== EXPAND_SHELLCMD
) && p_wmnu
)
556 && ccline
.cmdbuff
[ccline
.cmdpos
- 1] == PATHSEP
557 && (ccline
.cmdpos
< 3
558 || ccline
.cmdbuff
[ccline
.cmdpos
- 2] != '.'
559 || ccline
.cmdbuff
[ccline
.cmdpos
- 3] != '.'))
561 /* go down a directory */
564 else if (STRNCMP(xpc
.xp_pattern
, upseg
+ 1, 3) == 0 && c
== K_DOWN
)
566 /* If in a direct ancestor, strip off one ../ to go down */
570 i
= (int)(xpc
.xp_pattern
- ccline
.cmdbuff
);
575 j
-= (*mb_head_off
)(ccline
.cmdbuff
, ccline
.cmdbuff
+ j
);
577 if (vim_ispathsep(ccline
.cmdbuff
[j
]))
584 && ccline
.cmdbuff
[j
- 1] == '.'
585 && ccline
.cmdbuff
[j
- 2] == '.'
586 && (vim_ispathsep(ccline
.cmdbuff
[j
- 3]) || j
== i
+ 2))
594 /* go up a directory */
597 j
= ccline
.cmdpos
- 1;
598 i
= (int)(xpc
.xp_pattern
- ccline
.cmdbuff
);
603 j
-= (*mb_head_off
)(ccline
.cmdbuff
, ccline
.cmdbuff
+ j
);
605 if (vim_ispathsep(ccline
.cmdbuff
[j
])
606 #ifdef BACKSLASH_IN_FILENAME
607 && vim_strchr(" *?[{`$%#", ccline
.cmdbuff
[j
+ 1])
624 else if (STRNCMP(ccline
.cmdbuff
+ j
, upseg
, 4) == 0)
626 else if (STRNCMP(ccline
.cmdbuff
+ j
, upseg
+ 1, 3) == 0
633 /* TODO this is only for DOS/UNIX systems - need to put in
634 * machine-specific stuff here and in upseg init */
636 put_on_cmdline(upseg
+ 1, 3, FALSE
);
638 else if (ccline
.cmdpos
> i
)
643 #if 0 /* If enabled <Down> on a file takes you _completely_ out of wildmenu */
645 && (xpc
.xp_context
== EXPAND_FILES
646 || xpc
.xp_context
== EXPAND_MENUNAMES
)
647 && (c
== K_UP
|| c
== K_DOWN
))
648 xpc
.xp_context
= EXPAND_NOTHING
;
651 #endif /* FEAT_WILDMENU */
653 /* CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert
654 * mode when 'insertmode' is set, CTRL-\ e prompts for an expression. */
662 /* CTRL-\ e doesn't work when obtaining an expression. */
663 if (c
!= Ctrl_N
&& c
!= Ctrl_G
664 && (c
!= 'e' || ccline
.cmdfirstc
== '='))
675 * Replace the command line with the result of an expression.
676 * Need to save and restore the current command line, to be
677 * able to enter a new one...
679 if (ccline
.cmdpos
== ccline
.cmdlen
)
680 new_cmdpos
= 99999; /* keep it at the end */
682 new_cmdpos
= ccline
.cmdpos
;
684 save_cmdline(&save_ccline
);
685 c
= get_expr_register();
686 restore_cmdline(&save_ccline
);
689 /* Need to save and restore ccline. And set "textlock"
690 * to avoid nasty things like going to another buffer when
691 * evaluating an expression. */
692 save_cmdline(&save_ccline
);
696 restore_cmdline(&save_ccline
);
698 if (p
!= NULL
&& realloc_cmdbuff((int)STRLEN(p
) + 1) == OK
)
700 ccline
.cmdlen
= (int)STRLEN(p
);
701 STRCPY(ccline
.cmdbuff
, p
);
704 /* Restore the cursor or use the position set with
705 * set_cmdline_pos(). */
706 if (new_cmdpos
> ccline
.cmdlen
)
707 ccline
.cmdpos
= ccline
.cmdlen
;
709 ccline
.cmdpos
= new_cmdpos
;
711 KeyTyped
= FALSE
; /* Don't do p_wc completion. */
713 goto cmdline_changed
;
722 if (c
== Ctrl_G
&& p_im
&& restart_edit
== 0)
724 gotesc
= TRUE
; /* will free ccline.cmdbuff after putting it
726 goto returncmd
; /* back to Normal mode */
731 if (c
== cedit_key
|| c
== K_CMDWIN
)
734 * Open a window to edit the command line (and history).
737 some_key_typed
= TRUE
;
739 # ifdef FEAT_DIGRAPHS
747 if (c
== '\n' || c
== '\r' || c
== K_KENTER
|| (c
== ESC
748 && (!KeyTyped
|| vim_strchr(p_cpo
, CPO_ESC
) != NULL
)))
750 /* In Ex mode a backslash escapes a newline. */
753 && ccline
.cmdpos
== ccline
.cmdlen
755 && ccline
.cmdbuff
[ccline
.cmdpos
- 1] == '\\')
762 gotesc
= FALSE
; /* Might have typed ESC previously, don't
763 truncate the cmdline now. */
764 if (ccheck_abbr(c
+ ABBR_OFF
))
765 goto cmdline_changed
;
768 windgoto(msg_row
, 0);
776 * Completion for 'wildchar' or 'wildcharm' key.
777 * - hitting <ESC> twice means: abandon command line.
778 * - wildcard expansion is only done when the 'wildchar' key is really
779 * typed, not when it comes from a macro
781 if ((c
== p_wc
&& !gotesc
&& KeyTyped
) || c
== p_wcm
)
783 if (xpc
.xp_numfiles
> 0) /* typed p_wc at least twice */
785 /* if 'wildmode' contains "list" may still need to list */
786 if (xpc
.xp_numfiles
> 1
788 && (wim_flags
[wim_index
] & WIM_LIST
))
790 (void)showmatches(&xpc
, FALSE
);
792 did_wild_list
= TRUE
;
794 if (wim_flags
[wim_index
] & WIM_LONGEST
)
795 res
= nextwild(&xpc
, WILD_LONGEST
, WILD_NO_BEEP
);
796 else if (wim_flags
[wim_index
] & WIM_FULL
)
797 res
= nextwild(&xpc
, WILD_NEXT
, WILD_NO_BEEP
);
799 res
= OK
; /* don't insert 'wildchar' now */
801 else /* typed p_wc first time */
805 /* if 'wildmode' first contains "longest", get longest
807 if (wim_flags
[0] & WIM_LONGEST
)
808 res
= nextwild(&xpc
, WILD_LONGEST
, WILD_NO_BEEP
);
810 res
= nextwild(&xpc
, WILD_EXPAND_KEEP
, WILD_NO_BEEP
);
812 /* if interrupted while completing, behave like it failed */
815 (void)vpeekc(); /* remove <C-C> from input stream */
816 got_int
= FALSE
; /* don't abandon the command line */
817 (void)ExpandOne(&xpc
, NULL
, NULL
, 0, WILD_FREE
);
819 xpc
.xp_context
= EXPAND_NOTHING
;
821 goto cmdline_changed
;
824 /* when more than one match, and 'wildmode' first contains
825 * "list", or no change and 'wildmode' contains "longest,list",
826 * list all matches */
827 if (res
== OK
&& xpc
.xp_numfiles
> 1)
829 /* a "longest" that didn't do anything is skipped (but not
831 if (wim_flags
[0] == WIM_LONGEST
&& ccline
.cmdpos
== j
)
833 if ((wim_flags
[wim_index
] & WIM_LIST
)
835 || (p_wmnu
&& (wim_flags
[wim_index
] & WIM_FULL
) != 0)
839 if (!(wim_flags
[0] & WIM_LONGEST
))
842 int p_wmnu_save
= p_wmnu
;
845 nextwild(&xpc
, WILD_PREV
, 0); /* remove match */
847 p_wmnu
= p_wmnu_save
;
851 (void)showmatches(&xpc
, p_wmnu
852 && ((wim_flags
[wim_index
] & WIM_LIST
) == 0));
854 (void)showmatches(&xpc
, FALSE
);
857 did_wild_list
= TRUE
;
858 if (wim_flags
[wim_index
] & WIM_LONGEST
)
859 nextwild(&xpc
, WILD_LONGEST
, WILD_NO_BEEP
);
860 else if (wim_flags
[wim_index
] & WIM_FULL
)
861 nextwild(&xpc
, WILD_NEXT
, WILD_NO_BEEP
);
867 else if (xpc
.xp_numfiles
== -1)
868 xpc
.xp_context
= EXPAND_NOTHING
;
876 goto cmdline_changed
;
881 /* <S-Tab> goes to last match, in a clumsy way */
882 if (c
== K_S_TAB
&& KeyTyped
)
884 if (nextwild(&xpc
, WILD_EXPAND_KEEP
, 0) == OK
885 && nextwild(&xpc
, WILD_PREV
, 0) == OK
886 && nextwild(&xpc
, WILD_PREV
, 0) == OK
)
887 goto cmdline_changed
;
890 if (c
== NUL
|| c
== K_ZERO
) /* NUL is stored as NL */
893 do_abbr
= TRUE
; /* default: check for abbreviation */
896 * Big switch for a typed command line character.
906 if (cmd_fkmap
&& c
== K_BS
)
913 * delete current character is the same as backspace on next
914 * character, except at end of line
916 if (c
== K_DEL
&& ccline
.cmdpos
!= ccline
.cmdlen
)
919 if (has_mbyte
&& c
== K_DEL
)
920 ccline
.cmdpos
+= mb_off_next(ccline
.cmdbuff
,
921 ccline
.cmdbuff
+ ccline
.cmdpos
);
923 if (ccline
.cmdpos
> 0)
928 p
= ccline
.cmdbuff
+ j
;
932 p
= mb_prevptr(ccline
.cmdbuff
, p
);
935 while (p
> ccline
.cmdbuff
&& vim_isspace(*p
))
936 p
= mb_prevptr(ccline
.cmdbuff
, p
);
938 while (p
> ccline
.cmdbuff
&& mb_get_class(p
) == i
)
939 p
= mb_prevptr(ccline
.cmdbuff
, p
);
940 if (mb_get_class(p
) != i
)
941 p
+= (*mb_ptr2len
)(p
);
948 while (p
> ccline
.cmdbuff
&& vim_isspace(p
[-1]))
950 i
= vim_iswordc(p
[-1]);
951 while (p
> ccline
.cmdbuff
&& !vim_isspace(p
[-1])
952 && vim_iswordc(p
[-1]) == i
)
957 ccline
.cmdpos
= (int)(p
- ccline
.cmdbuff
);
958 ccline
.cmdlen
-= j
- ccline
.cmdpos
;
960 while (i
< ccline
.cmdlen
)
961 ccline
.cmdbuff
[i
++] = ccline
.cmdbuff
[j
++];
963 /* Truncate at the end, required for multi-byte chars. */
964 ccline
.cmdbuff
[ccline
.cmdlen
] = NUL
;
967 else if (ccline
.cmdlen
== 0 && c
!= Ctrl_W
968 && ccline
.cmdprompt
== NULL
&& indent
== 0)
970 /* In ex and debug mode it doesn't make sense to return. */
973 || ccline
.cmdfirstc
== '>'
976 goto cmdline_not_changed
;
978 vim_free(ccline
.cmdbuff
); /* no commandline to return */
979 ccline
.cmdbuff
= NULL
;
982 #ifdef FEAT_RIGHTLEFT
988 msg_putchar(' '); /* delete ':' */
990 redraw_cmdline
= TRUE
;
991 goto returncmd
; /* back to cmd mode */
993 goto cmdline_changed
;
998 /* if Farsi mode set, we are in reverse insert mode -
999 Do not change the mode */
1004 ccline
.overstrike
= !ccline
.overstrike
;
1006 ui_cursor_shape(); /* may show different cursor shape */
1008 goto cmdline_not_changed
;
1011 if (map_to_exists_mode((char_u
*)"", LANGMAP
, FALSE
))
1013 /* ":lmap" mappings exists, toggle use of mappings. */
1015 #ifdef USE_IM_CONTROL
1016 im_set_active(FALSE
); /* Disable input method */
1018 if (b_im_ptr
!= NULL
)
1020 if (State
& LANGMAP
)
1021 *b_im_ptr
= B_IMODE_LMAP
;
1023 *b_im_ptr
= B_IMODE_NONE
;
1026 #ifdef USE_IM_CONTROL
1029 /* There are no ":lmap" mappings, toggle IM. When
1030 * 'imdisable' is set don't try getting the status, it's
1032 if ((p_imdisable
&& b_im_ptr
!= NULL
)
1033 ? *b_im_ptr
== B_IMODE_IM
: im_get_status())
1035 im_set_active(FALSE
); /* Disable input method */
1036 if (b_im_ptr
!= NULL
)
1037 *b_im_ptr
= B_IMODE_NONE
;
1041 im_set_active(TRUE
); /* Enable input method */
1042 if (b_im_ptr
!= NULL
)
1043 *b_im_ptr
= B_IMODE_IM
;
1047 if (b_im_ptr
!= NULL
)
1049 if (b_im_ptr
== &curbuf
->b_p_iminsert
)
1050 set_iminsert_global();
1052 set_imsearch_global();
1055 ui_cursor_shape(); /* may show different cursor shape */
1057 #if defined(FEAT_WINDOWS) && defined(FEAT_KEYMAP)
1058 /* Show/unshow value of 'keymap' in status lines later. */
1059 status_redraw_curbuf();
1061 goto cmdline_not_changed
;
1063 /* case '@': only in very old vi */
1065 /* delete all characters left of the cursor */
1068 i
= ccline
.cmdpos
= 0;
1069 while (i
< ccline
.cmdlen
)
1070 ccline
.cmdbuff
[i
++] = ccline
.cmdbuff
[j
++];
1071 /* Truncate at the end, required for multi-byte chars. */
1072 ccline
.cmdbuff
[ccline
.cmdlen
] = NUL
;
1074 goto cmdline_changed
;
1076 #ifdef FEAT_CLIPBOARD
1078 /* Copy the modeless selection, if there is one. */
1079 if (clip_star
.state
!= SELECT_CLEARED
)
1081 if (clip_star
.state
== SELECT_DONE
)
1082 clip_copy_modeless_selection(TRUE
);
1083 goto cmdline_not_changed
;
1088 case ESC
: /* get here if p_wc != ESC or when ESC typed twice */
1090 /* In exmode it doesn't make sense to return. Except when
1091 * ":normal" runs out of characters. */
1093 #ifdef FEAT_EX_EXTRA
1094 && (ex_normal_busy
== 0 || typebuf
.tb_len
> 0)
1097 goto cmdline_not_changed
;
1099 gotesc
= TRUE
; /* will free ccline.cmdbuff after
1100 putting it in history */
1101 goto returncmd
; /* back to cmd mode */
1103 case Ctrl_R
: /* insert register */
1104 #ifdef USE_ON_FLY_SCROLL
1105 dont_scroll
= TRUE
; /* disallow scrolling here */
1107 putcmdline('"', TRUE
);
1109 i
= c
= plain_vgetc(); /* CTRL-R <char> */
1111 i
= Ctrl_R
; /* CTRL-R CTRL-O == CTRL-R CTRL-R */
1113 c
= plain_vgetc(); /* CTRL-R CTRL-R <char> */
1117 * Insert the result of an expression.
1118 * Need to save the current command line, to be able to enter
1124 if (ccline
.cmdfirstc
== '=')/* can't do this recursively */
1131 save_cmdline(&save_ccline
);
1132 c
= get_expr_register();
1133 restore_cmdline(&save_ccline
);
1137 if (c
!= ESC
) /* use ESC to cancel inserting register */
1139 cmdline_paste(c
, i
== Ctrl_R
, FALSE
);
1142 /* When there was a serious error abort getting the
1146 gotesc
= TRUE
; /* will free ccline.cmdbuff after
1147 putting it in history */
1148 goto returncmd
; /* back to cmd mode */
1151 KeyTyped
= FALSE
; /* Don't do p_wc completion. */
1153 if (new_cmdpos
>= 0)
1155 /* set_cmdline_pos() was used */
1156 if (new_cmdpos
> ccline
.cmdlen
)
1157 ccline
.cmdpos
= ccline
.cmdlen
;
1159 ccline
.cmdpos
= new_cmdpos
;
1164 goto cmdline_changed
;
1167 if (showmatches(&xpc
, FALSE
) == EXPAND_NOTHING
)
1168 break; /* Use ^D as normal char instead */
1171 continue; /* don't do incremental search now */
1178 if (ccline
.cmdpos
>= ccline
.cmdlen
)
1180 i
= cmdline_charsize(ccline
.cmdpos
);
1181 if (KeyTyped
&& ccline
.cmdspos
+ i
>= Columns
* Rows
)
1183 ccline
.cmdspos
+= i
;
1186 ccline
.cmdpos
+= (*mb_ptr2len
)(ccline
.cmdbuff
1192 while ((c
== K_S_RIGHT
|| c
== K_C_RIGHT
1193 || (mod_mask
& (MOD_MASK_SHIFT
|MOD_MASK_CTRL
)))
1194 && ccline
.cmdbuff
[ccline
.cmdpos
] != ' ');
1197 set_cmdspos_cursor();
1199 goto cmdline_not_changed
;
1204 if (ccline
.cmdpos
== 0)
1205 goto cmdline_not_changed
;
1210 if (has_mbyte
) /* move to first byte of char */
1211 ccline
.cmdpos
-= (*mb_head_off
)(ccline
.cmdbuff
,
1212 ccline
.cmdbuff
+ ccline
.cmdpos
);
1214 ccline
.cmdspos
-= cmdline_charsize(ccline
.cmdpos
);
1216 while (ccline
.cmdpos
> 0
1217 && (c
== K_S_LEFT
|| c
== K_C_LEFT
1218 || (mod_mask
& (MOD_MASK_SHIFT
|MOD_MASK_CTRL
)))
1219 && ccline
.cmdbuff
[ccline
.cmdpos
- 1] != ' ');
1222 set_cmdspos_cursor();
1224 goto cmdline_not_changed
;
1227 /* Ignore mouse event or ex_window() result. */
1228 goto cmdline_not_changed
;
1231 /* On Win32 ignore <M-F4>, we get it when closing the window was
1234 if (mod_mask
== MOD_MASK_ALT
)
1236 redrawcmd(); /* somehow the cmdline is cleared */
1237 goto cmdline_not_changed
;
1244 case K_MIDDLERELEASE
:
1245 goto cmdline_not_changed
; /* Ignore mouse */
1249 /* When GUI is active, also paste when 'mouse' is empty */
1252 if (!mouse_has(MOUSE_COMMAND
))
1253 goto cmdline_not_changed
; /* Ignore mouse */
1254 # ifdef FEAT_CLIPBOARD
1255 if (clip_star
.available
)
1256 cmdline_paste('*', TRUE
, TRUE
);
1259 cmdline_paste(0, TRUE
, TRUE
);
1261 goto cmdline_changed
;
1265 cmdline_paste('~', TRUE
, FALSE
);
1267 goto cmdline_changed
;
1273 case K_RIGHTRELEASE
:
1274 /* Ignore drag and release events when the button-down wasn't
1276 if (ignore_drag_release
)
1277 goto cmdline_not_changed
;
1281 if (c
== K_LEFTRELEASE
|| c
== K_RIGHTRELEASE
)
1282 ignore_drag_release
= TRUE
;
1284 ignore_drag_release
= FALSE
;
1286 /* When GUI is active, also move when 'mouse' is empty */
1289 if (!mouse_has(MOUSE_COMMAND
))
1290 goto cmdline_not_changed
; /* Ignore mouse */
1291 # ifdef FEAT_CLIPBOARD
1292 if (mouse_row
< cmdline_row
&& clip_star
.available
)
1294 int button
, is_click
, is_drag
;
1297 * Handle modeless selection.
1299 button
= get_mouse_button(KEY2TERMCAP1(c
),
1300 &is_click
, &is_drag
);
1301 if (mouse_model_popup() && button
== MOUSE_LEFT
1302 && (mod_mask
& MOD_MASK_SHIFT
))
1304 /* Translate shift-left to right button. */
1305 button
= MOUSE_RIGHT
;
1306 mod_mask
&= ~MOD_MASK_SHIFT
;
1308 clip_modeless(button
, is_click
, is_drag
);
1309 goto cmdline_not_changed
;
1314 for (ccline
.cmdpos
= 0; ccline
.cmdpos
< ccline
.cmdlen
;
1317 i
= cmdline_charsize(ccline
.cmdpos
);
1318 if (mouse_row
<= cmdline_row
+ ccline
.cmdspos
/ Columns
1319 && mouse_col
< ccline
.cmdspos
% Columns
+ i
)
1324 /* Count ">" for double-wide char that doesn't fit. */
1325 correct_cmdspos(ccline
.cmdpos
, i
);
1326 ccline
.cmdpos
+= (*mb_ptr2len
)(ccline
.cmdbuff
1327 + ccline
.cmdpos
) - 1;
1330 ccline
.cmdspos
+= i
;
1332 goto cmdline_not_changed
;
1334 /* Mouse scroll wheel: ignored here */
1337 /* Alternate buttons ignored here */
1344 goto cmdline_not_changed
;
1346 #endif /* FEAT_MOUSE */
1349 case K_LEFTMOUSE_NM
: /* mousefocus click, ignored */
1350 case K_LEFTRELEASE_NM
:
1351 goto cmdline_not_changed
;
1353 case K_VER_SCROLLBAR
:
1354 if (msg_scrolled
== 0)
1359 goto cmdline_not_changed
;
1361 case K_HOR_SCROLLBAR
:
1362 if (msg_scrolled
== 0)
1364 gui_do_horiz_scroll();
1367 goto cmdline_not_changed
;
1369 #ifdef FEAT_GUI_TABLINE
1372 /* Don't want to change any tabs here. Make sure the same tab
1373 * is still selected. */
1374 if (gui_use_tabline())
1375 gui_mch_set_curtab(tabpage_index(curtab
));
1376 goto cmdline_not_changed
;
1379 case K_SELECT
: /* end of Select mode mapping - ignore */
1380 goto cmdline_not_changed
;
1382 case Ctrl_B
: /* begin of command line */
1389 goto cmdline_not_changed
;
1391 case Ctrl_E
: /* end of command line */
1396 ccline
.cmdpos
= ccline
.cmdlen
;
1397 set_cmdspos_cursor();
1398 goto cmdline_not_changed
;
1400 case Ctrl_A
: /* all matches */
1401 if (nextwild(&xpc
, WILD_ALL
, 0) == FAIL
)
1403 goto cmdline_changed
;
1406 #ifdef FEAT_SEARCH_EXTRA
1407 if (p_is
&& !cmd_silent
&& (firstc
== '/' || firstc
== '?'))
1409 /* Add a character from under the cursor for 'incsearch' */
1411 && !equalpos(curwin
->w_cursor
, old_cursor
))
1416 if (c
== firstc
|| vim_strchr((char_u
*)(
1417 p_magic
? "\\^$.*[" : "\\^$"), c
)
1420 /* put a backslash before special characters */
1421 stuffcharReadbuff(c
);
1427 goto cmdline_not_changed
;
1431 /* completion: longest common part */
1432 if (nextwild(&xpc
, WILD_LONGEST
, 0) == FAIL
)
1434 goto cmdline_changed
;
1436 case Ctrl_N
: /* next match */
1437 case Ctrl_P
: /* previous match */
1438 if (xpc
.xp_numfiles
> 0)
1440 if (nextwild(&xpc
, (c
== Ctrl_P
) ? WILD_PREV
: WILD_NEXT
, 0)
1443 goto cmdline_changed
;
1455 if (hislen
== 0 || firstc
== NUL
) /* no history */
1456 goto cmdline_not_changed
;
1460 /* save current command string so it can be restored later */
1461 if (lookfor
== NULL
)
1463 if ((lookfor
= vim_strsave(ccline
.cmdbuff
)) == NULL
)
1464 goto cmdline_not_changed
;
1465 lookfor
[ccline
.cmdpos
] = NUL
;
1468 j
= (int)STRLEN(lookfor
);
1471 /* one step backwards */
1472 if (c
== K_UP
|| c
== K_S_UP
|| c
== Ctrl_P
1473 || c
== K_PAGEUP
|| c
== K_KPAGEUP
)
1475 if (hiscnt
== hislen
) /* first time */
1476 hiscnt
= hisidx
[histype
];
1477 else if (hiscnt
== 0 && hisidx
[histype
] != hislen
- 1)
1478 hiscnt
= hislen
- 1;
1479 else if (hiscnt
!= hisidx
[histype
] + 1)
1481 else /* at top of list */
1487 else /* one step forwards */
1489 /* on last entry, clear the line */
1490 if (hiscnt
== hisidx
[histype
])
1496 /* not on a history line, nothing to do */
1497 if (hiscnt
== hislen
)
1499 if (hiscnt
== hislen
- 1) /* wrap around */
1504 if (hiscnt
< 0 || history
[histype
][hiscnt
].hisstr
== NULL
)
1509 if ((c
!= K_UP
&& c
!= K_DOWN
)
1511 || STRNCMP(history
[histype
][hiscnt
].hisstr
,
1512 lookfor
, (size_t)j
) == 0)
1516 if (hiscnt
!= i
) /* jumped to other entry */
1522 vim_free(ccline
.cmdbuff
);
1523 xpc
.xp_context
= EXPAND_NOTHING
;
1524 if (hiscnt
== hislen
)
1525 p
= lookfor
; /* back to the old one */
1527 p
= history
[histype
][hiscnt
].hisstr
;
1529 if (histype
== HIST_SEARCH
1531 && (old_firstc
= p
[STRLEN(p
) + 1]) != firstc
)
1533 /* Correct for the separator character used when
1534 * adding the history entry vs the one used now.
1535 * First loop: count length.
1536 * Second loop: copy the characters. */
1537 for (i
= 0; i
<= 1; ++i
)
1540 for (j
= 0; p
[j
] != NUL
; ++j
)
1542 /* Replace old sep with new sep, unless it is
1544 if (p
[j
] == old_firstc
1545 && (j
== 0 || p
[j
- 1] != '\\'))
1548 ccline
.cmdbuff
[len
] = firstc
;
1552 /* Escape new sep, unless it is already
1555 && (j
== 0 || p
[j
- 1] != '\\'))
1558 ccline
.cmdbuff
[len
] = '\\';
1562 ccline
.cmdbuff
[len
] = p
[j
];
1569 if (ccline
.cmdbuff
== NULL
)
1573 ccline
.cmdbuff
[len
] = NUL
;
1577 alloc_cmdbuff((int)STRLEN(p
));
1578 if (ccline
.cmdbuff
== NULL
)
1580 STRCPY(ccline
.cmdbuff
, p
);
1583 ccline
.cmdpos
= ccline
.cmdlen
= (int)STRLEN(ccline
.cmdbuff
);
1585 goto cmdline_changed
;
1588 goto cmdline_not_changed
;
1594 ignore_drag_release
= TRUE
;
1596 putcmdline('^', TRUE
);
1597 c
= get_literal(); /* get next (two) character(s) */
1598 do_abbr
= FALSE
; /* don't do abbreviation now */
1600 /* may need to remove ^ when composing char was typed */
1601 if (enc_utf8
&& utf_iscomposing(c
) && !cmd_silent
)
1603 draw_cmdline(ccline
.cmdpos
, ccline
.cmdlen
- ccline
.cmdpos
);
1610 #ifdef FEAT_DIGRAPHS
1613 ignore_drag_release
= TRUE
;
1615 putcmdline('?', TRUE
);
1616 #ifdef USE_ON_FLY_SCROLL
1617 dont_scroll
= TRUE
; /* disallow scrolling here */
1619 c
= get_digraph(TRUE
);
1624 goto cmdline_not_changed
;
1625 #endif /* FEAT_DIGRAPHS */
1627 #ifdef FEAT_RIGHTLEFT
1628 case Ctrl__
: /* CTRL-_: switch language mode */
1634 cmd_fkmap
= !cmd_fkmap
;
1635 if (cmd_fkmap
) /* in Farsi always in Insert mode */
1636 ccline
.overstrike
= FALSE
;
1638 else /* Hebrew is default */
1640 cmd_hkmap
= !cmd_hkmap
;
1641 goto cmdline_not_changed
;
1648 gotesc
= TRUE
; /* will free ccline.cmdbuff after
1649 putting it in history */
1650 goto returncmd
; /* back to Normal mode */
1654 * Normal character with no special meaning. Just set mod_mask
1655 * to 0x0 so that typing Shift-Space in the GUI doesn't enter
1656 * the string <S-Space>. This should only happen after ^V.
1663 * End of switch on command line character.
1664 * We come here if we have a normal character.
1667 if (do_abbr
&& (IS_SPECIAL(c
) || !vim_iswordc(c
)) && ccheck_abbr(
1669 /* Add ABBR_OFF for characters above 0x100, this is
1670 * what check_abbr() expects. */
1671 (has_mbyte
&& c
>= 0x100) ? (c
+ ABBR_OFF
) :
1674 goto cmdline_changed
;
1677 * put the character in the command line
1679 if (IS_SPECIAL(c
) || mod_mask
!= 0)
1680 put_on_cmdline(get_special_key_name(c
, mod_mask
), -1, TRUE
);
1686 j
= (*mb_char2bytes
)(c
, IObuff
);
1687 IObuff
[j
] = NUL
; /* exclude composing chars */
1688 put_on_cmdline(IObuff
, j
, TRUE
);
1694 put_on_cmdline(IObuff
, 1, TRUE
);
1697 goto cmdline_changed
;
1700 * This part implements incremental searches for "/" and "?"
1701 * Jump to cmdline_not_changed when a character has been read but the command
1702 * line did not change. Then we only search and redraw if something changed in
1704 * Jump to cmdline_changed when the command line did change.
1705 * (Sorry for the goto's, I know it is ugly).
1707 cmdline_not_changed
:
1708 #ifdef FEAT_SEARCH_EXTRA
1709 if (!incsearch_postponed
)
1714 #ifdef FEAT_SEARCH_EXTRA
1716 * 'incsearch' highlighting.
1718 if (p_is
&& !cmd_silent
&& (firstc
== '/' || firstc
== '?'))
1725 /* if there is a character waiting, search and redraw later */
1728 incsearch_postponed
= TRUE
;
1731 incsearch_postponed
= FALSE
;
1732 curwin
->w_cursor
= old_cursor
; /* start at old position */
1734 /* If there is no command line, don't do anything */
1735 if (ccline
.cmdlen
== 0)
1739 cursor_off(); /* so the user knows we're busy */
1741 ++emsg_off
; /* So it doesn't beep if bad expr */
1743 /* Set the time limit to half a second. */
1744 profile_setlimit(500L, &tm
);
1746 i
= do_search(NULL
, firstc
, ccline
.cmdbuff
, count
,
1747 SEARCH_KEEP
+ SEARCH_OPT
+ SEARCH_NOOF
+ SEARCH_PEEK
,
1755 /* if interrupted while searching, behave like it failed */
1758 (void)vpeekc(); /* remove <C-C> from input stream */
1759 got_int
= FALSE
; /* don't abandon the command line */
1762 else if (char_avail())
1763 /* cancelled searching because a char was typed */
1764 incsearch_postponed
= TRUE
;
1767 highlight_match
= TRUE
; /* highlight position */
1769 highlight_match
= FALSE
; /* remove highlight */
1771 /* first restore the old curwin values, so the screen is
1772 * positioned in the same way as the actual search command */
1773 curwin
->w_leftcol
= old_leftcol
;
1774 curwin
->w_topline
= old_topline
;
1776 curwin
->w_topfill
= old_topfill
;
1778 curwin
->w_botline
= old_botline
;
1779 changed_cline_bef_curs();
1784 pos_T save_pos
= curwin
->w_cursor
;
1787 * First move cursor to end of match, then to the start. This
1788 * moves the whole match onto the screen when 'nowrap' is set.
1790 curwin
->w_cursor
.lnum
+= search_match_lines
;
1791 curwin
->w_cursor
.col
= search_match_endcol
;
1792 if (curwin
->w_cursor
.lnum
> curbuf
->b_ml
.ml_line_count
)
1794 curwin
->w_cursor
.lnum
= curbuf
->b_ml
.ml_line_count
;
1795 coladvance((colnr_T
)MAXCOL
);
1798 end_pos
= curwin
->w_cursor
;
1799 curwin
->w_cursor
= save_pos
;
1802 end_pos
= curwin
->w_cursor
; /* shutup gcc 4 */
1805 # ifdef FEAT_WINDOWS
1806 /* May redraw the status line to show the cursor position. */
1807 if (p_ru
&& curwin
->w_status_height
> 0)
1808 curwin
->w_redr_status
= TRUE
;
1811 save_cmdline(&save_ccline
);
1812 update_screen(SOME_VALID
);
1813 restore_cmdline(&save_ccline
);
1815 /* Leave it at the end to make CTRL-R CTRL-W work. */
1817 curwin
->w_cursor
= end_pos
;
1821 did_incsearch
= TRUE
;
1823 #else /* FEAT_SEARCH_EXTRA */
1827 #ifdef FEAT_RIGHTLEFT
1830 || (p_arshape
&& !p_tbidi
&& enc_utf8
)
1833 /* Always redraw the whole command line to fix shaping and
1834 * right-left typing. Not efficient, but it works. */
1841 #ifdef FEAT_RIGHTLEFT
1849 ExpandCleanup(&xpc
);
1852 #ifdef FEAT_SEARCH_EXTRA
1855 curwin
->w_cursor
= old_cursor
;
1856 curwin
->w_curswant
= old_curswant
;
1857 curwin
->w_leftcol
= old_leftcol
;
1858 curwin
->w_topline
= old_topline
;
1860 curwin
->w_topfill
= old_topfill
;
1862 curwin
->w_botline
= old_botline
;
1863 highlight_match
= FALSE
;
1864 validate_cursor(); /* needed for TAB */
1865 redraw_later(SOME_VALID
);
1869 if (ccline
.cmdbuff
!= NULL
)
1872 * Put line in history buffer (":" and "=" only when it was typed).
1875 if (ccline
.cmdlen
&& firstc
!= NUL
1876 && (some_key_typed
|| histype
== HIST_SEARCH
))
1878 add_to_history(histype
, ccline
.cmdbuff
, TRUE
,
1879 histype
== HIST_SEARCH
? firstc
: NUL
);
1882 vim_free(new_last_cmdline
);
1883 new_last_cmdline
= vim_strsave(ccline
.cmdbuff
);
1888 if (gotesc
) /* abandon command line */
1890 vim_free(ccline
.cmdbuff
);
1891 ccline
.cmdbuff
= NULL
;
1892 if (msg_scrolled
== 0)
1895 redraw_cmdline
= TRUE
;
1900 * If the screen was shifted up, redraw the whole screen (later).
1901 * If the line is too long, clear it, so ruler and shown command do
1902 * not get printed in the middle of it.
1905 msg_scroll
= save_msg_scroll
;
1908 /* When the command line was typed, no need for a wait-return prompt. */
1910 need_wait_return
= FALSE
;
1913 #ifdef USE_IM_CONTROL
1914 if (b_im_ptr
!= NULL
&& *b_im_ptr
!= B_IMODE_LMAP
)
1915 im_save_status(b_im_ptr
);
1916 im_set_active(FALSE
);
1922 ui_cursor_shape(); /* may show different cursor shape */
1926 char_u
*p
= ccline
.cmdbuff
;
1928 /* Make ccline empty, getcmdline() may try to use it. */
1929 ccline
.cmdbuff
= NULL
;
1934 #if (defined(FEAT_CRYPT) || defined(FEAT_EVAL)) || defined(PROTO)
1936 * Get a command line with a prompt.
1937 * This is prepared to be called recursively from getcmdline() (e.g. by
1938 * f_input() when evaluating an expression from CTRL-R =).
1939 * Returns the command line in allocated memory, or NULL.
1942 getcmdline_prompt(firstc
, prompt
, attr
, xp_context
, xp_arg
)
1944 char_u
*prompt
; /* command line prompt */
1945 int attr
; /* attributes for prompt */
1946 int xp_context
; /* type of expansion */
1947 char_u
*xp_arg
; /* user-defined expansion argument */
1950 struct cmdline_info save_ccline
;
1951 int msg_col_save
= msg_col
;
1953 save_cmdline(&save_ccline
);
1954 ccline
.cmdprompt
= prompt
;
1955 ccline
.cmdattr
= attr
;
1957 ccline
.xp_context
= xp_context
;
1958 ccline
.xp_arg
= xp_arg
;
1959 ccline
.input_fn
= (firstc
== '@');
1961 s
= getcmdline(firstc
, 1L, 0);
1962 restore_cmdline(&save_ccline
);
1963 /* Restore msg_col, the prompt from input() may have changed it. */
1964 msg_col
= msg_col_save
;
1971 * Return TRUE when the text must not be changed and we can't switch to
1972 * another window or buffer. Used when editing the command line, evaluating
1973 * 'balloonexpr', etc.
1979 if (cmdwin_type
!= 0)
1982 return textlock
!= 0;
1986 * Give an error message for a command that isn't allowed while the cmdline
1987 * window is open or editing the cmdline in another way.
1993 if (cmdwin_type
!= 0)
2000 #if defined(FEAT_AUTOCMD) || defined(PROTO)
2002 * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
2003 * and give an error message.
2008 if (curbuf_lock
> 0)
2010 EMSG(_("E788: Not allowed to edit another buffer now"));
2013 return allbuf_locked();
2017 * Check if "allbuf_lock" is set and return TRUE when it is and give an error
2023 if (allbuf_lock
> 0)
2025 EMSG(_("E811: Not allowed to change buffer information now"));
2033 cmdline_charsize(idx
)
2036 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
2037 if (cmdline_star
> 0) /* showing '*', always 1 position */
2040 return ptr2cells(ccline
.cmdbuff
+ idx
);
2044 * Compute the offset of the cursor on the command line for the prompt and
2050 if (ccline
.cmdfirstc
!= NUL
)
2051 ccline
.cmdspos
= 1 + ccline
.cmdindent
;
2053 ccline
.cmdspos
= 0 + ccline
.cmdindent
;
2057 * Compute the screen position for the cursor on the command line.
2060 set_cmdspos_cursor()
2068 if (m
< 0) /* overflow, Columns or Rows at weird value */
2073 for (i
= 0; i
< ccline
.cmdlen
&& i
< ccline
.cmdpos
; ++i
)
2075 c
= cmdline_charsize(i
);
2077 /* Count ">" for double-wide multi-byte char that doesn't fit. */
2079 correct_cmdspos(i
, c
);
2081 /* If the cmdline doesn't fit, show cursor on last visible char.
2082 * Don't move the cursor itself, so we can still append. */
2083 if ((ccline
.cmdspos
+= c
) >= m
)
2085 ccline
.cmdspos
-= c
;
2090 i
+= (*mb_ptr2len
)(ccline
.cmdbuff
+ i
) - 1;
2097 * Check if the character at "idx", which is "cells" wide, is a multi-byte
2098 * character that doesn't fit, so that a ">" must be displayed.
2101 correct_cmdspos(idx
, cells
)
2105 if ((*mb_ptr2len
)(ccline
.cmdbuff
+ idx
) > 1
2106 && (*mb_ptr2cells
)(ccline
.cmdbuff
+ idx
) > 1
2107 && ccline
.cmdspos
% Columns
+ cells
> Columns
)
2113 * Get an Ex command line for the ":" command.
2116 getexline(c
, cookie
, indent
)
2117 int c
; /* normally ':', NUL for ":append" */
2118 void *cookie UNUSED
;
2119 int indent
; /* indent for inside conditionals */
2121 /* When executing a register, remove ':' that's in front of each line. */
2122 if (exec_from_reg
&& vpeekc() == ':')
2124 return getcmdline(c
, 1L, indent
);
2128 * Get an Ex command line for Ex mode.
2129 * In Ex mode we only use the OS supplied line editing features and no
2130 * mappings or abbreviations.
2131 * Returns a string in allocated memory or NULL.
2134 getexmodeline(promptc
, cookie
, indent
)
2135 int promptc
; /* normally ':', NUL for ":append" and '?' for
2137 void *cookie UNUSED
;
2138 int indent
; /* indent for inside conditionals */
2144 int escaped
= FALSE
; /* CTRL-V typed */
2149 /* Switch cursor on now. This avoids that it happens after the "\n", which
2150 * confuses the system function that computes tabstops. */
2153 /* always start in column 0; write a newline if necessary */
2155 if ((msg_col
|| msg_didout
) && promptc
!= '?')
2159 /* indent that is only displayed, not in the line itself */
2162 while (indent
-- > 0)
2167 ga_init2(&line_ga
, 1, 30);
2169 /* autoindent for :insert and :append is in the line itself */
2175 ga_append(&line_ga
, TAB
);
2176 msg_puts((char_u
*)" ");
2179 while (indent
-- > 0)
2181 ga_append(&line_ga
, ' ');
2189 * Get the line, one character at a time.
2194 if (ga_grow(&line_ga
, 40) == FAIL
)
2197 /* Get one character at a time. Don't use inchar(), it can't handle
2198 * special characters. */
2203 * Handle line editing.
2204 * Previously this was left to the system, putting the terminal in
2205 * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
2215 /* CR typed means "enter", which is NL */
2219 if (c1
== BS
|| c1
== K_BS
2220 || c1
== DEL
|| c1
== K_DEL
|| c1
== K_KDEL
)
2222 if (line_ga
.ga_len
> 0)
2240 p
= (char_u
*)line_ga
.ga_data
;
2241 p
[line_ga
.ga_len
] = NUL
;
2242 indent
= get_indent_str(p
, 8);
2243 indent
+= curbuf
->b_p_sw
- indent
% curbuf
->b_p_sw
;
2245 while (get_indent_str(p
, 8) < indent
)
2247 char_u
*s
= skipwhite(p
);
2249 ga_grow(&line_ga
, 1);
2250 mch_memmove(s
+ 1, s
, line_ga
.ga_len
- (s
- p
) + 1);
2255 /* redraw the line */
2258 for (p
= (char_u
*)line_ga
.ga_data
;
2259 p
< (char_u
*)line_ga
.ga_data
+ line_ga
.ga_len
; ++p
)
2266 } while (++vcol
% 8);
2270 msg_outtrans_len(p
, 1);
2271 vcol
+= char2cells(*p
);
2275 windgoto(msg_row
, msg_col
);
2281 /* Delete one shiftwidth. */
2282 p
= (char_u
*)line_ga
.ga_data
;
2283 if (prev_char
== '0' || prev_char
== '^')
2285 if (prev_char
== '^')
2286 ex_keep_indent
= TRUE
;
2288 p
[--line_ga
.ga_len
] = NUL
;
2292 p
[line_ga
.ga_len
] = NUL
;
2293 indent
= get_indent_str(p
, 8);
2295 indent
-= indent
% curbuf
->b_p_sw
;
2297 while (get_indent_str(p
, 8) > indent
)
2299 char_u
*s
= skipwhite(p
);
2301 mch_memmove(s
- 1, s
, line_ga
.ga_len
- (s
- p
) + 1);
2307 if (c1
== Ctrl_V
|| c1
== Ctrl_Q
)
2313 /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
2320 ((char_u
*)line_ga
.ga_data
)[line_ga
.ga_len
] = c1
;
2325 /* Don't use chartabsize(), 'ts' can be different */
2329 } while (++vcol
% 8);
2334 ((char_u
*)line_ga
.ga_data
) + line_ga
.ga_len
, 1);
2335 vcol
+= char2cells(c1
);
2340 windgoto(msg_row
, msg_col
);
2341 pend
= (char_u
*)(line_ga
.ga_data
) + line_ga
.ga_len
;
2343 /* we are done when a NL is entered, but not when it comes after a
2345 if (line_ga
.ga_len
> 0 && pend
[-1] == '\n'
2346 && (line_ga
.ga_len
<= 1 || pend
[-2] != '\\'))
2358 /* make following messages go to the next line */
2361 if (msg_row
< Rows
- 1)
2363 emsg_on_display
= FALSE
; /* don't want ui_delay() */
2368 return (char_u
*)line_ga
.ga_data
;
2371 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
2372 || defined(FEAT_MOUSESHAPE) || defined(PROTO)
2374 * Return TRUE if ccline.overstrike is on.
2377 cmdline_overstrike()
2379 return ccline
.overstrike
;
2383 * Return TRUE if the cursor is at the end of the cmdline.
2388 return (ccline
.cmdpos
>= ccline
.cmdlen
);
2392 #if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))) \
2395 * Return the virtual column number at the current cursor position.
2396 * This is used by the IM code to obtain the start of the preedit string.
2399 cmdline_getvcol_cursor()
2401 if (ccline
.cmdbuff
== NULL
|| ccline
.cmdpos
> ccline
.cmdlen
)
2410 for (col
= 0; i
< ccline
.cmdpos
; ++col
)
2411 i
+= (*mb_ptr2len
)(ccline
.cmdbuff
+ i
);
2417 return ccline
.cmdpos
;
2421 #if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
2423 * If part of the command line is an IM preedit string, redraw it with
2424 * IM feedback attributes. The cursor position is restored after drawing.
2429 if ((State
& CMDLINE
)
2430 # ifndef FEAT_GUI_MACVIM
2433 /* && im_get_status() doesn't work when using SCIM */
2435 && im_is_preediting())
2445 cmdspos
= ((ccline
.cmdfirstc
!= NUL
) ? 1 : 0) + ccline
.cmdindent
;
2450 for (col
= 0; col
< preedit_start_col
2451 && cmdpos
< ccline
.cmdlen
; ++col
)
2453 cmdspos
+= (*mb_ptr2cells
)(ccline
.cmdbuff
+ cmdpos
);
2454 cmdpos
+= (*mb_ptr2len
)(ccline
.cmdbuff
+ cmdpos
);
2460 cmdspos
+= preedit_start_col
;
2461 cmdpos
+= preedit_start_col
;
2464 msg_row
= cmdline_row
+ (cmdspos
/ (int)Columns
);
2465 msg_col
= cmdspos
% (int)Columns
;
2466 if (msg_row
>= Rows
)
2469 for (col
= 0; cmdpos
< ccline
.cmdlen
; ++col
)
2474 char_attr
= im_get_feedback_attr(col
);
2476 break; /* end of preedit string */
2480 char_len
= (*mb_ptr2len
)(ccline
.cmdbuff
+ cmdpos
);
2485 msg_outtrans_len_attr(ccline
.cmdbuff
+ cmdpos
, char_len
, char_attr
);
2493 #endif /* FEAT_XIM && (FEAT_GUI_GTK || FEAT_GUI_MACVIM) */
2496 * Allocate a new command line buffer.
2497 * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
2498 * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
2505 * give some extra space to avoid having to allocate all the time
2512 ccline
.cmdbuff
= alloc(len
); /* caller should check for out-of-memory */
2513 ccline
.cmdbufflen
= len
;
2517 * Re-allocate the command line to length len + something extra.
2518 * return FAIL for failure, OK otherwise
2521 realloc_cmdbuff(len
)
2527 alloc_cmdbuff(len
); /* will get some more */
2528 if (ccline
.cmdbuff
== NULL
) /* out of memory */
2530 ccline
.cmdbuff
= p
; /* keep the old one */
2533 mch_memmove(ccline
.cmdbuff
, p
, (size_t)ccline
.cmdlen
+ 1);
2536 if (ccline
.xpc
!= NULL
2537 && ccline
.xpc
->xp_pattern
!= NULL
2538 && ccline
.xpc
->xp_context
!= EXPAND_NOTHING
2539 && ccline
.xpc
->xp_context
!= EXPAND_UNSUCCESSFUL
)
2541 int i
= (int)(ccline
.xpc
->xp_pattern
- p
);
2543 /* If xp_pattern points inside the old cmdbuff it needs to be adjusted
2544 * to point into the newly allocated memory. */
2545 if (i
>= 0 && i
<= ccline
.cmdlen
)
2546 ccline
.xpc
->xp_pattern
= ccline
.cmdbuff
+ i
;
2552 #if defined(FEAT_ARABIC) || defined(PROTO)
2553 static char_u
*arshape_buf
= NULL
;
2555 # if defined(EXITFREE) || defined(PROTO)
2559 vim_free(arshape_buf
);
2565 * Draw part of the cmdline at the current cursor position. But draw stars
2566 * when cmdline_star is TRUE.
2569 draw_cmdline(start
, len
)
2573 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
2576 if (cmdline_star
> 0)
2577 for (i
= 0; i
< len
; ++i
)
2582 i
+= (*mb_ptr2len
)(ccline
.cmdbuff
+ start
+ i
) - 1;
2588 if (p_arshape
&& !p_tbidi
&& enc_utf8
&& len
> 0)
2590 static int buflen
= 0;
2603 * Do arabic shaping into a temporary buffer. This is very
2606 if (len
* 2 + 2 > buflen
)
2608 /* Re-allocate the buffer. We keep it around to avoid a lot of
2609 * alloc()/free() calls. */
2610 vim_free(arshape_buf
);
2611 buflen
= len
* 2 + 2;
2612 arshape_buf
= alloc(buflen
);
2613 if (arshape_buf
== NULL
)
2614 return; /* out of memory */
2617 if (utf_iscomposing(utf_ptr2char(ccline
.cmdbuff
+ start
)))
2619 /* Prepend a space to draw the leading composing char on. */
2620 arshape_buf
[0] = ' ';
2624 for (j
= start
; j
< start
+ len
; j
+= mb_l
)
2626 p
= ccline
.cmdbuff
+ j
;
2627 u8c
= utfc_ptr2char_len(p
, u8cc
, start
+ len
- j
);
2628 mb_l
= utfc_ptr2len_len(p
, start
+ len
- j
);
2629 if (ARABIC_CHAR(u8c
))
2631 /* Do Arabic shaping. */
2634 /* displaying from right to left */
2638 if (j
+ mb_l
>= start
+ len
)
2641 nc
= utf_ptr2char(p
+ mb_l
);
2645 /* displaying from left to right */
2646 if (j
+ mb_l
>= start
+ len
)
2652 pc
= utfc_ptr2char_len(p
+ mb_l
, pcc
,
2653 start
+ len
- j
- mb_l
);
2660 u8c
= arabic_shape(u8c
, NULL
, &u8cc
[0], pc
, pc1
, nc
);
2662 newlen
+= (*mb_char2bytes
)(u8c
, arshape_buf
+ newlen
);
2665 newlen
+= (*mb_char2bytes
)(u8cc
[0], arshape_buf
+ newlen
);
2667 newlen
+= (*mb_char2bytes
)(u8cc
[1],
2668 arshape_buf
+ newlen
);
2674 mch_memmove(arshape_buf
+ newlen
, p
, mb_l
);
2679 msg_outtrans_len(arshape_buf
, newlen
);
2683 msg_outtrans_len(ccline
.cmdbuff
+ start
, len
);
2687 * Put a character on the command line. Shifts the following text to the
2688 * right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc.
2689 * "c" must be printable (fit in one display cell)!
2692 putcmdline(c
, shift
)
2701 draw_cmdline(ccline
.cmdpos
, ccline
.cmdlen
- ccline
.cmdpos
);
2702 msg_no_more
= FALSE
;
2707 * Undo a putcmdline(c, FALSE).
2715 if (ccline
.cmdlen
== ccline
.cmdpos
)
2718 draw_cmdline(ccline
.cmdpos
, 1);
2719 msg_no_more
= FALSE
;
2724 * Put the given string, of the given length, onto the command line.
2725 * If len is -1, then STRLEN() is used to calculate the length.
2726 * If 'redraw' is TRUE then the new part of the command line, and the remaining
2727 * part will be redrawn, otherwise it will not. If this function is called
2728 * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
2729 * called afterwards.
2732 put_on_cmdline(str
, len
, redraw
)
2743 len
= (int)STRLEN(str
);
2745 /* Check if ccline.cmdbuff needs to be longer */
2746 if (ccline
.cmdlen
+ len
+ 1 >= ccline
.cmdbufflen
)
2747 retval
= realloc_cmdbuff(ccline
.cmdlen
+ len
);
2752 if (!ccline
.overstrike
)
2754 mch_memmove(ccline
.cmdbuff
+ ccline
.cmdpos
+ len
,
2755 ccline
.cmdbuff
+ ccline
.cmdpos
,
2756 (size_t)(ccline
.cmdlen
- ccline
.cmdpos
));
2757 ccline
.cmdlen
+= len
;
2764 /* Count nr of characters in the new string. */
2766 for (i
= 0; i
< len
; i
+= (*mb_ptr2len
)(str
+ i
))
2768 /* Count nr of bytes in cmdline that are overwritten by these
2770 for (i
= ccline
.cmdpos
; i
< ccline
.cmdlen
&& m
> 0;
2771 i
+= (*mb_ptr2len
)(ccline
.cmdbuff
+ i
))
2773 if (i
< ccline
.cmdlen
)
2775 mch_memmove(ccline
.cmdbuff
+ ccline
.cmdpos
+ len
,
2776 ccline
.cmdbuff
+ i
, (size_t)(ccline
.cmdlen
- i
));
2777 ccline
.cmdlen
+= ccline
.cmdpos
+ len
- i
;
2780 ccline
.cmdlen
= ccline
.cmdpos
+ len
;
2784 if (ccline
.cmdpos
+ len
> ccline
.cmdlen
)
2785 ccline
.cmdlen
= ccline
.cmdpos
+ len
;
2787 mch_memmove(ccline
.cmdbuff
+ ccline
.cmdpos
, str
, (size_t)len
);
2788 ccline
.cmdbuff
[ccline
.cmdlen
] = NUL
;
2793 /* When the inserted text starts with a composing character,
2794 * backup to the character before it. There could be two of them.
2797 c
= utf_ptr2char(ccline
.cmdbuff
+ ccline
.cmdpos
);
2798 while (ccline
.cmdpos
> 0 && utf_iscomposing(c
))
2800 i
= (*mb_head_off
)(ccline
.cmdbuff
,
2801 ccline
.cmdbuff
+ ccline
.cmdpos
- 1) + 1;
2804 c
= utf_ptr2char(ccline
.cmdbuff
+ ccline
.cmdpos
);
2807 if (i
== 0 && ccline
.cmdpos
> 0 && arabic_maycombine(c
))
2809 /* Check the previous character for Arabic combining pair. */
2810 i
= (*mb_head_off
)(ccline
.cmdbuff
,
2811 ccline
.cmdbuff
+ ccline
.cmdpos
- 1) + 1;
2812 if (arabic_combine(utf_ptr2char(ccline
.cmdbuff
2813 + ccline
.cmdpos
- i
), c
))
2824 /* Also backup the cursor position. */
2825 i
= ptr2cells(ccline
.cmdbuff
+ ccline
.cmdpos
);
2826 ccline
.cmdspos
-= i
;
2837 if (redraw
&& !cmd_silent
)
2841 draw_cmdline(ccline
.cmdpos
, ccline
.cmdlen
- ccline
.cmdpos
);
2842 /* Avoid clearing the rest of the line too often. */
2843 if (cmdline_row
!= i
|| ccline
.overstrike
)
2845 msg_no_more
= FALSE
;
2849 * If we are in Farsi command mode, the character input must be in
2850 * Insert mode. So do not advance the cmdpos.
2858 if (m
< 0) /* overflow, Columns or Rows at weird value */
2863 for (i
= 0; i
< len
; ++i
)
2865 c
= cmdline_charsize(ccline
.cmdpos
);
2867 /* count ">" for a double-wide char that doesn't fit. */
2869 correct_cmdspos(ccline
.cmdpos
, c
);
2871 /* Stop cursor at the end of the screen, but do increment the
2872 * insert position, so that entering a very long command
2873 * works, even though you can't see it. */
2874 if (ccline
.cmdspos
+ c
< m
)
2875 ccline
.cmdspos
+= c
;
2879 c
= (*mb_ptr2len
)(ccline
.cmdbuff
+ ccline
.cmdpos
) - 1;
2880 if (c
> len
- i
- 1)
2895 static struct cmdline_info prev_ccline
;
2896 static int prev_ccline_used
= FALSE
;
2899 * Save ccline, because obtaining the "=" register may execute "normal :cmd"
2900 * and overwrite it. But get_cmdline_str() may need it, thus make it
2901 * available globally in prev_ccline.
2905 struct cmdline_info
*ccp
;
2907 if (!prev_ccline_used
)
2909 vim_memset(&prev_ccline
, 0, sizeof(struct cmdline_info
));
2910 prev_ccline_used
= TRUE
;
2913 prev_ccline
= ccline
;
2914 ccline
.cmdbuff
= NULL
;
2915 ccline
.cmdprompt
= NULL
;
2920 * Restore ccline after it has been saved with save_cmdline().
2923 restore_cmdline(ccp
)
2924 struct cmdline_info
*ccp
;
2926 ccline
= prev_ccline
;
2930 #if defined(FEAT_EVAL) || defined(PROTO)
2932 * Save the command line into allocated memory. Returns a pointer to be
2933 * passed to restore_cmdline_alloc() later.
2934 * Returns NULL when failed.
2937 save_cmdline_alloc()
2939 struct cmdline_info
*p
;
2941 p
= (struct cmdline_info
*)alloc((unsigned)sizeof(struct cmdline_info
));
2948 * Restore the command line from the return value of save_cmdline_alloc().
2951 restore_cmdline_alloc(p
)
2956 restore_cmdline((struct cmdline_info
*)p
);
2963 * paste a yank register into the command line.
2964 * used by CTRL-R command in command-line mode
2965 * insert_reg() can't be used here, because special characters from the
2966 * register contents will be interpreted as commands.
2968 * return FAIL for failure, OK otherwise
2971 cmdline_paste(regname
, literally
, remcr
)
2973 int literally
; /* Insert text literally instead of "as typed" */
2974 int remcr
; /* remove trailing CR */
2980 struct cmdline_info save_ccline
;
2982 /* check for valid regname; also accept special characters for CTRL-R in
2983 * the command line */
2984 if (regname
!= Ctrl_F
&& regname
!= Ctrl_P
&& regname
!= Ctrl_W
2985 && regname
!= Ctrl_A
&& !valid_yank_reg(regname
, FALSE
))
2988 /* A register containing CTRL-R can cause an endless loop. Allow using
2989 * CTRL-C to break the loop. */
2994 #ifdef FEAT_CLIPBOARD
2995 regname
= may_get_selection(regname
);
2998 /* Need to save and restore ccline. And set "textlock" to avoid nasty
2999 * things like going to another buffer when evaluating an expression. */
3000 save_cmdline(&save_ccline
);
3002 i
= get_spec_reg(regname
, &arg
, &allocated
, TRUE
);
3004 restore_cmdline(&save_ccline
);
3008 /* Got the value of a special register in "arg". */
3012 /* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
3013 * part of the word. */
3015 if (p_is
&& regname
== Ctrl_W
)
3020 /* Locate start of last word in the cmd buffer. */
3021 for (w
= ccline
.cmdbuff
+ ccline
.cmdlen
; w
> ccline
.cmdbuff
; )
3026 len
= (*mb_head_off
)(ccline
.cmdbuff
, w
- 1) + 1;
3027 if (!vim_iswordc(mb_ptr2char(w
- len
)))
3034 if (!vim_iswordc(w
[-1]))
3039 len
= (int)((ccline
.cmdbuff
+ ccline
.cmdlen
) - w
);
3040 if (p_ic
? STRNICMP(w
, arg
, len
) == 0 : STRNCMP(w
, arg
, len
) == 0)
3044 cmdline_paste_str(p
, literally
);
3050 return cmdline_paste_reg(regname
, literally
, remcr
);
3054 * Put a string on the command line.
3055 * When "literally" is TRUE, insert literally.
3056 * When "literally" is FALSE, insert as typed, but don't leave the command
3060 cmdline_paste_str(s
, literally
)
3067 put_on_cmdline(s
, -1, TRUE
);
3072 if (cv
== Ctrl_V
&& s
[1])
3076 c
= mb_cptr2char_adv(&s
);
3080 if (cv
== Ctrl_V
|| c
== ESC
|| c
== Ctrl_C
|| c
== CAR
|| c
== NL
3084 || (c
== Ctrl_BSL
&& *s
== Ctrl_N
))
3085 stuffcharReadbuff(Ctrl_V
);
3086 stuffcharReadbuff(c
);
3090 #ifdef FEAT_WILDMENU
3092 * Delete characters on the command line, from "from" to the current
3099 mch_memmove(ccline
.cmdbuff
+ from
, ccline
.cmdbuff
+ ccline
.cmdpos
,
3100 (size_t)(ccline
.cmdlen
- ccline
.cmdpos
+ 1));
3101 ccline
.cmdlen
-= ccline
.cmdpos
- from
;
3102 ccline
.cmdpos
= from
;
3107 * this function is called when the screen size changes and with incremental
3115 need_wait_return
= FALSE
;
3128 if (ccline
.cmdfirstc
!= NUL
)
3129 msg_putchar(ccline
.cmdfirstc
);
3130 if (ccline
.cmdprompt
!= NULL
)
3132 msg_puts_attr(ccline
.cmdprompt
, ccline
.cmdattr
);
3133 ccline
.cmdindent
= msg_col
+ (msg_row
- cmdline_row
) * Columns
;
3134 /* do the reverse of set_cmdspos() */
3135 if (ccline
.cmdfirstc
!= NUL
)
3139 for (i
= ccline
.cmdindent
; i
> 0; --i
)
3144 * Redraw what is currently on the command line.
3152 /* when 'incsearch' is set there may be no command line while redrawing */
3153 if (ccline
.cmdbuff
== NULL
)
3155 windgoto(cmdline_row
, 0);
3163 /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
3165 draw_cmdline(0, ccline
.cmdlen
);
3167 msg_no_more
= FALSE
;
3169 set_cmdspos_cursor();
3172 * An emsg() before may have set msg_scroll. This is used in normal mode,
3173 * in cmdline mode we can reset them now.
3175 msg_scroll
= FALSE
; /* next message overwrites cmdline */
3177 /* Typing ':' at the more prompt may set skip_redraw. We don't want this
3178 * in cmdline mode */
3179 skip_redraw
= FALSE
;
3185 if (exmode_active
|| msg_scrolled
!= 0)
3186 cmdline_row
= Rows
- 1;
3188 cmdline_row
= W_WINROW(lastwin
) + lastwin
->w_height
3189 + W_STATUS_HEIGHT(lastwin
);
3198 #ifdef FEAT_RIGHTLEFT
3201 msg_row
= cmdline_row
+ (ccline
.cmdspos
/ (int)(Columns
- 1));
3202 msg_col
= (int)Columns
- (ccline
.cmdspos
% (int)(Columns
- 1)) - 1;
3209 msg_row
= cmdline_row
+ (ccline
.cmdspos
/ (int)Columns
);
3210 msg_col
= ccline
.cmdspos
% (int)Columns
;
3211 if (msg_row
>= Rows
)
3215 windgoto(msg_row
, msg_col
);
3216 #if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
3217 redrawcmd_preedit();
3219 #ifdef MCH_CURSOR_SHAPE
3220 mch_update_cursor();
3229 #ifdef FEAT_RIGHTLEFT
3231 msg_col
= Columns
- 1;
3234 msg_col
= 0; /* always start in column 0 */
3235 if (clr
) /* clear the bottom line(s) */
3236 msg_clr_eos(); /* will reset clear_cmdline */
3237 windgoto(cmdline_row
, 0);
3241 * Check the word in front of the cursor for an abbreviation.
3242 * Called when the non-id character "c" has been entered.
3243 * When an abbreviation is recognized it is removed from the text with
3244 * backspaces and the replacement string is inserted, followed by "c".
3250 if (p_paste
|| no_abbr
) /* no abbreviations or in paste mode */
3253 return check_abbr(c
, ccline
.cmdbuff
, ccline
.cmdpos
, 0);
3257 * Return FAIL if this is not an appropriate context in which to do
3258 * completion of anything, return OK if it is (even if there are no matches).
3259 * For the caller, this means that the character is just passed through like a
3260 * normal character (instead of being expanded). This allows :s/^I^D etc.
3263 nextwild(xp
, type
, options
)
3266 int options
; /* extra options for ExpandOne() */
3274 if (xp
->xp_numfiles
== -1)
3276 set_expand_context(xp
);
3277 cmd_showtail
= expand_showtail(xp
);
3280 if (xp
->xp_context
== EXPAND_UNSUCCESSFUL
)
3283 return OK
; /* Something illegal on command line */
3285 if (xp
->xp_context
== EXPAND_NOTHING
)
3287 /* Caller can use the character as a normal char instead */
3291 MSG_PUTS("..."); /* show that we are busy */
3294 i
= (int)(xp
->xp_pattern
- ccline
.cmdbuff
);
3295 xp
->xp_pattern_len
= ccline
.cmdpos
- i
;
3297 if (type
== WILD_NEXT
|| type
== WILD_PREV
)
3300 * Get next/previous match for a previous expanded pattern.
3302 p2
= ExpandOne(xp
, NULL
, NULL
, 0, type
);
3307 * Translate string into pattern and expand it.
3309 if ((p1
= addstar(xp
->xp_pattern
, xp
->xp_pattern_len
,
3310 xp
->xp_context
)) == NULL
)
3314 p2
= ExpandOne(xp
, p1
,
3315 vim_strnsave(&ccline
.cmdbuff
[i
], xp
->xp_pattern_len
),
3316 WILD_HOME_REPLACE
|WILD_ADD_SLASH
|WILD_SILENT
|WILD_ESCAPE
3319 /* longest match: make sure it is not shorter, happens with :help */
3320 if (p2
!= NULL
&& type
== WILD_LONGEST
)
3322 for (j
= 0; j
< xp
->xp_pattern_len
; ++j
)
3323 if (ccline
.cmdbuff
[i
+ j
] == '*'
3324 || ccline
.cmdbuff
[i
+ j
] == '?')
3326 if ((int)STRLEN(p2
) < j
)
3335 if (p2
!= NULL
&& !got_int
)
3337 difflen
= (int)STRLEN(p2
) - xp
->xp_pattern_len
;
3338 if (ccline
.cmdlen
+ difflen
> ccline
.cmdbufflen
- 4)
3340 v
= realloc_cmdbuff(ccline
.cmdlen
+ difflen
);
3341 xp
->xp_pattern
= ccline
.cmdbuff
+ i
;
3347 mch_memmove(&ccline
.cmdbuff
[ccline
.cmdpos
+ difflen
],
3348 &ccline
.cmdbuff
[ccline
.cmdpos
],
3349 (size_t)(ccline
.cmdlen
- ccline
.cmdpos
+ 1));
3350 mch_memmove(&ccline
.cmdbuff
[i
], p2
, STRLEN(p2
));
3351 ccline
.cmdlen
+= difflen
;
3352 ccline
.cmdpos
+= difflen
;
3360 /* When expanding a ":map" command and no matches are found, assume that
3361 * the key is supposed to be inserted literally */
3362 if (xp
->xp_context
== EXPAND_MAPPINGS
&& p2
== NULL
)
3365 if (xp
->xp_numfiles
<= 0 && p2
== NULL
)
3367 else if (xp
->xp_numfiles
== 1)
3368 /* free expanded pattern */
3369 (void)ExpandOne(xp
, NULL
, NULL
, 0, WILD_FREE
);
3375 * Do wildcard expansion on the string 'str'.
3376 * Chars that should not be expanded must be preceded with a backslash.
3377 * Return a pointer to allocated memory containing the new string.
3378 * Return NULL for failure.
3380 * "orig" is the originally expanded string, copied to allocated memory. It
3381 * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
3382 * WILD_PREV "orig" should be NULL.
3384 * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
3385 * is WILD_EXPAND_FREE or WILD_ALL.
3387 * mode = WILD_FREE: just free previously expanded matches
3388 * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
3389 * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
3390 * mode = WILD_NEXT: use next match in multiple match, wrap to first
3391 * mode = WILD_PREV: use previous match in multiple match, wrap to first
3392 * mode = WILD_ALL: return all matches concatenated
3393 * mode = WILD_LONGEST: return longest matched part
3395 * options = WILD_LIST_NOTFOUND: list entries without a match
3396 * options = WILD_HOME_REPLACE: do home_replace() for buffer names
3397 * options = WILD_USE_NL: Use '\n' for WILD_ALL
3398 * options = WILD_NO_BEEP: Don't beep for multiple matches
3399 * options = WILD_ADD_SLASH: add a slash after directory names
3400 * options = WILD_KEEP_ALL: don't remove 'wildignore' entries
3401 * options = WILD_SILENT: don't print warning messages
3402 * options = WILD_ESCAPE: put backslash before special chars
3404 * The variables xp->xp_context and xp->xp_backslash must have been set!
3407 ExpandOne(xp
, str
, orig
, options
, mode
)
3410 char_u
*orig
; /* allocated copy of original of expanded string */
3416 static char_u
*orig_save
= NULL
; /* kept value of orig */
3417 int orig_saved
= FALSE
;
3420 int non_suf_match
; /* number without matching suffix */
3423 * first handle the case of using an old match
3425 if (mode
== WILD_NEXT
|| mode
== WILD_PREV
)
3427 if (xp
->xp_numfiles
> 0)
3429 if (mode
== WILD_PREV
)
3432 findex
= xp
->xp_numfiles
;
3435 else /* mode == WILD_NEXT */
3439 * When wrapping around, return the original string, set findex to
3444 if (orig_save
== NULL
)
3445 findex
= xp
->xp_numfiles
- 1;
3449 if (findex
>= xp
->xp_numfiles
)
3451 if (orig_save
== NULL
)
3456 #ifdef FEAT_WILDMENU
3458 win_redr_status_matches(xp
, xp
->xp_numfiles
, xp
->xp_files
,
3459 findex
, cmd_showtail
);
3462 return vim_strsave(orig_save
);
3463 return vim_strsave(xp
->xp_files
[findex
]);
3469 /* free old names */
3470 if (xp
->xp_numfiles
!= -1 && mode
!= WILD_ALL
&& mode
!= WILD_LONGEST
)
3472 FreeWild(xp
->xp_numfiles
, xp
->xp_files
);
3473 xp
->xp_numfiles
= -1;
3474 vim_free(orig_save
);
3479 if (mode
== WILD_FREE
) /* only release file name */
3482 if (xp
->xp_numfiles
== -1)
3484 vim_free(orig_save
);
3491 if (ExpandFromContext(xp
, str
, &xp
->xp_numfiles
, &xp
->xp_files
,
3494 #ifdef FNAME_ILLEGAL
3495 /* Illegal file name has been silently skipped. But when there
3496 * are wildcards, the real problem is that there was no match,
3497 * causing the pattern to be added, which has illegal characters.
3499 if (!(options
& WILD_SILENT
) && (options
& WILD_LIST_NOTFOUND
))
3500 EMSG2(_(e_nomatch2
), str
);
3503 else if (xp
->xp_numfiles
== 0)
3505 if (!(options
& WILD_SILENT
))
3506 EMSG2(_(e_nomatch2
), str
);
3510 /* Escape the matches for use on the command line. */
3511 ExpandEscape(xp
, str
, xp
->xp_numfiles
, xp
->xp_files
, options
);
3514 * Check for matching suffixes in file names.
3516 if (mode
!= WILD_ALL
&& mode
!= WILD_LONGEST
)
3518 if (xp
->xp_numfiles
)
3519 non_suf_match
= xp
->xp_numfiles
;
3522 if ((xp
->xp_context
== EXPAND_FILES
3523 || xp
->xp_context
== EXPAND_DIRECTORIES
)
3524 && xp
->xp_numfiles
> 1)
3527 * More than one match; check suffix.
3528 * The files will have been sorted on matching suffix in
3529 * expand_wildcards, only need to check the first two.
3532 for (i
= 0; i
< 2; ++i
)
3533 if (match_suffix(xp
->xp_files
[i
]))
3536 if (non_suf_match
!= 1)
3538 /* Can we ever get here unless it's while expanding
3539 * interactively? If not, we can get rid of this all
3540 * together. Don't really want to wait for this message
3541 * (and possibly have to hit return to continue!).
3543 if (!(options
& WILD_SILENT
))
3545 else if (!(options
& WILD_NO_BEEP
))
3548 if (!(non_suf_match
!= 1 && mode
== WILD_EXPAND_FREE
))
3549 ss
= vim_strsave(xp
->xp_files
[0]);
3554 /* Find longest common part */
3555 if (mode
== WILD_LONGEST
&& xp
->xp_numfiles
> 0)
3557 for (len
= 0; xp
->xp_files
[0][len
]; ++len
)
3559 for (i
= 0; i
< xp
->xp_numfiles
; ++i
)
3561 #ifdef CASE_INSENSITIVE_FILENAME
3562 if (xp
->xp_context
== EXPAND_DIRECTORIES
3563 || xp
->xp_context
== EXPAND_FILES
3564 || xp
->xp_context
== EXPAND_SHELLCMD
3565 || xp
->xp_context
== EXPAND_BUFFERS
)
3567 if (TOLOWER_LOC(xp
->xp_files
[i
][len
]) !=
3568 TOLOWER_LOC(xp
->xp_files
[0][len
]))
3573 if (xp
->xp_files
[i
][len
] != xp
->xp_files
[0][len
])
3576 if (i
< xp
->xp_numfiles
)
3578 if (!(options
& WILD_NO_BEEP
))
3583 ss
= alloc((unsigned)len
+ 1);
3585 vim_strncpy(ss
, xp
->xp_files
[0], (size_t)len
);
3586 findex
= -1; /* next p_wc gets first one */
3589 /* Concatenate all matching names */
3590 if (mode
== WILD_ALL
&& xp
->xp_numfiles
> 0)
3593 for (i
= 0; i
< xp
->xp_numfiles
; ++i
)
3594 len
+= (long_u
)STRLEN(xp
->xp_files
[i
]) + 1;
3595 ss
= lalloc(len
, TRUE
);
3599 for (i
= 0; i
< xp
->xp_numfiles
; ++i
)
3601 STRCAT(ss
, xp
->xp_files
[i
]);
3602 if (i
!= xp
->xp_numfiles
- 1)
3603 STRCAT(ss
, (options
& WILD_USE_NL
) ? "\n" : " ");
3608 if (mode
== WILD_EXPAND_FREE
|| mode
== WILD_ALL
)
3611 /* Free "orig" if it wasn't stored in "orig_save". */
3619 * Prepare an expand structure for use.
3625 xp
->xp_pattern
= NULL
;
3626 xp
->xp_pattern_len
= 0;
3627 xp
->xp_backslash
= XP_BS_NONE
;
3628 #ifndef BACKSLASH_IN_FILENAME
3629 xp
->xp_shell
= FALSE
;
3631 xp
->xp_numfiles
= -1;
3632 xp
->xp_files
= NULL
;
3633 #if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
3639 * Cleanup an expand structure after use.
3645 if (xp
->xp_numfiles
>= 0)
3647 FreeWild(xp
->xp_numfiles
, xp
->xp_files
);
3648 xp
->xp_numfiles
= -1;
3653 ExpandEscape(xp
, str
, numfiles
, files
, options
)
3664 * May change home directory back to "~"
3666 if (options
& WILD_HOME_REPLACE
)
3667 tilde_replace(str
, numfiles
, files
);
3669 if (options
& WILD_ESCAPE
)
3671 if (xp
->xp_context
== EXPAND_FILES
3672 || xp
->xp_context
== EXPAND_SHELLCMD
3673 || xp
->xp_context
== EXPAND_BUFFERS
3674 || xp
->xp_context
== EXPAND_DIRECTORIES
)
3677 * Insert a backslash into a file name before a space, \, %, #
3678 * and wildmatch characters, except '~'.
3680 for (i
= 0; i
< numfiles
; ++i
)
3682 /* for ":set path=" we need to escape spaces twice */
3683 if (xp
->xp_backslash
== XP_BS_THREE
)
3685 p
= vim_strsave_escaped(files
[i
], (char_u
*)" ");
3690 #if defined(BACKSLASH_IN_FILENAME)
3691 p
= vim_strsave_escaped(files
[i
], (char_u
*)" ");
3700 #ifdef BACKSLASH_IN_FILENAME
3701 p
= vim_strsave_fnameescape(files
[i
], FALSE
);
3703 p
= vim_strsave_fnameescape(files
[i
], xp
->xp_shell
);
3711 /* If 'str' starts with "\~", replace "~" at start of
3712 * files[i] with "\~". */
3713 if (str
[0] == '\\' && str
[1] == '~' && files
[i
][0] == '~')
3714 escape_fname(&files
[i
]);
3716 xp
->xp_backslash
= XP_BS_NONE
;
3718 /* If the first file starts with a '+' escape it. Otherwise it
3719 * could be seen as "+cmd". */
3720 if (*files
[0] == '+')
3721 escape_fname(&files
[0]);
3723 else if (xp
->xp_context
== EXPAND_TAGS
)
3726 * Insert a backslash before characters in a tag name that
3727 * would terminate the ":tag" command.
3729 for (i
= 0; i
< numfiles
; ++i
)
3731 p
= vim_strsave_escaped(files
[i
], (char_u
*)"\\|\"");
3743 * Escape special characters in "fname" for when used as a file name argument
3744 * after a Vim command, or, when "shell" is non-zero, a shell command.
3745 * Returns the result in allocated memory.
3748 vim_strsave_fnameescape(fname
, shell
)
3753 #ifdef BACKSLASH_IN_FILENAME
3757 /* Don't escape '[' and '{' if they are in 'isfname'. */
3758 for (p
= PATH_ESC_CHARS
; *p
!= NUL
; ++p
)
3759 if ((*p
!= '[' && *p
!= '{') || !vim_isfilec(*p
))
3762 p
= vim_strsave_escaped(fname
, buf
);
3764 p
= vim_strsave_escaped(fname
, shell
? SHELL_ESC_CHARS
: PATH_ESC_CHARS
);
3765 if (shell
&& csh_like_shell() && p
!= NULL
)
3769 /* For csh and similar shells need to put two backslashes before '!'.
3770 * One is taken by Vim, one by the shell. */
3771 s
= vim_strsave_escaped(p
, (char_u
*)"!");
3777 /* '>' and '+' are special at the start of some commands, e.g. ":edit" and
3778 * ":write". "cd -" has a special meaning. */
3779 if (*p
== '>' || *p
== '+' || (*p
== '-' && p
[1] == NUL
))
3786 * Put a backslash before the file name in "pp", which is in allocated memory.
3794 p
= alloc((unsigned)(STRLEN(*pp
) + 2));
3805 * For each file name in files[num_files]:
3806 * If 'orig_pat' starts with "~/", replace the home directory with "~".
3809 tilde_replace(orig_pat
, num_files
, files
)
3817 if (orig_pat
[0] == '~' && vim_ispathsep(orig_pat
[1]))
3819 for (i
= 0; i
< num_files
; ++i
)
3821 p
= home_replace_save(NULL
, files
[i
]);
3832 * Show all matches for completion on the command line.
3833 * Returns EXPAND_NOTHING when the character that triggered expansion should
3834 * be inserted like a normal character.
3837 showmatches(xp
, wildmenu
)
3839 int wildmenu UNUSED
;
3841 #define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
3843 char_u
**files_found
;
3853 if (xp
->xp_numfiles
== -1)
3855 set_expand_context(xp
);
3856 i
= expand_cmdline(xp
, ccline
.cmdbuff
, ccline
.cmdpos
,
3857 &num_files
, &files_found
);
3858 showtail
= expand_showtail(xp
);
3865 num_files
= xp
->xp_numfiles
;
3866 files_found
= xp
->xp_files
;
3867 showtail
= cmd_showtail
;
3870 #ifdef FEAT_WILDMENU
3874 msg_didany
= FALSE
; /* lines_left will be set */
3875 msg_start(); /* prepare for paging */
3878 cmdline_row
= msg_row
;
3879 msg_didany
= FALSE
; /* lines_left will be set again */
3880 msg_start(); /* prepare for paging */
3881 #ifdef FEAT_WILDMENU
3886 got_int
= FALSE
; /* only int. the completion, not the cmd line */
3887 #ifdef FEAT_WILDMENU
3889 win_redr_status_matches(xp
, num_files
, files_found
, 0, showtail
);
3893 /* find the length of the longest file name */
3895 for (i
= 0; i
< num_files
; ++i
)
3897 if (!showtail
&& (xp
->xp_context
== EXPAND_FILES
3898 || xp
->xp_context
== EXPAND_SHELLCMD
3899 || xp
->xp_context
== EXPAND_BUFFERS
))
3901 home_replace(NULL
, files_found
[i
], NameBuff
, MAXPATHL
, TRUE
);
3902 j
= vim_strsize(NameBuff
);
3905 j
= vim_strsize(L_SHOWFILE(i
));
3910 if (xp
->xp_context
== EXPAND_TAGS_LISTFILES
)
3914 /* compute the number of columns and lines for the listing */
3915 maxlen
+= 2; /* two spaces between file names */
3916 columns
= ((int)Columns
+ 2) / maxlen
;
3919 lines
= (num_files
+ columns
- 1) / columns
;
3922 attr
= hl_attr(HLF_D
); /* find out highlighting for directories */
3924 if (xp
->xp_context
== EXPAND_TAGS_LISTFILES
)
3926 MSG_PUTS_ATTR(_("tagname"), hl_attr(HLF_T
));
3928 msg_advance(maxlen
- 3);
3929 MSG_PUTS_ATTR(_(" kind file\n"), hl_attr(HLF_T
));
3932 /* list the files line by line */
3933 for (i
= 0; i
< lines
; ++i
)
3936 for (k
= i
; k
< num_files
; k
+= lines
)
3938 if (xp
->xp_context
== EXPAND_TAGS_LISTFILES
)
3940 msg_outtrans_attr(files_found
[k
], hl_attr(HLF_D
));
3941 p
= files_found
[k
] + STRLEN(files_found
[k
]) + 1;
3942 msg_advance(maxlen
+ 1);
3944 msg_advance(maxlen
+ 3);
3945 msg_puts_long_attr(p
+ 2, hl_attr(HLF_D
));
3948 for (j
= maxlen
- lastlen
; --j
>= 0; )
3950 if (xp
->xp_context
== EXPAND_FILES
3951 || xp
->xp_context
== EXPAND_SHELLCMD
3952 || xp
->xp_context
== EXPAND_BUFFERS
)
3954 /* highlight directories */
3955 j
= (mch_isdir(files_found
[k
]));
3960 home_replace(NULL
, files_found
[k
], NameBuff
, MAXPATHL
,
3970 lastlen
= msg_outtrans_attr(p
, j
? attr
: 0);
3972 if (msg_col
> 0) /* when not wrapped around */
3977 out_flush(); /* show one line at a time */
3986 * we redraw the command below the lines that we have just listed
3987 * This is a bit tricky, but it saves a lot of screen updating.
3989 cmdline_row
= msg_row
; /* will put it back later */
3992 if (xp
->xp_numfiles
== -1)
3993 FreeWild(num_files
, files_found
);
3999 * Private gettail for showmatches() (and win_redr_status_matches()):
4000 * Find tail of file name path, but ignore trailing "/".
4008 int had_sep
= FALSE
;
4010 for (p
= s
; *p
!= NUL
; )
4012 if (vim_ispathsep(*p
)
4013 #ifdef BACKSLASH_IN_FILENAME
4014 && !rem_backslash(p
)
4029 * Return TRUE if we only need to show the tail of completion matches.
4030 * When not completing file names or there is a wildcard in the path FALSE is
4040 /* When not completing file names a "/" may mean something different. */
4041 if (xp
->xp_context
!= EXPAND_FILES
4042 && xp
->xp_context
!= EXPAND_SHELLCMD
4043 && xp
->xp_context
!= EXPAND_DIRECTORIES
)
4046 end
= gettail(xp
->xp_pattern
);
4047 if (end
== xp
->xp_pattern
) /* there is no path separator */
4050 for (s
= xp
->xp_pattern
; s
< end
; s
++)
4052 /* Skip escaped wildcards. Only when the backslash is not a path
4053 * separator, on DOS the '*' "path\*\file" must not be skipped. */
4054 if (rem_backslash(s
))
4056 else if (vim_strchr((char_u
*)"*?[", *s
) != NULL
)
4063 * Prepare a string for expansion.
4064 * When expanding file names: The string will be used with expand_wildcards().
4065 * Copy the file name into allocated memory and add a '*' at the end.
4066 * When expanding other names: The string will be used with regcomp(). Copy
4067 * the name into allocated memory and prepend "^".
4070 addstar(fname
, len
, context
)
4073 int context
; /* EXPAND_FILES etc. */
4080 if (context
!= EXPAND_FILES
4081 && context
!= EXPAND_SHELLCMD
4082 && context
!= EXPAND_DIRECTORIES
)
4085 * Matching will be done internally (on something other than files).
4086 * So we convert the file-matching-type wildcards into our kind for
4087 * use with vim_regcomp(). First work out how long it will be:
4090 /* For help tags the translation is done in find_help_tags().
4091 * For a tag pattern starting with "/" no translation is needed. */
4092 if (context
== EXPAND_HELP
4093 || context
== EXPAND_COLORS
4094 || context
== EXPAND_COMPILER
4095 || (context
== EXPAND_TAGS
&& fname
[0] == '/'))
4096 retval
= vim_strnsave(fname
, len
);
4099 new_len
= len
+ 2; /* +2 for '^' at start, NUL at end */
4100 for (i
= 0; i
< len
; i
++)
4102 if (fname
[i
] == '*' || fname
[i
] == '~')
4103 new_len
++; /* '*' needs to be replaced by ".*"
4104 '~' needs to be replaced by "\~" */
4106 /* Buffer names are like file names. "." should be literal */
4107 if (context
== EXPAND_BUFFERS
&& fname
[i
] == '.')
4108 new_len
++; /* "." becomes "\." */
4110 /* Custom expansion takes care of special things, match
4111 * backslashes literally (perhaps also for other types?) */
4112 if ((context
== EXPAND_USER_DEFINED
4113 || context
== EXPAND_USER_LIST
) && fname
[i
] == '\\')
4114 new_len
++; /* '\' becomes "\\" */
4116 retval
= alloc(new_len
);
4121 for (i
= 0; i
< len
; i
++, j
++)
4123 /* Skip backslash. But why? At least keep it for custom
4125 if (context
!= EXPAND_USER_DEFINED
4126 && context
!= EXPAND_USER_LIST
4133 case '*': retval
[j
++] = '.';
4135 case '~': retval
[j
++] = '\\';
4137 case '?': retval
[j
] = '.';
4139 case '.': if (context
== EXPAND_BUFFERS
)
4142 case '\\': if (context
== EXPAND_USER_DEFINED
4143 || context
== EXPAND_USER_LIST
)
4147 retval
[j
] = fname
[i
];
4155 retval
= alloc(len
+ 4);
4158 vim_strncpy(retval
, fname
, len
);
4161 * Don't add a star to *, ~, ~user, $var or `cmd`.
4162 * * would become **, which walks the whole tree.
4163 * ~ would be at the start of the file name, but not the tail.
4164 * $ could be anywhere in the tail.
4165 * ` could be anywhere in the file name.
4166 * When the name ends in '$' don't add a star, remove the '$'.
4168 tail
= gettail(retval
);
4169 if ((*retval
!= '~' || tail
!= retval
)
4170 && (len
== 0 || retval
[len
- 1] != '*')
4171 && vim_strchr(tail
, '$') == NULL
4172 && vim_strchr(retval
, '`') == NULL
)
4173 retval
[len
++] = '*';
4174 else if (len
> 0 && retval
[len
- 1] == '$')
4183 * Must parse the command line so far to work out what context we are in.
4184 * Completion can then be done based on that context.
4185 * This routine sets the variables:
4186 * xp->xp_pattern The start of the pattern to be expanded within
4187 * the command line (ends at the cursor).
4188 * xp->xp_context The type of thing to expand. Will be one of:
4190 * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on
4191 * the command line, like an unknown command. Caller
4193 * EXPAND_NOTHING Unrecognised context for completion, use char like
4194 * a normal char, rather than for completion. eg
4196 * EXPAND_COMMANDS Cursor is still touching the command, so complete
4198 * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands.
4199 * EXPAND_FILES After command with XFILE set, or after setting
4200 * with P_EXPAND set. eg :e ^I, :w>>^I
4201 * EXPAND_DIRECTORIES In some cases this is used instead of the latter
4202 * when we know only directories are of interest. eg
4204 * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd".
4205 * EXPAND_SETTINGS Complete variable names. eg :set d^I
4206 * EXPAND_BOOL_SETTINGS Complete boolean variables only, eg :set no^I
4207 * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I
4208 * EXPAND_TAGS_LISTFILES As above, but list filenames on ^D, after :tselect
4209 * EXPAND_HELP Complete tags from the file 'helpfile'/tags
4210 * EXPAND_EVENTS Complete event names
4211 * EXPAND_SYNTAX Complete :syntax command arguments
4212 * EXPAND_HIGHLIGHT Complete highlight (syntax) group names
4213 * EXPAND_AUGROUP Complete autocommand group names
4214 * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I
4215 * EXPAND_MAPPINGS Complete mapping and abbreviation names,
4216 * eg :unmap a^I , :cunab x^I
4217 * EXPAND_FUNCTIONS Complete internal or user defined function names,
4219 * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I
4220 * EXPAND_EXPRESSION Complete internal or user defined function/variable
4221 * names in expressions, eg :while s^I
4222 * EXPAND_ENV_VARS Complete environment variable names
4225 set_expand_context(xp
)
4228 /* only expansion for ':', '>' and '=' command-lines */
4229 if (ccline
.cmdfirstc
!= ':'
4231 && ccline
.cmdfirstc
!= '>' && ccline
.cmdfirstc
!= '='
4236 xp
->xp_context
= EXPAND_NOTHING
;
4239 set_cmd_context(xp
, ccline
.cmdbuff
, ccline
.cmdlen
, ccline
.cmdpos
);
4243 set_cmd_context(xp
, str
, len
, col
)
4245 char_u
*str
; /* start of command line */
4246 int len
; /* length of command line (excl. NUL) */
4247 int col
; /* position of cursor */
4253 * Avoid a UMR warning from Purify, only save the character if it has been
4257 old_char
= str
[col
];
4262 if (ccline
.cmdfirstc
== '=')
4264 # ifdef FEAT_CMDL_COMPL
4265 /* pass CMD_SIZE because there is no real command */
4266 set_context_for_expression(xp
, str
, CMD_SIZE
);
4269 else if (ccline
.input_fn
)
4271 xp
->xp_context
= ccline
.xp_context
;
4272 xp
->xp_pattern
= ccline
.cmdbuff
;
4273 # if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
4274 xp
->xp_arg
= ccline
.xp_arg
;
4279 while (nextcomm
!= NULL
)
4280 nextcomm
= set_one_cmd_context(xp
, nextcomm
);
4282 str
[col
] = old_char
;
4286 * Expand the command line "str" from context "xp".
4287 * "xp" must have been set by set_cmd_context().
4288 * xp->xp_pattern points into "str", to where the text that is to be expanded
4290 * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
4292 * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
4293 * key that triggered expansion literally.
4294 * Returns EXPAND_OK otherwise.
4297 expand_cmdline(xp
, str
, col
, matchcount
, matches
)
4299 char_u
*str
; /* start of command line */
4300 int col
; /* position of cursor */
4301 int *matchcount
; /* return: nr of matches */
4302 char_u
***matches
; /* return: array of pointers to matches */
4304 char_u
*file_str
= NULL
;
4306 if (xp
->xp_context
== EXPAND_UNSUCCESSFUL
)
4309 return EXPAND_UNSUCCESSFUL
; /* Something illegal on command line */
4311 if (xp
->xp_context
== EXPAND_NOTHING
)
4313 /* Caller can use the character as a normal char instead */
4314 return EXPAND_NOTHING
;
4317 /* add star to file name, or convert to regexp if not exp. files. */
4318 xp
->xp_pattern_len
= (int)(str
+ col
- xp
->xp_pattern
);
4319 file_str
= addstar(xp
->xp_pattern
, xp
->xp_pattern_len
, xp
->xp_context
);
4320 if (file_str
== NULL
)
4321 return EXPAND_UNSUCCESSFUL
;
4323 /* find all files that match the description */
4324 if (ExpandFromContext(xp
, file_str
, matchcount
, matches
,
4325 WILD_ADD_SLASH
|WILD_SILENT
) == FAIL
)
4335 #ifdef FEAT_MULTI_LANG
4337 * Cleanup matches for help tags: remove "@en" if "en" is the only language.
4339 static void cleanup_help_tags
__ARGS((int num_file
, char_u
**file
));
4342 cleanup_help_tags(num_file
, file
)
4349 for (i
= 0; i
< num_file
; ++i
)
4351 len
= (int)STRLEN(file
[i
]) - 3;
4352 if (len
> 0 && STRCMP(file
[i
] + len
, "@en") == 0)
4354 /* Sorting on priority means the same item in another language may
4355 * be anywhere. Search all items for a match up to the "@en". */
4356 for (j
= 0; j
< num_file
; ++j
)
4358 && (int)STRLEN(file
[j
]) == len
+ 3
4359 && STRNCMP(file
[i
], file
[j
], len
+ 1) == 0)
4369 * Do the expansion based on xp->xp_context and "pat".
4372 ExpandFromContext(xp
, pat
, num_file
, file
, options
)
4379 #ifdef FEAT_CMDL_COMPL
4380 regmatch_T regmatch
;
4385 flags
= EW_DIR
; /* include directories */
4386 if (options
& WILD_LIST_NOTFOUND
)
4387 flags
|= EW_NOTFOUND
;
4388 if (options
& WILD_ADD_SLASH
)
4389 flags
|= EW_ADDSLASH
;
4390 if (options
& WILD_KEEP_ALL
)
4391 flags
|= EW_KEEPALL
;
4392 if (options
& WILD_SILENT
)
4395 if (xp
->xp_context
== EXPAND_FILES
|| xp
->xp_context
== EXPAND_DIRECTORIES
)
4398 * Expand file or directory names.
4400 int free_pat
= FALSE
;
4403 /* for ":set path=" and ":set tags=" halve backslashes for escaped
4405 if (xp
->xp_backslash
!= XP_BS_NONE
)
4408 pat
= vim_strsave(pat
);
4409 for (i
= 0; pat
[i
]; ++i
)
4412 if (xp
->xp_backslash
== XP_BS_THREE
4413 && pat
[i
+ 1] == '\\'
4414 && pat
[i
+ 2] == '\\'
4415 && pat
[i
+ 3] == ' ')
4416 STRMOVE(pat
+ i
, pat
+ i
+ 3);
4417 if (xp
->xp_backslash
== XP_BS_ONE
4418 && pat
[i
+ 1] == ' ')
4419 STRMOVE(pat
+ i
, pat
+ i
+ 1);
4423 if (xp
->xp_context
== EXPAND_FILES
)
4426 flags
= (flags
| EW_DIR
) & ~EW_FILE
;
4427 /* Expand wildcards, supporting %:h and the like. */
4428 ret
= expand_wildcards_eval(&pat
, num_file
, file
, flags
);
4434 *file
= (char_u
**)"";
4436 if (xp
->xp_context
== EXPAND_HELP
)
4438 /* With an empty argument we would get all the help tags, which is
4439 * very slow. Get matches for "help" instead. */
4440 if (find_help_tags(*pat
== NUL
? (char_u
*)"help" : pat
,
4441 num_file
, file
, FALSE
) == OK
)
4443 #ifdef FEAT_MULTI_LANG
4444 cleanup_help_tags(*num_file
, *file
);
4451 #ifndef FEAT_CMDL_COMPL
4454 if (xp
->xp_context
== EXPAND_SHELLCMD
)
4455 return expand_shellcmd(pat
, num_file
, file
, flags
);
4456 if (xp
->xp_context
== EXPAND_OLD_SETTING
)
4457 return ExpandOldSetting(num_file
, file
);
4458 if (xp
->xp_context
== EXPAND_BUFFERS
)
4459 return ExpandBufnames(pat
, num_file
, file
, options
);
4460 if (xp
->xp_context
== EXPAND_TAGS
4461 || xp
->xp_context
== EXPAND_TAGS_LISTFILES
)
4462 return expand_tags(xp
->xp_context
== EXPAND_TAGS
, pat
, num_file
, file
);
4463 if (xp
->xp_context
== EXPAND_COLORS
)
4464 return ExpandRTDir(pat
, num_file
, file
, "colors");
4465 if (xp
->xp_context
== EXPAND_COMPILER
)
4466 return ExpandRTDir(pat
, num_file
, file
, "compiler");
4467 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
4468 if (xp
->xp_context
== EXPAND_USER_LIST
)
4469 return ExpandUserList(xp
, num_file
, file
);
4472 regmatch
.regprog
= vim_regcomp(pat
, p_magic
? RE_MAGIC
: 0);
4473 if (regmatch
.regprog
== NULL
)
4476 /* set ignore-case according to p_ic, p_scs and pat */
4477 regmatch
.rm_ic
= ignorecase(pat
);
4479 if (xp
->xp_context
== EXPAND_SETTINGS
4480 || xp
->xp_context
== EXPAND_BOOL_SETTINGS
)
4481 ret
= ExpandSettings(xp
, ®match
, num_file
, file
);
4482 else if (xp
->xp_context
== EXPAND_MAPPINGS
)
4483 ret
= ExpandMappings(®match
, num_file
, file
);
4484 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
4485 else if (xp
->xp_context
== EXPAND_USER_DEFINED
)
4486 ret
= ExpandUserDefined(xp
, ®match
, num_file
, file
);
4490 static struct expgen
4493 char_u
*((*func
)__ARGS((expand_T
*, int)));
4497 {EXPAND_COMMANDS
, get_command_name
, FALSE
},
4498 #ifdef FEAT_USR_CMDS
4499 {EXPAND_USER_COMMANDS
, get_user_commands
, FALSE
},
4500 {EXPAND_USER_CMD_FLAGS
, get_user_cmd_flags
, FALSE
},
4501 {EXPAND_USER_NARGS
, get_user_cmd_nargs
, FALSE
},
4502 {EXPAND_USER_COMPLETE
, get_user_cmd_complete
, FALSE
},
4505 {EXPAND_USER_VARS
, get_user_var_name
, FALSE
},
4506 {EXPAND_FUNCTIONS
, get_function_name
, FALSE
},
4507 {EXPAND_USER_FUNC
, get_user_func_name
, FALSE
},
4508 {EXPAND_EXPRESSION
, get_expr_name
, FALSE
},
4511 {EXPAND_MENUS
, get_menu_name
, FALSE
},
4512 {EXPAND_MENUNAMES
, get_menu_names
, FALSE
},
4515 {EXPAND_SYNTAX
, get_syntax_name
, TRUE
},
4517 {EXPAND_HIGHLIGHT
, get_highlight_name
, TRUE
},
4519 {EXPAND_EVENTS
, get_event_name
, TRUE
},
4520 {EXPAND_AUGROUP
, get_augroup_name
, TRUE
},
4523 {EXPAND_CSCOPE
, get_cscope_name
, TRUE
},
4526 {EXPAND_SIGN
, get_sign_name
, TRUE
},
4529 {EXPAND_PROFILE
, get_profile_name
, TRUE
},
4531 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
4532 && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
4533 {EXPAND_LANGUAGE
, get_lang_arg
, TRUE
},
4535 {EXPAND_ENV_VARS
, get_env_name
, TRUE
},
4536 #ifdef FEAT_GUI_MACVIM
4537 {EXPAND_MACACTION
, get_macaction_name
, FALSE
},
4543 * Find a context in the table and call the ExpandGeneric() with the
4544 * right function to do the expansion.
4547 for (i
= 0; i
< (int)(sizeof(tab
) / sizeof(struct expgen
)); ++i
)
4548 if (xp
->xp_context
== tab
[i
].context
)
4551 regmatch
.rm_ic
= TRUE
;
4552 ret
= ExpandGeneric(xp
, ®match
, num_file
, file
, tab
[i
].func
);
4557 vim_free(regmatch
.regprog
);
4560 #endif /* FEAT_CMDL_COMPL */
4563 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
4565 * Expand a list of names.
4567 * Generic function for command line completion. It calls a function to
4568 * obtain strings, one by one. The strings are matched against a regexp
4569 * program. Matching strings are copied into an array, which is returned.
4571 * Returns OK when no problems encountered, FAIL for error (out of memory).
4574 ExpandGeneric(xp
, regmatch
, num_file
, file
, func
)
4576 regmatch_T
*regmatch
;
4579 char_u
*((*func
)__ARGS((expand_T
*, int)));
4580 /* returns a string from the list */
4587 /* do this loop twice:
4588 * round == 0: count the number of matching names
4589 * round == 1: copy the matching names into allocated memory
4591 for (round
= 0; round
<= 1; ++round
)
4595 str
= (*func
)(xp
, i
);
4596 if (str
== NULL
) /* end of list */
4598 if (*str
== NUL
) /* skip empty strings */
4601 if (vim_regexec(regmatch
, str
, (colnr_T
)0))
4605 str
= vim_strsave_escaped(str
, (char_u
*)" \t\\.");
4606 (*file
)[count
] = str
;
4608 if (func
== get_menu_names
&& str
!= NULL
)
4610 /* test for separator added by get_menu_names() */
4611 str
+= STRLEN(str
) - 1;
4625 *file
= (char_u
**)alloc((unsigned)(count
* sizeof(char_u
*)));
4628 *file
= (char_u
**)"";
4635 /* Sort the results. Keep menu's in the specified order. */
4636 if (xp
->xp_context
!= EXPAND_MENUNAMES
&& xp
->xp_context
!= EXPAND_MENUS
)
4637 sort_strings(*file
, *num_file
);
4639 #ifdef FEAT_CMDL_COMPL
4640 /* Reset the variables used for special highlight names expansion, so that
4641 * they don't show up when getting normal highlight names by ID. */
4642 reset_expand_highlight();
4649 * Complete a shell command.
4650 * Returns FAIL or OK;
4653 expand_shellcmd(filepat
, num_file
, file
, flagsarg
)
4654 char_u
*filepat
; /* pattern to match with command names */
4655 int *num_file
; /* return: number of matches */
4656 char_u
***file
; /* return: array with matches */
4657 int flagsarg
; /* EW_ flags */
4662 int mustfree
= FALSE
;
4664 char_u
*buf
= alloc(MAXPATHL
);
4667 int flags
= flagsarg
;
4673 /* for ":set path=" and ":set tags=" halve backslashes for escaped
4675 pat
= vim_strsave(filepat
);
4676 for (i
= 0; pat
[i
]; ++i
)
4677 if (pat
[i
] == '\\' && pat
[i
+ 1] == ' ')
4678 STRMOVE(pat
+ i
, pat
+ i
+ 1);
4680 flags
|= EW_FILE
| EW_EXEC
;
4682 /* For an absolute name we don't use $PATH. */
4683 if (mch_isFullName(pat
))
4684 path
= (char_u
*)" ";
4685 else if ((pat
[0] == '.' && (vim_ispathsep(pat
[1])
4686 || (pat
[1] == '.' && vim_ispathsep(pat
[2])))))
4687 path
= (char_u
*)".";
4689 path
= vim_getenv((char_u
*)"PATH", &mustfree
);
4692 * Go over all directories in $PATH. Expand matches in that directory and
4693 * collect them in "ga".
4695 ga_init2(&ga
, (int)sizeof(char *), 10);
4696 for (s
= path
; *s
!= NUL
; s
= e
)
4699 ++s
; /* Skip space used for absolute path name. */
4701 #if defined(MSDOS) || defined(MSWIN) || defined(OS2)
4702 e
= vim_strchr(s
, ';');
4704 e
= vim_strchr(s
, ':');
4710 if (l
> MAXPATHL
- 5)
4712 vim_strncpy(buf
, s
, l
);
4715 vim_strncpy(buf
+ l
, pat
, MAXPATHL
- 1 - l
);
4717 /* Expand matches in one directory of $PATH. */
4718 ret
= expand_wildcards(1, &buf
, num_file
, file
, flags
);
4721 if (ga_grow(&ga
, *num_file
) == FAIL
)
4722 FreeWild(*num_file
, *file
);
4725 for (i
= 0; i
< *num_file
; ++i
)
4730 /* Remove the path again. */
4732 ((char_u
**)ga
.ga_data
)[ga
.ga_len
++] = s
;
4744 *num_file
= ga
.ga_len
;
4754 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
4755 static void * call_user_expand_func
__ARGS((void *(*user_expand_func
) __ARGS((char_u
*, int, char_u
**, int)), expand_T
*xp
, int *num_file
, char_u
***file
));
4758 * Call "user_expand_func()" to invoke a user defined VimL function and return
4759 * the result (either a string or a List).
4762 call_user_expand_func(user_expand_func
, xp
, num_file
, file
)
4763 void *(*user_expand_func
) __ARGS((char_u
*, int, char_u
**, int));
4771 int save_current_SID
= current_SID
;
4773 struct cmdline_info save_ccline
;
4775 if (xp
->xp_arg
== NULL
|| xp
->xp_arg
[0] == '\0')
4780 if (ccline
.cmdbuff
== NULL
)
4782 /* Completion from Insert mode, pass fake arguments. */
4784 sprintf((char *)num
, "%d", (int)STRLEN(xp
->xp_pattern
));
4785 args
[1] = xp
->xp_pattern
;
4789 /* Completion on the command line, pass real arguments. */
4790 keep
= ccline
.cmdbuff
[ccline
.cmdlen
];
4791 ccline
.cmdbuff
[ccline
.cmdlen
] = 0;
4792 sprintf((char *)num
, "%d", ccline
.cmdpos
);
4793 args
[1] = ccline
.cmdbuff
;
4795 args
[0] = vim_strnsave(xp
->xp_pattern
, xp
->xp_pattern_len
);
4798 /* Save the cmdline, we don't know what the function may do. */
4799 save_ccline
= ccline
;
4800 ccline
.cmdbuff
= NULL
;
4801 ccline
.cmdprompt
= NULL
;
4802 current_SID
= xp
->xp_scriptID
;
4804 ret
= user_expand_func(xp
->xp_arg
, 3, args
, FALSE
);
4806 ccline
= save_ccline
;
4807 current_SID
= save_current_SID
;
4808 if (ccline
.cmdbuff
!= NULL
)
4809 ccline
.cmdbuff
[ccline
.cmdlen
] = keep
;
4816 * Expand names with a function defined by the user.
4819 ExpandUserDefined(xp
, regmatch
, num_file
, file
)
4821 regmatch_T
*regmatch
;
4831 retstr
= call_user_expand_func(call_func_retstr
, xp
, num_file
, file
);
4835 ga_init2(&ga
, (int)sizeof(char *), 3);
4836 for (s
= retstr
; *s
!= NUL
; s
= e
)
4838 e
= vim_strchr(s
, '\n');
4844 if (xp
->xp_pattern
[0] && vim_regexec(regmatch
, s
, (colnr_T
)0) == 0)
4852 if (ga_grow(&ga
, 1) == FAIL
)
4855 ((char_u
**)ga
.ga_data
)[ga
.ga_len
] = vim_strnsave(s
, (int)(e
- s
));
4864 *num_file
= ga
.ga_len
;
4869 * Expand names with a list returned by a function defined by the user.
4872 ExpandUserList(xp
, num_file
, file
)
4881 retlist
= call_user_expand_func(call_func_retlist
, xp
, num_file
, file
);
4882 if (retlist
== NULL
)
4885 ga_init2(&ga
, (int)sizeof(char *), 3);
4886 /* Loop over the items in the list. */
4887 for (li
= retlist
->lv_first
; li
!= NULL
; li
= li
->li_next
)
4889 if (li
->li_tv
.v_type
!= VAR_STRING
|| li
->li_tv
.vval
.v_string
== NULL
)
4890 continue; /* Skip non-string items and empty strings */
4892 if (ga_grow(&ga
, 1) == FAIL
)
4895 ((char_u
**)ga
.ga_data
)[ga
.ga_len
] =
4896 vim_strsave(li
->li_tv
.vval
.v_string
);
4899 list_unref(retlist
);
4902 *num_file
= ga
.ga_len
;
4908 * Expand color scheme names: 'runtimepath'/colors/{pat}.vim
4909 * or compiler names.
4912 ExpandRTDir(pat
, num_file
, file
, dirname
)
4916 char *dirname
; /* "colors" or "compiler" */
4925 s
= alloc((unsigned)(STRLEN(pat
) + STRLEN(dirname
) + 7));
4928 sprintf((char *)s
, "%s/%s*.vim", dirname
, pat
);
4929 all
= globpath(p_rtp
, s
, 0);
4934 ga_init2(&ga
, (int)sizeof(char *), 3);
4935 for (s
= all
; *s
!= NUL
; s
= e
)
4937 e
= vim_strchr(s
, '\n');
4940 if (ga_grow(&ga
, 1) == FAIL
)
4942 if (e
- 4 > s
&& STRNICMP(e
- 4, ".vim", 4) == 0)
4944 for (s
= e
- 4; s
> all
; mb_ptr_back(all
, s
))
4945 if (*s
== '\n' || vim_ispathsep(*s
))
4948 ((char_u
**)ga
.ga_data
)[ga
.ga_len
] =
4949 vim_strnsave(s
, (int)(e
- s
- 4));
4957 *num_file
= ga
.ga_len
;
4963 #if defined(FEAT_CMDL_COMPL) || defined(FEAT_EVAL) || defined(PROTO)
4965 * Expand "file" for all comma-separated directories in "path".
4966 * Returns an allocated string with all matches concatenated, separated by
4967 * newlines. Returns NULL for an error or no matches.
4970 globpath(path
, file
, expand_options
)
4984 buf
= alloc(MAXPATHL
);
4989 xpc
.xp_context
= EXPAND_FILES
;
4991 ga_init2(&ga
, 1, 100);
4993 /* Loop over all entries in {path}. */
4994 while (*path
!= NUL
)
4996 /* Copy one item of the path to buf[] and concatenate the file name. */
4997 copy_option_part(&path
, buf
, MAXPATHL
, ",");
4998 if (STRLEN(buf
) + STRLEN(file
) + 2 < MAXPATHL
)
5002 if (ExpandFromContext(&xpc
, buf
, &num_p
, &p
,
5003 WILD_SILENT
|expand_options
) != FAIL
&& num_p
> 0)
5005 ExpandEscape(&xpc
, buf
, num_p
, p
, WILD_SILENT
|expand_options
);
5006 for (len
= 0, i
= 0; i
< num_p
; ++i
)
5007 len
+= (int)STRLEN(p
[i
]) + 1;
5009 /* Concatenate new results to previous ones. */
5010 if (ga_grow(&ga
, len
) == OK
)
5012 cur
= (char_u
*)ga
.ga_data
+ ga
.ga_len
;
5013 for (i
= 0; i
< num_p
; ++i
)
5016 cur
+= STRLEN(p
[i
]);
5026 *--cur
= 0; /* Replace trailing newline with NUL */
5029 return (char_u
*)ga
.ga_data
;
5034 #if defined(FEAT_CMDHIST) || defined(PROTO)
5036 /*********************************
5037 * Command line history stuff *
5038 *********************************/
5041 * Translate a history character to the associated type number.
5055 return HIST_SEARCH
; /* must be '?' or '/' */
5059 * Table of history names.
5060 * These names are used in :history and various hist...() functions.
5061 * It is sufficient to give the significant prefix of a history name.
5064 static char *(history_names
[]) =
5075 * init_history() - Initialize the command line history.
5076 * Also used to re-allocate the history when the size changes.
5081 int newlen
; /* new length of history table */
5088 * If size of history table changed, reallocate it
5091 if (newlen
!= hislen
) /* history length changed */
5093 for (type
= 0; type
< HIST_COUNT
; ++type
) /* adjust the tables */
5097 temp
= (histentry_T
*)lalloc(
5098 (long_u
)(newlen
* sizeof(histentry_T
)), TRUE
);
5099 if (temp
== NULL
) /* out of memory! */
5101 if (type
== 0) /* first one: just keep the old length */
5106 /* Already changed one table, now we can only have zero
5107 * length for all tables. */
5115 if (newlen
== 0 || temp
!= NULL
)
5117 if (hisidx
[type
] < 0) /* there are no entries yet */
5119 for (i
= 0; i
< newlen
; ++i
)
5122 temp
[i
].hisstr
= NULL
;
5125 else if (newlen
> hislen
) /* array becomes bigger */
5127 for (i
= 0; i
<= hisidx
[type
]; ++i
)
5128 temp
[i
] = history
[type
][i
];
5130 for ( ; i
<= newlen
- (hislen
- hisidx
[type
]); ++i
)
5133 temp
[i
].hisstr
= NULL
;
5135 for ( ; j
< hislen
; ++i
, ++j
)
5136 temp
[i
] = history
[type
][j
];
5138 else /* array becomes smaller or 0 */
5141 for (i
= newlen
- 1; ; --i
)
5143 if (i
>= 0) /* copy newest entries */
5144 temp
[i
] = history
[type
][j
];
5145 else /* remove older entries */
5146 vim_free(history
[type
][j
].hisstr
);
5149 if (j
== hisidx
[type
])
5152 hisidx
[type
] = newlen
- 1;
5154 vim_free(history
[type
]);
5155 history
[type
] = temp
;
5163 * Check if command line 'str' is already in history.
5164 * If 'move_to_front' is TRUE, matching entry is moved to end of history.
5167 in_history(type
, str
, move_to_front
)
5170 int move_to_front
; /* Move the entry to the front if it exists */
5175 if (hisidx
[type
] < 0)
5180 if (history
[type
][i
].hisstr
== NULL
)
5182 if (STRCMP(str
, history
[type
][i
].hisstr
) == 0)
5191 } while (i
!= hisidx
[type
]);
5195 str
= history
[type
][i
].hisstr
;
5196 while (i
!= hisidx
[type
])
5200 history
[type
][last_i
] = history
[type
][i
];
5203 history
[type
][i
].hisstr
= str
;
5204 history
[type
][i
].hisnum
= ++hisnum
[type
];
5211 * Convert history name (from table above) to its HIST_ equivalent.
5212 * When "name" is empty, return "cmd" history.
5213 * Returns -1 for unknown history name.
5220 int len
= (int)STRLEN(name
);
5222 /* No argument: use current history. */
5224 return hist_char2type(ccline
.cmdfirstc
);
5226 for (i
= 0; history_names
[i
] != NULL
; ++i
)
5227 if (STRNICMP(name
, history_names
[i
], len
) == 0)
5230 if (vim_strchr((char_u
*)":=@>?/", name
[0]) != NULL
&& name
[1] == NUL
)
5231 return hist_char2type(name
[0]);
5236 static int last_maptick
= -1; /* last seen maptick */
5239 * Add the given string to the given history. If the string is already in the
5240 * history then it is moved to the front. "histype" may be one of he HIST_
5244 add_to_history(histype
, new_entry
, in_map
, sep
)
5247 int in_map
; /* consider maptick when inside a mapping */
5248 int sep
; /* separator character used (search hist) */
5250 histentry_T
*hisptr
;
5253 if (hislen
== 0) /* no history */
5257 * Searches inside the same mapping overwrite each other, so that only
5258 * the last line is kept. Be careful not to remove a line that was moved
5259 * down, only lines that were added.
5261 if (histype
== HIST_SEARCH
&& in_map
)
5263 if (maptick
== last_maptick
)
5265 /* Current line is from the same mapping, remove it */
5266 hisptr
= &history
[HIST_SEARCH
][hisidx
[HIST_SEARCH
]];
5267 vim_free(hisptr
->hisstr
);
5268 hisptr
->hisstr
= NULL
;
5271 if (--hisidx
[HIST_SEARCH
] < 0)
5272 hisidx
[HIST_SEARCH
] = hislen
- 1;
5276 if (!in_history(histype
, new_entry
, TRUE
))
5278 if (++hisidx
[histype
] == hislen
)
5279 hisidx
[histype
] = 0;
5280 hisptr
= &history
[histype
][hisidx
[histype
]];
5281 vim_free(hisptr
->hisstr
);
5283 /* Store the separator after the NUL of the string. */
5284 len
= (int)STRLEN(new_entry
);
5285 hisptr
->hisstr
= vim_strnsave(new_entry
, len
+ 2);
5286 if (hisptr
->hisstr
!= NULL
)
5287 hisptr
->hisstr
[len
+ 1] = sep
;
5289 hisptr
->hisnum
= ++hisnum
[histype
];
5290 if (histype
== HIST_SEARCH
&& in_map
)
5291 last_maptick
= maptick
;
5295 #if defined(FEAT_EVAL) || defined(PROTO)
5298 * Get identifier of newest history entry.
5299 * "histype" may be one of the HIST_ values.
5302 get_history_idx(histype
)
5305 if (hislen
== 0 || histype
< 0 || histype
>= HIST_COUNT
5306 || hisidx
[histype
] < 0)
5309 return history
[histype
][hisidx
[histype
]].hisnum
;
5312 static struct cmdline_info
*get_ccline_ptr
__ARGS((void));
5315 * Get pointer to the command line info to use. cmdline_paste() may clear
5316 * ccline and put the previous value in prev_ccline.
5318 static struct cmdline_info
*
5321 if ((State
& CMDLINE
) == 0)
5323 if (ccline
.cmdbuff
!= NULL
)
5325 if (prev_ccline_used
&& prev_ccline
.cmdbuff
!= NULL
)
5326 return &prev_ccline
;
5331 * Get the current command line in allocated memory.
5332 * Only works when the command line is being edited.
5333 * Returns NULL when something is wrong.
5338 struct cmdline_info
*p
= get_ccline_ptr();
5342 return vim_strnsave(p
->cmdbuff
, p
->cmdlen
);
5346 * Get the current command line position, counted in bytes.
5347 * Zero is the first position.
5348 * Only works when the command line is being edited.
5349 * Returns -1 when something is wrong.
5354 struct cmdline_info
*p
= get_ccline_ptr();
5362 * Set the command line byte position to "pos". Zero is the first position.
5363 * Only works when the command line is being edited.
5364 * Returns 1 when failed, 0 when OK.
5367 set_cmdline_pos(pos
)
5370 struct cmdline_info
*p
= get_ccline_ptr();
5375 /* The position is not set directly but after CTRL-\ e or CTRL-R = has
5376 * changed the command line. */
5385 * Get the current command-line type.
5386 * Returns ':' or '/' or '?' or '@' or '>' or '-'
5387 * Only works when the command line is being edited.
5388 * Returns NUL when something is wrong.
5393 struct cmdline_info
*p
= get_ccline_ptr();
5397 if (p
->cmdfirstc
== NUL
)
5398 return (p
->input_fn
) ? '@' : '-';
5399 return p
->cmdfirstc
;
5403 * Calculate history index from a number:
5404 * num > 0: seen as identifying number of a history entry
5405 * num < 0: relative position in history wrt newest entry
5406 * "histype" may be one of the HIST_ values.
5409 calc_hist_idx(histype
, num
)
5415 int wrapped
= FALSE
;
5417 if (hislen
== 0 || histype
< 0 || histype
>= HIST_COUNT
5418 || (i
= hisidx
[histype
]) < 0 || num
== 0)
5421 hist
= history
[histype
];
5424 while (hist
[i
].hisnum
> num
)
5432 if (hist
[i
].hisnum
== num
&& hist
[i
].hisstr
!= NULL
)
5435 else if (-num
<= hislen
)
5440 if (hist
[i
].hisstr
!= NULL
)
5447 * Get a history entry by its index.
5448 * "histype" may be one of the HIST_ values.
5451 get_history_entry(histype
, idx
)
5455 idx
= calc_hist_idx(histype
, idx
);
5457 return history
[histype
][idx
].hisstr
;
5459 return (char_u
*)"";
5463 * Clear all entries of a history.
5464 * "histype" may be one of the HIST_ values.
5467 clr_history(histype
)
5471 histentry_T
*hisptr
;
5473 if (hislen
!= 0 && histype
>= 0 && histype
< HIST_COUNT
)
5475 hisptr
= history
[histype
];
5476 for (i
= hislen
; i
--;)
5478 vim_free(hisptr
->hisstr
);
5480 hisptr
++->hisstr
= NULL
;
5482 hisidx
[histype
] = -1; /* mark history as cleared */
5483 hisnum
[histype
] = 0; /* reset identifier counter */
5490 * Remove all entries matching {str} from a history.
5491 * "histype" may be one of the HIST_ values.
5494 del_history_entry(histype
, str
)
5498 regmatch_T regmatch
;
5499 histentry_T
*hisptr
;
5505 regmatch
.regprog
= NULL
;
5506 regmatch
.rm_ic
= FALSE
; /* always match case */
5509 && histype
< HIST_COUNT
5511 && (idx
= hisidx
[histype
]) >= 0
5512 && (regmatch
.regprog
= vim_regcomp(str
, RE_MAGIC
+ RE_STRING
))
5518 hisptr
= &history
[histype
][i
];
5519 if (hisptr
->hisstr
== NULL
)
5521 if (vim_regexec(®match
, hisptr
->hisstr
, (colnr_T
)0))
5524 vim_free(hisptr
->hisstr
);
5525 hisptr
->hisstr
= NULL
;
5532 history
[histype
][last
] = *hisptr
;
5533 hisptr
->hisstr
= NULL
;
5542 if (history
[histype
][idx
].hisstr
== NULL
)
5543 hisidx
[histype
] = -1;
5545 vim_free(regmatch
.regprog
);
5550 * Remove an indexed entry from a history.
5551 * "histype" may be one of the HIST_ values.
5554 del_history_idx(histype
, idx
)
5560 i
= calc_hist_idx(histype
, idx
);
5563 idx
= hisidx
[histype
];
5564 vim_free(history
[histype
][i
].hisstr
);
5566 /* When deleting the last added search string in a mapping, reset
5567 * last_maptick, so that the last added search string isn't deleted again.
5569 if (histype
== HIST_SEARCH
&& maptick
== last_maptick
&& i
== idx
)
5574 j
= (i
+ 1) % hislen
;
5575 history
[histype
][i
] = history
[histype
][j
];
5578 history
[histype
][i
].hisstr
= NULL
;
5579 history
[histype
][i
].hisnum
= 0;
5582 hisidx
[histype
] = i
;
5586 #endif /* FEAT_EVAL */
5588 #if defined(FEAT_CRYPT) || defined(PROTO)
5590 * Very specific function to remove the value in ":set key=val" from the
5594 remove_key_from_history()
5599 i
= hisidx
[HIST_CMD
];
5602 p
= history
[HIST_CMD
][i
].hisstr
;
5605 if (STRNCMP(p
, "key", 3) == 0 && !isalpha(p
[3]))
5607 p
= vim_strchr(p
+ 3, '=');
5611 for (i
= 0; p
[i
] && !vim_iswhite(p
[i
]); ++i
)
5612 if (p
[i
] == '\\' && p
[i
+ 1])
5620 #endif /* FEAT_CMDHIST */
5622 #if defined(FEAT_QUICKFIX) || defined(FEAT_CMDHIST) || defined(PROTO)
5624 * Get indices "num1,num2" that specify a range within a list (not a range of
5625 * text lines in a buffer!) from a string. Used for ":history" and ":clist".
5626 * Returns OK if parsed successfully, otherwise FAIL.
5629 get_list_range(str
, num1
, num2
)
5638 *str
= skipwhite(*str
);
5639 if (**str
== '-' || vim_isdigit(**str
)) /* parse "from" part of range */
5641 vim_str2nr(*str
, NULL
, &len
, FALSE
, FALSE
, &num
, NULL
);
5646 *str
= skipwhite(*str
);
5647 if (**str
== ',') /* parse "to" part of range */
5649 *str
= skipwhite(*str
+ 1);
5650 vim_str2nr(*str
, NULL
, &len
, FALSE
, FALSE
, &num
, NULL
);
5654 *str
= skipwhite(*str
+ len
);
5656 else if (!first
) /* no number given at all */
5659 else if (first
) /* only one number given */
5665 #if defined(FEAT_CMDHIST) || defined(PROTO)
5667 * :history command - print a history
5674 int histype1
= HIST_CMD
;
5675 int histype2
= HIST_CMD
;
5681 char_u
*arg
= eap
->arg
;
5685 MSG(_("'history' option is zero"));
5689 if (!(VIM_ISDIGIT(*arg
) || *arg
== '-' || *arg
== ','))
5692 while (ASCII_ISALPHA(*end
)
5693 || vim_strchr((char_u
*)":=@>/?", *end
) != NULL
)
5697 histype1
= get_histtype(arg
);
5700 if (STRNICMP(arg
, "all", STRLEN(arg
)) == 0)
5703 histype2
= HIST_COUNT
-1;
5708 EMSG(_(e_trailing
));
5713 histype2
= histype1
;
5718 if (!get_list_range(&end
, &hisidx1
, &hisidx2
) || *end
!= NUL
)
5720 EMSG(_(e_trailing
));
5724 for (; !got_int
&& histype1
<= histype2
; ++histype1
)
5726 STRCPY(IObuff
, "\n # ");
5727 STRCAT(STRCAT(IObuff
, history_names
[histype1
]), " history");
5728 MSG_PUTS_TITLE(IObuff
);
5729 idx
= hisidx
[histype1
];
5730 hist
= history
[histype1
];
5734 j
= (-j
> hislen
) ? 0 : hist
[(hislen
+j
+idx
+1) % hislen
].hisnum
;
5736 k
= (-k
> hislen
) ? 0 : hist
[(hislen
+k
+idx
+1) % hislen
].hisnum
;
5737 if (idx
>= 0 && j
<= k
)
5738 for (i
= idx
+ 1; !got_int
; ++i
)
5742 if (hist
[i
].hisstr
!= NULL
5743 && hist
[i
].hisnum
>= j
&& hist
[i
].hisnum
<= k
)
5746 sprintf((char *)IObuff
, "%c%6d ", i
== idx
? '>' : ' ',
5748 if (vim_strsize(hist
[i
].hisstr
) > (int)Columns
- 10)
5749 trunc_string(hist
[i
].hisstr
, IObuff
+ STRLEN(IObuff
),
5752 STRCAT(IObuff
, hist
[i
].hisstr
);
5753 msg_outtrans(IObuff
);
5763 #if (defined(FEAT_VIMINFO) && defined(FEAT_CMDHIST)) || defined(PROTO)
5764 static char_u
**viminfo_history
[HIST_COUNT
] = {NULL
, NULL
, NULL
, NULL
};
5765 static int viminfo_hisidx
[HIST_COUNT
] = {0, 0, 0, 0};
5766 static int viminfo_hislen
[HIST_COUNT
] = {0, 0, 0, 0};
5767 static int viminfo_add_at_front
= FALSE
;
5769 static int hist_type2char
__ARGS((int type
, int use_question
));
5772 * Translate a history type number to the associated character.
5775 hist_type2char(type
, use_question
)
5777 int use_question
; /* use '?' instead of '/' */
5779 if (type
== HIST_CMD
)
5781 if (type
== HIST_SEARCH
)
5788 if (type
== HIST_EXPR
)
5794 * Prepare for reading the history from the viminfo file.
5795 * This allocates history arrays to store the read history lines.
5798 prepare_viminfo_history(asklen
)
5807 viminfo_add_at_front
= (asklen
!= 0);
5808 if (asklen
> hislen
)
5811 for (type
= 0; type
< HIST_COUNT
; ++type
)
5814 * Count the number of empty spaces in the history list. If there are
5815 * more spaces available than we request, then fill them up.
5817 for (i
= 0, num
= 0; i
< hislen
; i
++)
5818 if (history
[type
][i
].hisstr
== NULL
)
5824 viminfo_history
[type
] = NULL
;
5826 viminfo_history
[type
] =
5827 (char_u
**)lalloc((long_u
)(len
* sizeof(char_u
*)), FALSE
);
5828 if (viminfo_history
[type
] == NULL
)
5830 viminfo_hislen
[type
] = len
;
5831 viminfo_hisidx
[type
] = 0;
5836 * Accept a line from the viminfo, store it in the history array when it's
5840 read_viminfo_history(virp
)
5848 type
= hist_char2type(virp
->vir_line
[0]);
5849 if (viminfo_hisidx
[type
] < viminfo_hislen
[type
])
5851 val
= viminfo_readstring(virp
, 1, TRUE
);
5852 if (val
!= NULL
&& *val
!= NUL
)
5854 if (!in_history(type
, val
+ (type
== HIST_SEARCH
),
5855 viminfo_add_at_front
))
5857 /* Need to re-allocate to append the separator byte. */
5859 p
= lalloc(len
+ 2, TRUE
);
5862 if (type
== HIST_SEARCH
)
5864 /* Search entry: Move the separator from the first
5865 * column to after the NUL. */
5866 mch_memmove(p
, val
+ 1, (size_t)len
);
5867 p
[len
] = (*val
== ' ' ? NUL
: *val
);
5871 /* Not a search entry: No separator in the viminfo
5872 * file, add a NUL separator. */
5873 mch_memmove(p
, val
, (size_t)len
+ 1);
5876 viminfo_history
[type
][viminfo_hisidx
[type
]++] = p
;
5882 return viminfo_readline(virp
);
5886 finish_viminfo_history()
5892 for (type
= 0; type
< HIST_COUNT
; ++type
)
5894 if (history
[type
] == NULL
)
5896 idx
= hisidx
[type
] + viminfo_hisidx
[type
];
5901 if (viminfo_add_at_front
)
5905 if (hisidx
[type
] == -1)
5906 hisidx
[type
] = hislen
- 1;
5909 if (history
[type
][idx
].hisstr
!= NULL
)
5911 if (++idx
== hislen
)
5913 } while (idx
!= hisidx
[type
]);
5914 if (idx
!= hisidx
[type
] && --idx
< 0)
5917 for (i
= 0; i
< viminfo_hisidx
[type
]; i
++)
5919 vim_free(history
[type
][idx
].hisstr
);
5920 history
[type
][idx
].hisstr
= viminfo_history
[type
][i
];
5926 for (i
= 0; i
< viminfo_hisidx
[type
]; i
++)
5928 history
[type
][idx
++].hisnum
= ++hisnum
[type
];
5931 vim_free(viminfo_history
[type
]);
5932 viminfo_history
[type
] = NULL
;
5937 write_viminfo_history(fp
)
5949 for (type
= 0; type
< HIST_COUNT
; ++type
)
5951 num_saved
= get_viminfo_parameter(hist_type2char(type
, FALSE
));
5954 if (num_saved
< 0) /* Use default */
5956 fprintf(fp
, _("\n# %s History (newest to oldest):\n"),
5957 type
== HIST_CMD
? _("Command Line") :
5958 type
== HIST_SEARCH
? _("Search String") :
5959 type
== HIST_EXPR
? _("Expression") :
5961 if (num_saved
> hislen
)
5967 p
= history
[type
][i
].hisstr
;
5970 fputc(hist_type2char(type
, TRUE
), fp
);
5971 /* For the search history: put the separator in the second
5972 * column; use a space if there isn't one. */
5973 if (type
== HIST_SEARCH
)
5975 c
= p
[STRLEN(p
) + 1];
5976 putc(c
== NUL
? ' ' : c
, fp
);
5978 viminfo_writestring(fp
, p
);
5985 #endif /* FEAT_VIMINFO */
5987 #if defined(FEAT_FKMAP) || defined(PROTO)
5989 * Write a character at the current cursor+offset position.
5990 * It is directly written into the command buffer block.
5993 cmd_pchar(c
, offset
)
5996 if (ccline
.cmdpos
+ offset
>= ccline
.cmdlen
|| ccline
.cmdpos
+ offset
< 0)
5998 EMSG(_("E198: cmd_pchar beyond the command length"));
6001 ccline
.cmdbuff
[ccline
.cmdpos
+ offset
] = (char_u
)c
;
6002 ccline
.cmdbuff
[ccline
.cmdlen
] = NUL
;
6009 if (ccline
.cmdpos
+ offset
>= ccline
.cmdlen
|| ccline
.cmdpos
+ offset
< 0)
6011 /* EMSG(_("cmd_gchar beyond the command length")); */
6014 return (int)ccline
.cmdbuff
[ccline
.cmdpos
+ offset
];
6018 #if defined(FEAT_CMDWIN) || defined(PROTO)
6020 * Open a window on the current command line and history. Allow editing in
6021 * the window. Returns when the window is closed.
6023 * CR if the command is to be executed
6024 * Ctrl_C if it is to be abandoned
6025 * K_IGNORE if editing continues
6030 struct cmdline_info save_ccline
;
6031 buf_T
*old_curbuf
= curbuf
;
6032 win_T
*old_curwin
= curwin
;
6042 int save_restart_edit
= restart_edit
;
6043 int save_State
= State
;
6044 int save_exmode
= exmode_active
;
6045 #ifdef FEAT_RIGHTLEFT
6046 int save_cmdmsg_rl
= cmdmsg_rl
;
6049 /* Can't do this recursively. Can't do it when typing a password. */
6050 if (cmdwin_type
!= 0
6051 # if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
6060 /* Save current window sizes. */
6061 win_size_save(&winsizes
);
6063 # ifdef FEAT_AUTOCMD
6064 /* Don't execute autocommands while creating the window. */
6067 /* don't use a new tab page */
6070 /* Create a window for the command-line buffer. */
6071 if (win_split((int)p_cwh
, WSP_BOT
) == FAIL
)
6074 # ifdef FEAT_AUTOCMD
6079 cmdwin_type
= get_cmdline_type();
6081 /* Create the command-line buffer empty. */
6082 (void)do_ecmd(0, NULL
, NULL
, NULL
, ECMD_ONE
, ECMD_HIDE
, NULL
);
6083 (void)setfname(curbuf
, (char_u
*)"[Command Line]", NULL
, TRUE
);
6084 set_option_value((char_u
*)"bt", 0L, (char_u
*)"nofile", OPT_LOCAL
);
6085 set_option_value((char_u
*)"swf", 0L, NULL
, OPT_LOCAL
);
6086 curbuf
->b_p_ma
= TRUE
;
6088 curwin
->w_p_fen
= FALSE
;
6090 # ifdef FEAT_RIGHTLEFT
6091 curwin
->w_p_rl
= cmdmsg_rl
;
6094 # ifdef FEAT_SCROLLBIND
6095 curwin
->w_p_scb
= FALSE
;
6098 # ifdef FEAT_AUTOCMD
6099 /* Do execute autocommands for setting the filetype (load syntax). */
6103 /* Showing the prompt may have set need_wait_return, reset it. */
6104 need_wait_return
= FALSE
;
6106 histtype
= hist_char2type(cmdwin_type
);
6107 if (histtype
== HIST_CMD
|| histtype
== HIST_DEBUG
)
6111 add_map((char_u
*)"<buffer> <Tab> <C-X><C-V>", INSERT
);
6112 add_map((char_u
*)"<buffer> <Tab> a<C-X><C-V>", NORMAL
);
6114 set_option_value((char_u
*)"ft", 0L, (char_u
*)"vim", OPT_LOCAL
);
6117 /* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
6118 * sets 'textwidth' to 78). */
6121 /* Fill the buffer with the history. */
6125 i
= hisidx
[histtype
];
6133 if (history
[histtype
][i
].hisstr
!= NULL
)
6134 ml_append(lnum
++, history
[histtype
][i
].hisstr
,
6137 while (i
!= hisidx
[histtype
]);
6141 /* Replace the empty last line with the current command-line and put the
6143 ml_replace(curbuf
->b_ml
.ml_line_count
, ccline
.cmdbuff
, TRUE
);
6144 curwin
->w_cursor
.lnum
= curbuf
->b_ml
.ml_line_count
;
6145 curwin
->w_cursor
.col
= ccline
.cmdpos
;
6146 changed_line_abv_curs();
6147 invalidate_botline();
6148 redraw_later(SOME_VALID
);
6150 /* Save the command line info, can be used recursively. */
6151 save_ccline
= ccline
;
6152 ccline
.cmdbuff
= NULL
;
6153 ccline
.cmdprompt
= NULL
;
6155 /* No Ex mode here! */
6163 # ifdef FEAT_AUTOCMD
6164 /* Trigger CmdwinEnter autocommands. */
6165 typestr
[0] = cmdwin_type
;
6167 apply_autocmds(EVENT_CMDWINENTER
, typestr
, typestr
, FALSE
, curbuf
);
6168 if (restart_edit
!= 0) /* autocmd with ":startinsert" */
6169 stuffcharReadbuff(K_NOP
);
6172 i
= RedrawingDisabled
;
6173 RedrawingDisabled
= 0;
6176 * Call the main loop until <CR> or CTRL-C is typed.
6179 main_loop(TRUE
, FALSE
);
6181 RedrawingDisabled
= i
;
6183 # ifdef FEAT_AUTOCMD
6184 /* Trigger CmdwinLeave autocommands. */
6185 apply_autocmds(EVENT_CMDWINLEAVE
, typestr
, typestr
, FALSE
, curbuf
);
6188 /* Restore the command line info. */
6189 ccline
= save_ccline
;
6192 exmode_active
= save_exmode
;
6194 /* Safety check: The old window or buffer was deleted: It's a bug when
6196 if (!win_valid(old_curwin
) || !buf_valid(old_curbuf
))
6198 cmdwin_result
= Ctrl_C
;
6199 EMSG(_("E199: Active window or buffer deleted"));
6203 # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
6204 /* autocmds may abort script processing */
6205 if (aborting() && cmdwin_result
!= K_IGNORE
)
6206 cmdwin_result
= Ctrl_C
;
6208 /* Set the new command line from the cmdline buffer. */
6209 vim_free(ccline
.cmdbuff
);
6210 if (cmdwin_result
== K_XF1
|| cmdwin_result
== K_XF2
) /* :qa[!] typed */
6212 char *p
= (cmdwin_result
== K_XF2
) ? "qa" : "qa!";
6214 if (histtype
== HIST_CMD
)
6216 /* Execute the command directly. */
6217 ccline
.cmdbuff
= vim_strsave((char_u
*)p
);
6218 cmdwin_result
= CAR
;
6222 /* First need to cancel what we were doing. */
6223 ccline
.cmdbuff
= NULL
;
6224 stuffcharReadbuff(':');
6225 stuffReadbuff((char_u
*)p
);
6226 stuffcharReadbuff(CAR
);
6229 else if (cmdwin_result
== K_XF2
) /* :qa typed */
6231 ccline
.cmdbuff
= vim_strsave((char_u
*)"qa");
6232 cmdwin_result
= CAR
;
6235 ccline
.cmdbuff
= vim_strsave(ml_get_curline());
6236 if (ccline
.cmdbuff
== NULL
)
6237 cmdwin_result
= Ctrl_C
;
6240 ccline
.cmdlen
= (int)STRLEN(ccline
.cmdbuff
);
6241 ccline
.cmdbufflen
= ccline
.cmdlen
+ 1;
6242 ccline
.cmdpos
= curwin
->w_cursor
.col
;
6243 if (ccline
.cmdpos
> ccline
.cmdlen
)
6244 ccline
.cmdpos
= ccline
.cmdlen
;
6245 if (cmdwin_result
== K_IGNORE
)
6247 set_cmdspos_cursor();
6252 # ifdef FEAT_AUTOCMD
6253 /* Don't execute autocommands while deleting the window. */
6258 win_goto(old_curwin
);
6259 win_close(wp
, TRUE
);
6260 close_buffer(NULL
, bp
, DOBUF_WIPE
);
6262 /* Restore window sizes. */
6263 win_size_restore(&winsizes
);
6265 # ifdef FEAT_AUTOCMD
6270 ga_clear(&winsizes
);
6271 restart_edit
= save_restart_edit
;
6272 # ifdef FEAT_RIGHTLEFT
6273 cmdmsg_rl
= save_cmdmsg_rl
;
6281 return cmdwin_result
;
6283 #endif /* FEAT_CMDWIN */
6286 * Used for commands that either take a simple command string argument, or:
6290 * Returns a pointer to allocated memory with {script} or NULL.
6293 script_get(eap
, cmd
)
6298 char *end_pattern
= NULL
;
6302 if (cmd
[0] != '<' || cmd
[1] != '<' || eap
->getline
== NULL
)
6305 ga_init2(&ga
, 1, 0x400);
6308 end_pattern
= (char *)skipwhite(cmd
+ 2);
6314 theline
= eap
->getline(
6316 eap
->cstack
->cs_looplevel
> 0 ? -1 :
6318 NUL
, eap
->cookie
, 0);
6320 if (theline
== NULL
|| STRCMP(end_pattern
, theline
) == 0)
6326 ga_concat(&ga
, theline
);
6327 ga_append(&ga
, '\n');
6330 ga_append(&ga
, NUL
);
6332 return (char_u
*)ga
.ga_data
;