xref: /vim-8.2.3635/src/ex_cmds.c (revision 899dddf8)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
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.
8  */
9 
10 /*
11  * ex_cmds.c: some functions for command line commands
12  */
13 
14 #include "vim.h"
15 #ifdef HAVE_FCNTL_H
16 # include <fcntl.h>
17 #endif
18 #include "version.h"
19 
20 #ifdef FEAT_EX_EXTRA
21 static int linelen __ARGS((int *has_tab));
22 #endif
23 static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, int do_in, int do_out));
24 #ifdef FEAT_VIMINFO
25 static char_u *viminfo_filename __ARGS((char_u	*));
26 static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int want_info, int want_marks, int force_read));
27 static int viminfo_encoding __ARGS((vir_T *virp));
28 static int read_viminfo_up_to_marks __ARGS((vir_T *virp, int forceit, int writing));
29 #endif
30 
31 static int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int other));
32 static int check_readonly __ARGS((int *forceit, buf_T *buf));
33 #ifdef FEAT_AUTOCMD
34 static void delbuf_msg __ARGS((char_u *name));
35 #endif
36 static int
37 #ifdef __BORLANDC__
38     _RTLENTRYF
39 #endif
40 	help_compare __ARGS((const void *s1, const void *s2));
41 
42 /*
43  * ":ascii" and "ga".
44  */
45 /*ARGSUSED*/
46     void
47 do_ascii(eap)
48     exarg_T	*eap;
49 {
50     int		c;
51     char	buf1[20];
52     char	buf2[20];
53     char_u	buf3[7];
54 #ifdef FEAT_MBYTE
55     int		cc[MAX_MCO];
56     int		ci = 0;
57     int		len;
58 
59     if (enc_utf8)
60 	c = utfc_ptr2char(ml_get_cursor(), cc);
61     else
62 #endif
63 	c = gchar_cursor();
64     if (c == NUL)
65     {
66 	MSG("NUL");
67 	return;
68     }
69 
70 #ifdef FEAT_MBYTE
71     IObuff[0] = NUL;
72     if (!has_mbyte || (enc_dbcs != 0 && c < 0x100) || c < 0x80)
73 #endif
74     {
75 	if (c == NL)	    /* NUL is stored as NL */
76 	    c = NUL;
77 	if (vim_isprintc_strict(c) && (c < ' '
78 #ifndef EBCDIC
79 		    || c > '~'
80 #endif
81 			       ))
82 	{
83 	    transchar_nonprint(buf3, c);
84 	    sprintf(buf1, "  <%s>", (char *)buf3);
85 	}
86 	else
87 	    buf1[0] = NUL;
88 #ifndef EBCDIC
89 	if (c >= 0x80)
90 	    sprintf(buf2, "  <M-%s>", transchar(c & 0x7f));
91 	else
92 #endif
93 	    buf2[0] = NUL;
94 	vim_snprintf((char *)IObuff, IOSIZE,
95 		_("<%s>%s%s  %d,  Hex %02x,  Octal %03o"),
96 					   transchar(c), buf1, buf2, c, c, c);
97 #ifdef FEAT_MBYTE
98 	c = cc[ci++];
99 #endif
100     }
101 
102 #ifdef FEAT_MBYTE
103     /* Repeat for combining characters. */
104     while (has_mbyte && (c >= 0x100 || (enc_utf8 && c >= 0x80)))
105     {
106 	len = (int)STRLEN(IObuff);
107 	/* This assumes every multi-byte char is printable... */
108 	if (len > 0)
109 	    IObuff[len++] = ' ';
110 	IObuff[len++] = '<';
111 	if (utf_iscomposing(c)
112 # ifdef USE_GUI
113 		&& !gui.in_use
114 # endif
115 		)
116 	    IObuff[len++] = ' '; /* draw composing char on top of a space */
117 	len += (*mb_char2bytes)(c, IObuff + len);
118 	vim_snprintf((char *)IObuff + len, IOSIZE - len,
119 			c < 0x10000 ? _("> %d, Hex %04x, Octal %o")
120 				    : _("> %d, Hex %08x, Octal %o"), c, c, c);
121 	if (ci == MAX_MCO)
122 	    break;
123 	c = cc[ci++];
124     }
125 #endif
126 
127     msg(IObuff);
128 }
129 
130 #if defined(FEAT_EX_EXTRA) || defined(PROTO)
131 /*
132  * ":left", ":center" and ":right": align text.
133  */
134     void
135 ex_align(eap)
136     exarg_T	*eap;
137 {
138     pos_T	save_curpos;
139     int		len;
140     int		indent = 0;
141     int		new_indent;
142     int		has_tab;
143     int		width;
144 
145 #ifdef FEAT_RIGHTLEFT
146     if (curwin->w_p_rl)
147     {
148 	/* switch left and right aligning */
149 	if (eap->cmdidx == CMD_right)
150 	    eap->cmdidx = CMD_left;
151 	else if (eap->cmdidx == CMD_left)
152 	    eap->cmdidx = CMD_right;
153     }
154 #endif
155 
156     width = atoi((char *)eap->arg);
157     save_curpos = curwin->w_cursor;
158     if (eap->cmdidx == CMD_left)    /* width is used for new indent */
159     {
160 	if (width >= 0)
161 	    indent = width;
162     }
163     else
164     {
165 	/*
166 	 * if 'textwidth' set, use it
167 	 * else if 'wrapmargin' set, use it
168 	 * if invalid value, use 80
169 	 */
170 	if (width <= 0)
171 	    width = curbuf->b_p_tw;
172 	if (width == 0 && curbuf->b_p_wm > 0)
173 	    width = W_WIDTH(curwin) - curbuf->b_p_wm;
174 	if (width <= 0)
175 	    width = 80;
176     }
177 
178     if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
179 	return;
180 
181     for (curwin->w_cursor.lnum = eap->line1;
182 		 curwin->w_cursor.lnum <= eap->line2; ++curwin->w_cursor.lnum)
183     {
184 	if (eap->cmdidx == CMD_left)		/* left align */
185 	    new_indent = indent;
186 	else
187 	{
188 	    len = linelen(eap->cmdidx == CMD_right ? &has_tab
189 						   : NULL) - get_indent();
190 
191 	    if (len <= 0)			/* skip blank lines */
192 		continue;
193 
194 	    if (eap->cmdidx == CMD_center)
195 		new_indent = (width - len) / 2;
196 	    else
197 	    {
198 		new_indent = width - len;	/* right align */
199 
200 		/*
201 		 * Make sure that embedded TABs don't make the text go too far
202 		 * to the right.
203 		 */
204 		if (has_tab)
205 		    while (new_indent > 0)
206 		    {
207 			(void)set_indent(new_indent, 0);
208 			if (linelen(NULL) <= width)
209 			{
210 			    /*
211 			     * Now try to move the line as much as possible to
212 			     * the right.  Stop when it moves too far.
213 			     */
214 			    do
215 				(void)set_indent(++new_indent, 0);
216 			    while (linelen(NULL) <= width);
217 			    --new_indent;
218 			    break;
219 			}
220 			--new_indent;
221 		    }
222 	    }
223 	}
224 	if (new_indent < 0)
225 	    new_indent = 0;
226 	(void)set_indent(new_indent, 0);		/* set indent */
227     }
228     changed_lines(eap->line1, 0, eap->line2 + 1, 0L);
229     curwin->w_cursor = save_curpos;
230     beginline(BL_WHITE | BL_FIX);
231 }
232 
233 /*
234  * Get the length of the current line, excluding trailing white space.
235  */
236     static int
237 linelen(has_tab)
238     int	    *has_tab;
239 {
240     char_u  *line;
241     char_u  *first;
242     char_u  *last;
243     int	    save;
244     int	    len;
245 
246     /* find the first non-blank character */
247     line = ml_get_curline();
248     first = skipwhite(line);
249 
250     /* find the character after the last non-blank character */
251     for (last = first + STRLEN(first);
252 				last > first && vim_iswhite(last[-1]); --last)
253 	;
254     save = *last;
255     *last = NUL;
256     len = linetabsize(line);		/* get line length */
257     if (has_tab != NULL)		/* check for embedded TAB */
258 	*has_tab = (vim_strrchr(first, TAB) != NULL);
259     *last = save;
260 
261     return len;
262 }
263 
264 /* Buffer for one line used during sorting.  It's allocated to contain the
265  * longest line being sorted. */
266 static char_u	*sortbuf;
267 
268 static int	sort_ic;		/* ignore case */
269 static int	sort_nr;		/* sort on number */
270 
271 /* Struct to store info to be sorted. */
272 typedef struct
273 {
274     linenr_T	lnum;			/* line number */
275     long	col_nr;			/* column number or number */
276 } sorti_T;
277 
278 static int
279 #ifdef __BORLANDC__
280 _RTLENTRYF
281 #endif
282 sort_compare __ARGS((const void *s1, const void *s2));
283 
284     static int
285 #ifdef __BORLANDC__
286 _RTLENTRYF
287 #endif
288 sort_compare(s1, s2)
289     const void	*s1;
290     const void	*s2;
291 {
292     sorti_T	l1 = *(sorti_T *)s1;
293     sorti_T	l2 = *(sorti_T *)s2;
294     char_u	*s;
295 
296     /* When sorting numbers "col_nr" is the number, not the column number. */
297     if (sort_nr)
298 	return l1.col_nr - l2.col_nr;
299 
300     /* We need to copy one line into "sortbuf", because there is no guarantee
301      * that the first pointer becomes invalid when obtaining the second one. */
302     STRCPY(sortbuf, ml_get(l1.lnum) + l1.col_nr);
303     s = ml_get(l2.lnum) + l2.col_nr;
304 
305     return sort_ic ? STRICMP(sortbuf, s) : STRCMP(sortbuf, s);
306 }
307 
308 /*
309  * ":sort".
310  */
311     void
312 ex_sort(eap)
313     exarg_T	*eap;
314 {
315     regmatch_T	regmatch;
316     int		len;
317     linenr_T	lnum;
318     long	maxlen = 0;
319     sorti_T	*nrs;
320     size_t	count = eap->line2 - eap->line1 + 1;
321     size_t	i;
322     char_u	*p;
323     char_u	*s;
324     int		unique = FALSE;
325     long	deleted;
326     colnr_T	col;
327     int		sort_oct;		/* sort on octal number */
328     int		sort_hex;		/* sort on hex number */
329 
330     if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
331 	return;
332     sortbuf = NULL;
333     regmatch.regprog = NULL;
334     nrs = (sorti_T *)lalloc((long_u)(count * sizeof(sorti_T)), TRUE);
335     if (nrs == NULL)
336 	goto theend;
337 
338     sort_ic = sort_nr = sort_oct = sort_hex = 0;
339 
340     for (p = eap->arg; *p != NUL; ++p)
341     {
342 	if (vim_iswhite(*p))
343 	    ;
344 	else if (*p == 'i')
345 	    sort_ic = TRUE;
346 	else if (*p == 'n')
347 	    sort_nr = 2;
348 	else if (*p == 'o')
349 	    sort_oct = 2;
350 	else if (*p == 'x')
351 	    sort_hex = 2;
352 	else if (*p == 'u')
353 	    unique = TRUE;
354 	else if (*p == '"')	/* comment start */
355 	    break;
356 	else if (check_nextcmd(p) != NULL)
357 	{
358 	    eap->nextcmd = check_nextcmd(p);
359 	    break;
360 	}
361 	else if (!ASCII_ISALPHA(*p) && regmatch.regprog == NULL)
362 	{
363 	    s = skip_regexp(p + 1, *p, TRUE, NULL);
364 	    if (*s != *p)
365 	    {
366 		EMSG(_(e_invalpat));
367 		goto theend;
368 	    }
369 	    *s = NUL;
370 	    regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
371 	    if (regmatch.regprog == NULL)
372 		goto theend;
373 	    p = s;		/* continue after the regexp */
374 	    regmatch.rm_ic = p_ic;
375 	}
376 	else
377 	{
378 	    EMSG2(_(e_invarg2), p);
379 	    goto theend;
380 	}
381     }
382 
383     /* Can only have one of 'n', 'o' and 'x'. */
384     if (sort_nr + sort_oct + sort_hex > 2)
385     {
386 	EMSG(_(e_invarg));
387 	goto theend;
388     }
389 
390     /* From here on "sort_nr" is used as a flag for any number sorting. */
391     sort_nr += sort_oct + sort_hex;
392 
393     /*
394      * Make an array with all line numbers.  This avoids having to copy all
395      * the lines into allocated memory.
396      * When sorting on strings "col_nr" is de offset in the line, for numbers
397      * sorting it's the number to sort on.  This means the pattern matching
398      * and number conversion only has to be done once per line.
399      * Also get the longest line length for allocating "sortbuf".
400      */
401     for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
402     {
403 	s = ml_get(lnum);
404 	len = STRLEN(s);
405 	if (maxlen < len)
406 	    maxlen = len;
407 
408 	if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0))
409 	    col = regmatch.endp[0] - s;
410 	else
411 	    col = 0;
412 
413 	if (sort_nr)
414 	{
415 	    /* Sorting on number: Store the number itself. */
416 	    if (sort_hex)
417 		s = skiptohex(s + col);
418 	    else
419 		s = skiptodigit(s + col);
420 	    vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
421 					&nrs[lnum - eap->line1].col_nr, NULL);
422 	}
423 	else
424 	    /* Store the column to sort at. */
425 	    nrs[lnum - eap->line1].col_nr = col;
426 
427 	nrs[lnum - eap->line1].lnum = lnum;
428 
429 	if (regmatch.regprog != NULL)
430 	    fast_breakcheck();
431 	if (got_int)
432 	    goto theend;
433     }
434 
435     /* Allocate a buffer that can hold the longest line. */
436     sortbuf = alloc((unsigned)maxlen + 1);
437     if (sortbuf == NULL)
438 	goto theend;
439 
440     /* Sort the array of line numbers.  Note: can't be interrupted! */
441     qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
442 
443     /* Insert the lines in the sorted order below the last one. */
444     lnum = eap->line2;
445     for (i = 0; i < count; ++i)
446     {
447 	s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum);
448 	if (!unique || i == 0
449 		|| (sort_ic ? STRICMP(s, sortbuf) : STRCMP(s, sortbuf)) != 0)
450 	{
451 	    if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL)
452 		break;
453 	    if (unique)
454 		STRCPY(sortbuf, s);
455 	}
456 	fast_breakcheck();
457 	if (got_int)
458 	    goto theend;
459     }
460 
461     /* delete the original lines if appending worked */
462     if (i == count)
463 	for (i = 0; i < count; ++i)
464 	    ml_delete(eap->line1, FALSE);
465     else
466 	count = 0;
467 
468     /* Adjust marks for deleted (or added) lines and prepare for displaying. */
469     deleted = count - (lnum - eap->line2);
470     if (deleted > 0)
471 	mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
472     else if (deleted < 0)
473 	mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
474     changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
475 
476     curwin->w_cursor.lnum = eap->line1;
477     beginline(BL_WHITE | BL_FIX);
478 
479 theend:
480     vim_free(nrs);
481     vim_free(sortbuf);
482     vim_free(regmatch.regprog);
483     if (got_int)
484 	EMSG(_(e_interr));
485 }
486 
487 /*
488  * ":retab".
489  */
490     void
491 ex_retab(eap)
492     exarg_T	*eap;
493 {
494     linenr_T	lnum;
495     int		got_tab = FALSE;
496     long	num_spaces = 0;
497     long	num_tabs;
498     long	len;
499     long	col;
500     long	vcol;
501     long	start_col = 0;		/* For start of white-space string */
502     long	start_vcol = 0;		/* For start of white-space string */
503     int		temp;
504     long	old_len;
505     char_u	*ptr;
506     char_u	*new_line = (char_u *)1;    /* init to non-NULL */
507     int		did_undo;		/* called u_save for current line */
508     int		new_ts;
509     int		save_list;
510     linenr_T	first_line = 0;		/* first changed line */
511     linenr_T	last_line = 0;		/* last changed line */
512 
513     save_list = curwin->w_p_list;
514     curwin->w_p_list = 0;	    /* don't want list mode here */
515 
516     new_ts = getdigits(&(eap->arg));
517     if (new_ts < 0)
518     {
519 	EMSG(_(e_positive));
520 	return;
521     }
522     if (new_ts == 0)
523 	new_ts = curbuf->b_p_ts;
524     for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum)
525     {
526 	ptr = ml_get(lnum);
527 	col = 0;
528 	vcol = 0;
529 	did_undo = FALSE;
530 	for (;;)
531 	{
532 	    if (vim_iswhite(ptr[col]))
533 	    {
534 		if (!got_tab && num_spaces == 0)
535 		{
536 		    /* First consecutive white-space */
537 		    start_vcol = vcol;
538 		    start_col = col;
539 		}
540 		if (ptr[col] == ' ')
541 		    num_spaces++;
542 		else
543 		    got_tab = TRUE;
544 	    }
545 	    else
546 	    {
547 		if (got_tab || (eap->forceit && num_spaces > 1))
548 		{
549 		    /* Retabulate this string of white-space */
550 
551 		    /* len is virtual length of white string */
552 		    len = num_spaces = vcol - start_vcol;
553 		    num_tabs = 0;
554 		    if (!curbuf->b_p_et)
555 		    {
556 			temp = new_ts - (start_vcol % new_ts);
557 			if (num_spaces >= temp)
558 			{
559 			    num_spaces -= temp;
560 			    num_tabs++;
561 			}
562 			num_tabs += num_spaces / new_ts;
563 			num_spaces -= (num_spaces / new_ts) * new_ts;
564 		    }
565 		    if (curbuf->b_p_et || got_tab ||
566 					(num_spaces + num_tabs < len))
567 		    {
568 			if (did_undo == FALSE)
569 			{
570 			    did_undo = TRUE;
571 			    if (u_save((linenr_T)(lnum - 1),
572 						(linenr_T)(lnum + 1)) == FAIL)
573 			    {
574 				new_line = NULL;	/* flag out-of-memory */
575 				break;
576 			    }
577 			}
578 
579 			/* len is actual number of white characters used */
580 			len = num_spaces + num_tabs;
581 			old_len = (long)STRLEN(ptr);
582 			new_line = lalloc(old_len - col + start_col + len + 1,
583 									TRUE);
584 			if (new_line == NULL)
585 			    break;
586 			if (start_col > 0)
587 			    mch_memmove(new_line, ptr, (size_t)start_col);
588 			mch_memmove(new_line + start_col + len,
589 				      ptr + col, (size_t)(old_len - col + 1));
590 			ptr = new_line + start_col;
591 			for (col = 0; col < len; col++)
592 			    ptr[col] = (col < num_tabs) ? '\t' : ' ';
593 			ml_replace(lnum, new_line, FALSE);
594 			if (first_line == 0)
595 			    first_line = lnum;
596 			last_line = lnum;
597 			ptr = new_line;
598 			col = start_col + len;
599 		    }
600 		}
601 		got_tab = FALSE;
602 		num_spaces = 0;
603 	    }
604 	    if (ptr[col] == NUL)
605 		break;
606 	    vcol += chartabsize(ptr + col, (colnr_T)vcol);
607 #ifdef FEAT_MBYTE
608 	    if (has_mbyte)
609 		col += (*mb_ptr2len)(ptr + col);
610 	    else
611 #endif
612 		++col;
613 	}
614 	if (new_line == NULL)		    /* out of memory */
615 	    break;
616 	line_breakcheck();
617     }
618     if (got_int)
619 	EMSG(_(e_interr));
620 
621     if (curbuf->b_p_ts != new_ts)
622 	redraw_curbuf_later(NOT_VALID);
623     if (first_line != 0)
624 	changed_lines(first_line, 0, last_line + 1, 0L);
625 
626     curwin->w_p_list = save_list;	/* restore 'list' */
627 
628     curbuf->b_p_ts = new_ts;
629     coladvance(curwin->w_curswant);
630 
631     u_clearline();
632 }
633 #endif
634 
635 /*
636  * :move command - move lines line1-line2 to line dest
637  *
638  * return FAIL for failure, OK otherwise
639  */
640     int
641 do_move(line1, line2, dest)
642     linenr_T	line1;
643     linenr_T	line2;
644     linenr_T	dest;
645 {
646     char_u	*str;
647     linenr_T	l;
648     linenr_T	extra;	    /* Num lines added before line1 */
649     linenr_T	num_lines;  /* Num lines moved */
650     linenr_T	last_line;  /* Last line in file after adding new text */
651 
652     if (dest >= line1 && dest < line2)
653     {
654 	EMSG(_("E134: Move lines into themselves"));
655 	return FAIL;
656     }
657 
658     num_lines = line2 - line1 + 1;
659 
660     /*
661      * First we copy the old text to its new location -- webb
662      * Also copy the flag that ":global" command uses.
663      */
664     if (u_save(dest, dest + 1) == FAIL)
665 	return FAIL;
666     for (extra = 0, l = line1; l <= line2; l++)
667     {
668 	str = vim_strsave(ml_get(l + extra));
669 	if (str != NULL)
670 	{
671 	    ml_append(dest + l - line1, str, (colnr_T)0, FALSE);
672 	    vim_free(str);
673 	    if (dest < line1)
674 		extra++;
675 	}
676     }
677 
678     /*
679      * Now we must be careful adjusting our marks so that we don't overlap our
680      * mark_adjust() calls.
681      *
682      * We adjust the marks within the old text so that they refer to the
683      * last lines of the file (temporarily), because we know no other marks
684      * will be set there since these line numbers did not exist until we added
685      * our new lines.
686      *
687      * Then we adjust the marks on lines between the old and new text positions
688      * (either forwards or backwards).
689      *
690      * And Finally we adjust the marks we put at the end of the file back to
691      * their final destination at the new text position -- webb
692      */
693     last_line = curbuf->b_ml.ml_line_count;
694     mark_adjust(line1, line2, last_line - line2, 0L);
695     if (dest >= line2)
696     {
697 	mark_adjust(line2 + 1, dest, -num_lines, 0L);
698 	curbuf->b_op_start.lnum = dest - num_lines + 1;
699 	curbuf->b_op_end.lnum = dest;
700     }
701     else
702     {
703 	mark_adjust(dest + 1, line1 - 1, num_lines, 0L);
704 	curbuf->b_op_start.lnum = dest + 1;
705 	curbuf->b_op_end.lnum = dest + num_lines;
706     }
707     curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
708     mark_adjust(last_line - num_lines + 1, last_line,
709 					     -(last_line - dest - extra), 0L);
710 
711     /*
712      * Now we delete the original text -- webb
713      */
714     if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL)
715 	return FAIL;
716 
717     for (l = line1; l <= line2; l++)
718 	ml_delete(line1 + extra, TRUE);
719 
720     if (!global_busy && num_lines > p_report)
721     {
722 	if (num_lines == 1)
723 	    MSG(_("1 line moved"));
724 	else
725 	    smsg((char_u *)_("%ld lines moved"), num_lines);
726     }
727 
728     /*
729      * Leave the cursor on the last of the moved lines.
730      */
731     if (dest >= line1)
732 	curwin->w_cursor.lnum = dest;
733     else
734 	curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
735 
736     if (line1 < dest)
737 	changed_lines(line1, 0, dest + num_lines + 1, 0L);
738     else
739 	changed_lines(dest + 1, 0, line1 + num_lines, 0L);
740 
741     return OK;
742 }
743 
744 /*
745  * ":copy"
746  */
747     void
748 ex_copy(line1, line2, n)
749     linenr_T	line1;
750     linenr_T	line2;
751     linenr_T	n;
752 {
753     linenr_T	count;
754     char_u	*p;
755 
756     count = line2 - line1 + 1;
757     curbuf->b_op_start.lnum = n + 1;
758     curbuf->b_op_end.lnum = n + count;
759     curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
760 
761     /*
762      * there are three situations:
763      * 1. destination is above line1
764      * 2. destination is between line1 and line2
765      * 3. destination is below line2
766      *
767      * n = destination (when starting)
768      * curwin->w_cursor.lnum = destination (while copying)
769      * line1 = start of source (while copying)
770      * line2 = end of source (while copying)
771      */
772     if (u_save(n, n + 1) == FAIL)
773 	return;
774 
775     curwin->w_cursor.lnum = n;
776     while (line1 <= line2)
777     {
778 	/* need to use vim_strsave() because the line will be unlocked within
779 	 * ml_append() */
780 	p = vim_strsave(ml_get(line1));
781 	if (p != NULL)
782 	{
783 	    ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, FALSE);
784 	    vim_free(p);
785 	}
786 	/* situation 2: skip already copied lines */
787 	if (line1 == n)
788 	    line1 = curwin->w_cursor.lnum;
789 	++line1;
790 	if (curwin->w_cursor.lnum < line1)
791 	    ++line1;
792 	if (curwin->w_cursor.lnum < line2)
793 	    ++line2;
794 	++curwin->w_cursor.lnum;
795     }
796 
797     appended_lines_mark(n, count);
798 
799     msgmore((long)count);
800 }
801 
802 static char_u	*prevcmd = NULL;	/* the previous command */
803 
804 #if defined(EXITFREE) || defined(PROTO)
805     void
806 free_prev_shellcmd()
807 {
808     vim_free(prevcmd);
809 }
810 #endif
811 
812 /*
813  * Handle the ":!cmd" command.	Also for ":r !cmd" and ":w !cmd"
814  * Bangs in the argument are replaced with the previously entered command.
815  * Remember the argument.
816  *
817  * RISCOS: Bangs only replaced when followed by a space, since many
818  * pathnames contain one.
819  */
820     void
821 do_bang(addr_count, eap, forceit, do_in, do_out)
822     int		addr_count;
823     exarg_T	*eap;
824     int		forceit;
825     int		do_in, do_out;
826 {
827     char_u		*arg = eap->arg;	/* command */
828     linenr_T		line1 = eap->line1;	/* start of range */
829     linenr_T		line2 = eap->line2;	/* end of range */
830     char_u		*newcmd = NULL;		/* the new command */
831     int			free_newcmd = FALSE;    /* need to free() newcmd */
832     int			ins_prevcmd;
833     char_u		*t;
834     char_u		*p;
835     char_u		*trailarg;
836     int			len;
837     int			scroll_save = msg_scroll;
838 
839     /*
840      * Disallow shell commands for "rvim".
841      * Disallow shell commands from .exrc and .vimrc in current directory for
842      * security reasons.
843      */
844     if (check_restricted() || check_secure())
845 	return;
846 
847     if (addr_count == 0)		/* :! */
848     {
849 	msg_scroll = FALSE;	    /* don't scroll here */
850 	autowrite_all();
851 	msg_scroll = scroll_save;
852     }
853 
854     /*
855      * Try to find an embedded bang, like in :!<cmd> ! [args]
856      * (:!! is indicated by the 'forceit' variable)
857      */
858     ins_prevcmd = forceit;
859     trailarg = arg;
860     do
861     {
862 	len = (int)STRLEN(trailarg) + 1;
863 	if (newcmd != NULL)
864 	    len += (int)STRLEN(newcmd);
865 	if (ins_prevcmd)
866 	{
867 	    if (prevcmd == NULL)
868 	    {
869 		EMSG(_(e_noprev));
870 		vim_free(newcmd);
871 		return;
872 	    }
873 	    len += (int)STRLEN(prevcmd);
874 	}
875 	if ((t = alloc(len)) == NULL)
876 	{
877 	    vim_free(newcmd);
878 	    return;
879 	}
880 	*t = NUL;
881 	if (newcmd != NULL)
882 	    STRCAT(t, newcmd);
883 	if (ins_prevcmd)
884 	    STRCAT(t, prevcmd);
885 	p = t + STRLEN(t);
886 	STRCAT(t, trailarg);
887 	vim_free(newcmd);
888 	newcmd = t;
889 
890 	/*
891 	 * Scan the rest of the argument for '!', which is replaced by the
892 	 * previous command.  "\!" is replaced by "!" (this is vi compatible).
893 	 */
894 	trailarg = NULL;
895 	while (*p)
896 	{
897 	    if (*p == '!'
898 #ifdef RISCOS
899 			&& (p[1] == ' ' || p[1] == NUL)
900 #endif
901 					)
902 	    {
903 		if (p > newcmd && p[-1] == '\\')
904 		    mch_memmove(p - 1, p, (size_t)(STRLEN(p) + 1));
905 		else
906 		{
907 		    trailarg = p;
908 		    *trailarg++ = NUL;
909 		    ins_prevcmd = TRUE;
910 		    break;
911 		}
912 	    }
913 	    ++p;
914 	}
915     } while (trailarg != NULL);
916 
917     vim_free(prevcmd);
918     prevcmd = newcmd;
919 
920     if (bangredo)	    /* put cmd in redo buffer for ! command */
921     {
922 	AppendToRedobuffLit(prevcmd, -1);
923 	AppendToRedobuff((char_u *)"\n");
924 	bangredo = FALSE;
925     }
926     /*
927      * Add quotes around the command, for shells that need them.
928      */
929     if (*p_shq != NUL)
930     {
931 	newcmd = alloc((unsigned)(STRLEN(prevcmd) + 2 * STRLEN(p_shq) + 1));
932 	if (newcmd == NULL)
933 	    return;
934 	STRCPY(newcmd, p_shq);
935 	STRCAT(newcmd, prevcmd);
936 	STRCAT(newcmd, p_shq);
937 	free_newcmd = TRUE;
938     }
939     if (addr_count == 0)		/* :! */
940     {
941 	/* echo the command */
942 	msg_start();
943 	msg_putchar(':');
944 	msg_putchar('!');
945 	msg_outtrans(newcmd);
946 	msg_clr_eos();
947 	windgoto(msg_row, msg_col);
948 
949 	do_shell(newcmd, 0);
950     }
951     else				/* :range! */
952     {
953 	/* Careful: This may recursively call do_bang() again! (because of
954 	 * autocommands) */
955 	do_filter(line1, line2, eap, newcmd, do_in, do_out);
956 #ifdef FEAT_AUTOCMD
957 	apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, FALSE, curbuf);
958 #endif
959     }
960     if (free_newcmd)
961 	vim_free(newcmd);
962 }
963 
964 /*
965  * do_filter: filter lines through a command given by the user
966  *
967  * We mostly use temp files and the call_shell() routine here. This would
968  * normally be done using pipes on a UNIX machine, but this is more portable
969  * to non-unix machines. The call_shell() routine needs to be able
970  * to deal with redirection somehow, and should handle things like looking
971  * at the PATH env. variable, and adding reasonable extensions to the
972  * command name given by the user. All reasonable versions of call_shell()
973  * do this.
974  * Alternatively, if on Unix and redirecting input or output, but not both,
975  * and the 'shelltemp' option isn't set, use pipes.
976  * We use input redirection if do_in is TRUE.
977  * We use output redirection if do_out is TRUE.
978  */
979     static void
980 do_filter(line1, line2, eap, cmd, do_in, do_out)
981     linenr_T	line1, line2;
982     exarg_T	*eap;		/* for forced 'ff' and 'fenc' */
983     char_u	*cmd;
984     int		do_in, do_out;
985 {
986     char_u	*itmp = NULL;
987     char_u	*otmp = NULL;
988     linenr_T	linecount;
989     linenr_T	read_linecount;
990     pos_T	cursor_save;
991     char_u	*cmd_buf;
992 #ifdef FEAT_AUTOCMD
993     buf_T	*old_curbuf = curbuf;
994 #endif
995     int		shell_flags = 0;
996 
997     if (*cmd == NUL)	    /* no filter command */
998 	return;
999 
1000 #ifdef WIN3264
1001     /*
1002      * Check if external commands are allowed now.
1003      */
1004     if (can_end_termcap_mode(TRUE) == FALSE)
1005 	return;
1006 #endif
1007 
1008     cursor_save = curwin->w_cursor;
1009     linecount = line2 - line1 + 1;
1010     curwin->w_cursor.lnum = line1;
1011     curwin->w_cursor.col = 0;
1012     changed_line_abv_curs();
1013     invalidate_botline();
1014 
1015     /*
1016      * When using temp files:
1017      * 1. * Form temp file names
1018      * 2. * Write the lines to a temp file
1019      * 3.   Run the filter command on the temp file
1020      * 4. * Read the output of the command into the buffer
1021      * 5. * Delete the original lines to be filtered
1022      * 6. * Remove the temp files
1023      *
1024      * When writing the input with a pipe or when catching the output with a
1025      * pipe only need to do 3.
1026      */
1027 
1028     if (do_out)
1029 	shell_flags |= SHELL_DOOUT;
1030 
1031 #if !defined(USE_SYSTEM) && defined(UNIX)
1032     if (!do_in && do_out && !p_stmp)
1033     {
1034 	/* Use a pipe to fetch stdout of the command, do not use a temp file. */
1035 	shell_flags |= SHELL_READ;
1036 	curwin->w_cursor.lnum = line2;
1037     }
1038     else if (do_in && !do_out && !p_stmp)
1039     {
1040 	/* Use a pipe to write stdin of the command, do not use a temp file. */
1041 	shell_flags |= SHELL_WRITE;
1042 	curbuf->b_op_start.lnum = line1;
1043 	curbuf->b_op_end.lnum = line2;
1044     }
1045     else if (do_in && do_out && !p_stmp)
1046     {
1047 	/* Use a pipe to write stdin and fetch stdout of the command, do not
1048 	 * use a temp file. */
1049 	shell_flags |= SHELL_READ|SHELL_WRITE;
1050 	curbuf->b_op_start.lnum = line1;
1051 	curbuf->b_op_end.lnum = line2;
1052 	curwin->w_cursor.lnum = line2;
1053     }
1054     else
1055 #endif
1056 	if ((do_in && (itmp = vim_tempname('i')) == NULL)
1057 		|| (do_out && (otmp = vim_tempname('o')) == NULL))
1058 	{
1059 	    EMSG(_(e_notmp));
1060 	    goto filterend;
1061 	}
1062 
1063 /*
1064  * The writing and reading of temp files will not be shown.
1065  * Vi also doesn't do this and the messages are not very informative.
1066  */
1067     ++no_wait_return;		/* don't call wait_return() while busy */
1068     if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
1069 					   FALSE, FALSE, FALSE, TRUE) == FAIL)
1070     {
1071 	msg_putchar('\n');		/* keep message from buf_write() */
1072 	--no_wait_return;
1073 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
1074 	if (!aborting())
1075 #endif
1076 	    (void)EMSG2(_(e_notcreate), itmp);	/* will call wait_return */
1077 	goto filterend;
1078     }
1079 #ifdef FEAT_AUTOCMD
1080     if (curbuf != old_curbuf)
1081 	goto filterend;
1082 #endif
1083 
1084     if (!do_out)
1085 	msg_putchar('\n');
1086 
1087     cmd_buf = make_filter_cmd(cmd, itmp, otmp);
1088     if (cmd_buf == NULL)
1089 	goto filterend;
1090 
1091     windgoto((int)Rows - 1, 0);
1092     cursor_on();
1093 
1094     /*
1095      * When not redirecting the output the command can write anything to the
1096      * screen. If 'shellredir' is equal to ">", screen may be messed up by
1097      * stderr output of external command. Clear the screen later.
1098      * If do_in is FALSE, this could be something like ":r !cat", which may
1099      * also mess up the screen, clear it later.
1100      */
1101     if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in)
1102 	redraw_later_clear();
1103 
1104     if (do_out)
1105     {
1106 	if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
1107 	    goto error;
1108 	redraw_curbuf_later(VALID);
1109     }
1110     read_linecount = curbuf->b_ml.ml_line_count;
1111 
1112     /*
1113      * When call_shell() fails wait_return() is called to give the user a
1114      * chance to read the error messages. Otherwise errors are ignored, so you
1115      * can see the error messages from the command that appear on stdout; use
1116      * 'u' to fix the text
1117      * Switch to cooked mode when not redirecting stdin, avoids that something
1118      * like ":r !cat" hangs.
1119      * Pass on the SHELL_DOOUT flag when the output is being redirected.
1120      */
1121     if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED | shell_flags))
1122     {
1123 	redraw_later_clear();
1124 	wait_return(FALSE);
1125     }
1126     vim_free(cmd_buf);
1127 
1128     did_check_timestamps = FALSE;
1129     need_check_timestamps = TRUE;
1130 
1131     /* When interrupting the shell command, it may still have produced some
1132      * useful output.  Reset got_int here, so that readfile() won't cancel
1133      * reading. */
1134     ui_breakcheck();
1135     got_int = FALSE;
1136 
1137     if (do_out)
1138     {
1139 	if (otmp != NULL)
1140 	{
1141 	    if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
1142 						    eap, READ_FILTER) == FAIL)
1143 	    {
1144 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
1145 		if (!aborting())
1146 #endif
1147 		{
1148 		    msg_putchar('\n');
1149 		    EMSG2(_(e_notread), otmp);
1150 		}
1151 		goto error;
1152 	    }
1153 #ifdef FEAT_AUTOCMD
1154 	    if (curbuf != old_curbuf)
1155 		goto filterend;
1156 #endif
1157 	}
1158 
1159 	read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
1160 
1161 	if (shell_flags & SHELL_READ)
1162 	{
1163 	    curbuf->b_op_start.lnum = line2 + 1;
1164 	    curbuf->b_op_end.lnum = curwin->w_cursor.lnum;
1165 	    appended_lines_mark(line2, read_linecount);
1166 	}
1167 
1168 	if (do_in)
1169 	{
1170 	    if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL)
1171 	    {
1172 		if (read_linecount >= linecount)
1173 		    /* move all marks from old lines to new lines */
1174 		    mark_adjust(line1, line2, linecount, 0L);
1175 		else
1176 		{
1177 		    /* move marks from old lines to new lines, delete marks
1178 		     * that are in deleted lines */
1179 		    mark_adjust(line1, line1 + read_linecount - 1,
1180 								linecount, 0L);
1181 		    mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L);
1182 		}
1183 	    }
1184 
1185 	    /*
1186 	     * Put cursor on first filtered line for ":range!cmd".
1187 	     * Adjust '[ and '] (set by buf_write()).
1188 	     */
1189 	    curwin->w_cursor.lnum = line1;
1190 	    del_lines(linecount, TRUE);
1191 	    curbuf->b_op_start.lnum -= linecount;	/* adjust '[ */
1192 	    curbuf->b_op_end.lnum -= linecount;		/* adjust '] */
1193 	    write_lnum_adjust(-linecount);		/* adjust last line
1194 							   for next write */
1195 #ifdef FEAT_FOLDING
1196 	    foldUpdate(curwin, curbuf->b_op_start.lnum, curbuf->b_op_end.lnum);
1197 #endif
1198 	}
1199 	else
1200 	{
1201 	    /*
1202 	     * Put cursor on last new line for ":r !cmd".
1203 	     */
1204 	    linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
1205 	    curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
1206 	}
1207 
1208 	beginline(BL_WHITE | BL_FIX);	    /* cursor on first non-blank */
1209 	--no_wait_return;
1210 
1211 	if (linecount > p_report)
1212 	{
1213 	    if (do_in)
1214 	    {
1215 		vim_snprintf((char *)msg_buf, sizeof(msg_buf),
1216 				    _("%ld lines filtered"), (long)linecount);
1217 		if (msg(msg_buf) && !msg_scroll)
1218 		    /* save message to display it after redraw */
1219 		    set_keep_msg(msg_buf, 0);
1220 	    }
1221 	    else
1222 		msgmore((long)linecount);
1223 	}
1224     }
1225     else
1226     {
1227 error:
1228 	/* put cursor back in same position for ":w !cmd" */
1229 	curwin->w_cursor = cursor_save;
1230 	--no_wait_return;
1231 	wait_return(FALSE);
1232     }
1233 
1234 filterend:
1235 
1236 #ifdef FEAT_AUTOCMD
1237     if (curbuf != old_curbuf)
1238     {
1239 	--no_wait_return;
1240 	EMSG(_("E135: *Filter* Autocommands must not change current buffer"));
1241     }
1242 #endif
1243     if (itmp != NULL)
1244 	mch_remove(itmp);
1245     if (otmp != NULL)
1246 	mch_remove(otmp);
1247     vim_free(itmp);
1248     vim_free(otmp);
1249 }
1250 
1251 /*
1252  * Call a shell to execute a command.
1253  * When "cmd" is NULL start an interactive shell.
1254  */
1255     void
1256 do_shell(cmd, flags)
1257     char_u	*cmd;
1258     int		flags;	/* may be SHELL_DOOUT when output is redirected */
1259 {
1260     buf_T	*buf;
1261 #ifndef FEAT_GUI_MSWIN
1262     int		save_nwr;
1263 #endif
1264 #ifdef MSWIN
1265     int		winstart = FALSE;
1266 #endif
1267 
1268     /*
1269      * Disallow shell commands for "rvim".
1270      * Disallow shell commands from .exrc and .vimrc in current directory for
1271      * security reasons.
1272      */
1273     if (check_restricted() || check_secure())
1274     {
1275 	msg_end();
1276 	return;
1277     }
1278 
1279 #ifdef MSWIN
1280     /*
1281      * Check if external commands are allowed now.
1282      */
1283     if (can_end_termcap_mode(TRUE) == FALSE)
1284 	return;
1285 
1286     /*
1287      * Check if ":!start" is used.
1288      */
1289     if (cmd != NULL)
1290 	winstart = (STRNICMP(cmd, "start ", 6) == 0);
1291 #endif
1292 
1293     /*
1294      * For autocommands we want to get the output on the current screen, to
1295      * avoid having to type return below.
1296      */
1297     msg_putchar('\r');			/* put cursor at start of line */
1298 #ifdef FEAT_AUTOCMD
1299     if (!autocmd_busy)
1300 #endif
1301     {
1302 #ifdef MSWIN
1303 	if (!winstart)
1304 #endif
1305 	    stoptermcap();
1306     }
1307 #ifdef MSWIN
1308     if (!winstart)
1309 #endif
1310 	msg_putchar('\n');		/* may shift screen one line up */
1311 
1312     /* warning message before calling the shell */
1313     if (p_warn
1314 #ifdef FEAT_AUTOCMD
1315 		&& !autocmd_busy
1316 #endif
1317 		&& msg_silent == 0)
1318 	for (buf = firstbuf; buf; buf = buf->b_next)
1319 	    if (bufIsChanged(buf))
1320 	    {
1321 #ifdef FEAT_GUI_MSWIN
1322 		if (!winstart)
1323 		    starttermcap();	/* don't want a message box here */
1324 #endif
1325 		MSG_PUTS(_("[No write since last change]\n"));
1326 #ifdef FEAT_GUI_MSWIN
1327 		if (!winstart)
1328 		    stoptermcap();
1329 #endif
1330 		break;
1331 	    }
1332 
1333     /* This windgoto is required for when the '\n' resulted in a "delete line
1334      * 1" command to the terminal. */
1335     if (!swapping_screen())
1336 	windgoto(msg_row, msg_col);
1337     cursor_on();
1338     (void)call_shell(cmd, SHELL_COOKED | flags);
1339     did_check_timestamps = FALSE;
1340     need_check_timestamps = TRUE;
1341 
1342     /*
1343      * put the message cursor at the end of the screen, avoids wait_return()
1344      * to overwrite the text that the external command showed
1345      */
1346     if (!swapping_screen())
1347     {
1348 	msg_row = Rows - 1;
1349 	msg_col = 0;
1350     }
1351 
1352 #ifdef FEAT_AUTOCMD
1353     if (autocmd_busy)
1354     {
1355 	if (msg_silent == 0)
1356 	    redraw_later_clear();
1357     }
1358     else
1359 #endif
1360     {
1361 	/*
1362 	 * For ":sh" there is no need to call wait_return(), just redraw.
1363 	 * Also for the Win32 GUI (the output is in a console window).
1364 	 * Otherwise there is probably text on the screen that the user wants
1365 	 * to read before redrawing, so call wait_return().
1366 	 */
1367 #ifndef FEAT_GUI_MSWIN
1368 	if (cmd == NULL
1369 # ifdef WIN3264
1370 		|| (winstart && !need_wait_return)
1371 # endif
1372 	   )
1373 	{
1374 	    if (msg_silent == 0)
1375 		redraw_later_clear();
1376 	    need_wait_return = FALSE;
1377 	}
1378 	else
1379 	{
1380 	    /*
1381 	     * If we switch screens when starttermcap() is called, we really
1382 	     * want to wait for "hit return to continue".
1383 	     */
1384 	    save_nwr = no_wait_return;
1385 	    if (swapping_screen())
1386 		no_wait_return = FALSE;
1387 # ifdef AMIGA
1388 	    wait_return(term_console ? -1 : msg_silent == 0);	/* see below */
1389 # else
1390 	    wait_return(msg_silent == 0);
1391 # endif
1392 	    no_wait_return = save_nwr;
1393 	}
1394 #endif /* FEAT_GUI_W32 */
1395 
1396 #ifdef MSWIN
1397 	if (!winstart) /* if winstart==TRUE, never stopped termcap! */
1398 #endif
1399 	    starttermcap();	/* start termcap if not done by wait_return() */
1400 
1401 	/*
1402 	 * In an Amiga window redrawing is caused by asking the window size.
1403 	 * If we got an interrupt this will not work. The chance that the
1404 	 * window size is wrong is very small, but we need to redraw the
1405 	 * screen.  Don't do this if ':' hit in wait_return().	THIS IS UGLY
1406 	 * but it saves an extra redraw.
1407 	 */
1408 #ifdef AMIGA
1409 	if (skip_redraw)		/* ':' hit in wait_return() */
1410 	{
1411 	    if (msg_silent == 0)
1412 		redraw_later_clear();
1413 	}
1414 	else if (term_console)
1415 	{
1416 	    OUT_STR(IF_EB("\033[0 q", ESC_STR "[0 q"));	/* get window size */
1417 	    if (got_int && msg_silent == 0)
1418 		redraw_later_clear();	/* if got_int is TRUE, redraw needed */
1419 	    else
1420 		must_redraw = 0;	/* no extra redraw needed */
1421 	}
1422 #endif
1423     }
1424 
1425     /* display any error messages now */
1426     display_errors();
1427 
1428 #ifdef FEAT_AUTOCMD
1429     apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf);
1430 #endif
1431 }
1432 
1433 /*
1434  * Create a shell command from a command string, input redirection file and
1435  * output redirection file.
1436  * Returns an allocated string with the shell command, or NULL for failure.
1437  */
1438     char_u *
1439 make_filter_cmd(cmd, itmp, otmp)
1440     char_u	*cmd;		/* command */
1441     char_u	*itmp;		/* NULL or name of input file */
1442     char_u	*otmp;		/* NULL or name of output file */
1443 {
1444     char_u	*buf;
1445     long_u	len;
1446 
1447     len = (long_u)STRLEN(cmd) + 3;			/* "()" + NUL */
1448     if (itmp != NULL)
1449 	len += (long_u)STRLEN(itmp) + 9;		/* " { < " + " } " */
1450     if (otmp != NULL)
1451 	len += (long_u)STRLEN(otmp) + (long_u)STRLEN(p_srr) + 2; /* "  " */
1452     buf = lalloc(len, TRUE);
1453     if (buf == NULL)
1454 	return NULL;
1455 
1456 #if (defined(UNIX) && !defined(ARCHIE)) || defined(OS2)
1457     /*
1458      * Put braces around the command (for concatenated commands) when
1459      * redirecting input and/or output.
1460      */
1461     if (itmp != NULL || otmp != NULL)
1462 	sprintf((char *)buf, "(%s)", (char *)cmd);
1463     else
1464 	STRCPY(buf, cmd);
1465     if (itmp != NULL)
1466     {
1467 	STRCAT(buf, " < ");
1468 	STRCAT(buf, itmp);
1469     }
1470 #else
1471     /*
1472      * for shells that don't understand braces around commands, at least allow
1473      * the use of commands in a pipe.
1474      */
1475     STRCPY(buf, cmd);
1476     if (itmp != NULL)
1477     {
1478 	char_u	*p;
1479 
1480 	/*
1481 	 * If there is a pipe, we have to put the '<' in front of it.
1482 	 * Don't do this when 'shellquote' is not empty, otherwise the
1483 	 * redirection would be inside the quotes.
1484 	 */
1485 	if (*p_shq == NUL)
1486 	{
1487 	    p = vim_strchr(buf, '|');
1488 	    if (p != NULL)
1489 		*p = NUL;
1490 	}
1491 # ifdef RISCOS
1492 	STRCAT(buf, " { < ");	/* Use RISC OS notation for input. */
1493 	STRCAT(buf, itmp);
1494 	STRCAT(buf, " } ");
1495 # else
1496 	STRCAT(buf, " <");	/* " < " causes problems on Amiga */
1497 	STRCAT(buf, itmp);
1498 # endif
1499 	if (*p_shq == NUL)
1500 	{
1501 	    p = vim_strchr(cmd, '|');
1502 	    if (p != NULL)
1503 	    {
1504 		STRCAT(buf, " ");   /* insert a space before the '|' for DOS */
1505 		STRCAT(buf, p);
1506 	    }
1507 	}
1508     }
1509 #endif
1510     if (otmp != NULL)
1511 	append_redir(buf, p_srr, otmp);
1512 
1513     return buf;
1514 }
1515 
1516 /*
1517  * Append output redirection for file "fname" to the end of string buffer "buf"
1518  * Works with the 'shellredir' and 'shellpipe' options.
1519  * The caller should make sure that there is enough room:
1520  *	STRLEN(opt) + STRLEN(fname) + 3
1521  */
1522     void
1523 append_redir(buf, opt, fname)
1524     char_u	*buf;
1525     char_u	*opt;
1526     char_u	*fname;
1527 {
1528     char_u	*p;
1529 
1530     buf += STRLEN(buf);
1531     /* find "%s", skipping "%%" */
1532     for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p)
1533 	if (p[1] == 's')
1534 	    break;
1535     if (p != NULL)
1536     {
1537 	*buf = ' '; /* not really needed? Not with sh, ksh or bash */
1538 	sprintf((char *)buf + 1, (char *)opt, (char *)fname);
1539     }
1540     else
1541 	sprintf((char *)buf,
1542 #ifdef FEAT_QUICKFIX
1543 # ifndef RISCOS
1544 		opt != p_sp ? " %s%s" :
1545 # endif
1546 		" %s %s",
1547 #else
1548 # ifndef RISCOS
1549 		" %s%s",	/* " > %s" causes problems on Amiga */
1550 # else
1551 		" %s %s",	/* But is needed for 'shellpipe' and RISC OS */
1552 # endif
1553 #endif
1554 		(char *)opt, (char *)fname);
1555 }
1556 
1557 #ifdef FEAT_VIMINFO
1558 
1559 static int no_viminfo __ARGS((void));
1560 static int  viminfo_errcnt;
1561 
1562     static int
1563 no_viminfo()
1564 {
1565     /* "vim -i NONE" does not read or write a viminfo file */
1566     return (use_viminfo != NULL && STRCMP(use_viminfo, "NONE") == 0);
1567 }
1568 
1569 /*
1570  * Report an error for reading a viminfo file.
1571  * Count the number of errors.	When there are more than 10, return TRUE.
1572  */
1573     int
1574 viminfo_error(errnum, message, line)
1575     char    *errnum;
1576     char    *message;
1577     char_u  *line;
1578 {
1579     vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "),
1580 							     errnum, message);
1581     STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff));
1582     if (IObuff[STRLEN(IObuff) - 1] == '\n')
1583 	IObuff[STRLEN(IObuff) - 1] = NUL;
1584     emsg(IObuff);
1585     if (++viminfo_errcnt >= 10)
1586     {
1587 	EMSG(_("E136: viminfo: Too many errors, skipping rest of file"));
1588 	return TRUE;
1589     }
1590     return FALSE;
1591 }
1592 
1593 /*
1594  * read_viminfo() -- Read the viminfo file.  Registers etc. which are already
1595  * set are not over-written unless force is TRUE. -- webb
1596  */
1597     int
1598 read_viminfo(file, want_info, want_marks, forceit)
1599     char_u	*file;
1600     int		want_info;
1601     int		want_marks;
1602     int		forceit;
1603 {
1604     FILE	*fp;
1605     char_u	*fname;
1606 
1607     if (no_viminfo())
1608 	return FAIL;
1609 
1610     fname = viminfo_filename(file);	    /* may set to default if NULL */
1611     if (fname == NULL)
1612 	return FAIL;
1613     fp = mch_fopen((char *)fname, READBIN);
1614 
1615     if (p_verbose > 0)
1616     {
1617 	verbose_enter();
1618 	smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
1619 		fname,
1620 		want_info ? _(" info") : "",
1621 		want_marks ? _(" marks") : "",
1622 		fp == NULL ? _(" FAILED") : "");
1623 	verbose_leave();
1624     }
1625 
1626     vim_free(fname);
1627     if (fp == NULL)
1628 	return FAIL;
1629 
1630     viminfo_errcnt = 0;
1631     do_viminfo(fp, NULL, want_info, want_marks, forceit);
1632 
1633     fclose(fp);
1634 
1635     return OK;
1636 }
1637 
1638 /*
1639  * write_viminfo() -- Write the viminfo file.  The old one is read in first so
1640  * that effectively a merge of current info and old info is done.  This allows
1641  * multiple vims to run simultaneously, without losing any marks etc.  If
1642  * forceit is TRUE, then the old file is not read in, and only internal info is
1643  * written to the file. -- webb
1644  */
1645     void
1646 write_viminfo(file, forceit)
1647     char_u	*file;
1648     int		forceit;
1649 {
1650     char_u	*fname;
1651     FILE	*fp_in = NULL;	/* input viminfo file, if any */
1652     FILE	*fp_out = NULL;	/* output viminfo file */
1653     char_u	*tempname = NULL;	/* name of temp viminfo file */
1654     struct stat	st_new;		/* mch_stat() of potential new file */
1655     char_u	*wp;
1656 #if defined(UNIX) || defined(VMS)
1657     mode_t	umask_save;
1658 #endif
1659 #ifdef UNIX
1660     int		shortname = FALSE;	/* use 8.3 file name */
1661     struct stat	st_old;		/* mch_stat() of existing viminfo file */
1662 #endif
1663 #ifdef WIN3264
1664     long	perm = -1;
1665 #endif
1666 
1667     if (no_viminfo())
1668 	return;
1669 
1670     fname = viminfo_filename(file);	/* may set to default if NULL */
1671     if (fname == NULL)
1672 	return;
1673 
1674     fp_in = mch_fopen((char *)fname, READBIN);
1675     if (fp_in == NULL)
1676     {
1677 	/* if it does exist, but we can't read it, don't try writing */
1678 	if (mch_stat((char *)fname, &st_new) == 0)
1679 	    goto end;
1680 #if defined(UNIX) || defined(VMS)
1681 	/*
1682 	 * For Unix we create the .viminfo non-accessible for others,
1683 	 * because it may contain text from non-accessible documents.
1684 	 */
1685 	umask_save = umask(077);
1686 #endif
1687 	fp_out = mch_fopen((char *)fname, WRITEBIN);
1688 #if defined(UNIX) || defined(VMS)
1689 	(void)umask(umask_save);
1690 #endif
1691     }
1692     else
1693     {
1694 	/*
1695 	 * There is an existing viminfo file.  Create a temporary file to
1696 	 * write the new viminfo into, in the same directory as the
1697 	 * existing viminfo file, which will be renamed later.
1698 	 */
1699 #ifdef UNIX
1700 	/*
1701 	 * For Unix we check the owner of the file.  It's not very nice to
1702 	 * overwrite a user's viminfo file after a "su root", with a
1703 	 * viminfo file that the user can't read.
1704 	 */
1705 	st_old.st_dev = st_old.st_ino = 0;
1706 	st_old.st_mode = 0600;
1707 	if (mch_stat((char *)fname, &st_old) == 0 && getuid()
1708 		&& !(st_old.st_uid == getuid()
1709 			? (st_old.st_mode & 0200)
1710 			: (st_old.st_gid == getgid()
1711 				? (st_old.st_mode & 0020)
1712 				: (st_old.st_mode & 0002))))
1713 	{
1714 	    int	tt;
1715 
1716 	    /* avoid a wait_return for this message, it's annoying */
1717 	    tt = msg_didany;
1718 	    EMSG2(_("E137: Viminfo file is not writable: %s"), fname);
1719 	    msg_didany = tt;
1720 	    goto end;
1721 	}
1722 #endif
1723 #ifdef WIN3264
1724 	/* Get the file attributes of the existing viminfo file. */
1725 	perm = mch_getperm(fname);
1726 #endif
1727 
1728 	/*
1729 	 * Make tempname.
1730 	 * May try twice: Once normal and once with shortname set, just in
1731 	 * case somebody puts his viminfo file in an 8.3 filesystem.
1732 	 */
1733 	for (;;)
1734 	{
1735 	    tempname = buf_modname(
1736 #ifdef UNIX
1737 				    shortname,
1738 #else
1739 # ifdef SHORT_FNAME
1740 				    TRUE,
1741 # else
1742 #  ifdef FEAT_GUI_W32
1743 				    gui_is_win32s(),
1744 #  else
1745 				    FALSE,
1746 #  endif
1747 # endif
1748 #endif
1749 				    fname,
1750 #ifdef VMS
1751 				    (char_u *)"-tmp",
1752 #else
1753 # ifdef RISCOS
1754 				    (char_u *)"/tmp",
1755 # else
1756 				    (char_u *)".tmp",
1757 # endif
1758 #endif
1759 				    FALSE);
1760 	    if (tempname == NULL)		/* out of memory */
1761 		break;
1762 
1763 	    /*
1764 	     * Check if tempfile already exists.  Never overwrite an
1765 	     * existing file!
1766 	     */
1767 	    if (mch_stat((char *)tempname, &st_new) == 0)
1768 	    {
1769 #ifdef UNIX
1770 		/*
1771 		 * Check if tempfile is same as original file.  May happen
1772 		 * when modname() gave the same file back.  E.g.  silly
1773 		 * link, or file name-length reached.  Try again with
1774 		 * shortname set.
1775 		 */
1776 		if (!shortname && st_new.st_dev == st_old.st_dev
1777 					    && st_new.st_ino == st_old.st_ino)
1778 		{
1779 		    vim_free(tempname);
1780 		    tempname = NULL;
1781 		    shortname = TRUE;
1782 		    continue;
1783 		}
1784 #endif
1785 		/*
1786 		 * Try another name.  Change one character, just before
1787 		 * the extension.  This should also work for an 8.3
1788 		 * file name, when after adding the extension it still is
1789 		 * the same file as the original.
1790 		 */
1791 		wp = tempname + STRLEN(tempname) - 5;
1792 		if (wp < gettail(tempname))	    /* empty file name? */
1793 		    wp = gettail(tempname);
1794 		for (*wp = 'z'; mch_stat((char *)tempname, &st_new) == 0;
1795 								    --*wp)
1796 		{
1797 		    /*
1798 		     * They all exist?  Must be something wrong! Don't
1799 		     * write the viminfo file then.
1800 		     */
1801 		    if (*wp == 'a')
1802 		    {
1803 			vim_free(tempname);
1804 			tempname = NULL;
1805 			break;
1806 		    }
1807 		}
1808 	    }
1809 	    break;
1810 	}
1811 
1812 	if (tempname != NULL)
1813 	{
1814 #ifdef VMS
1815 	    /* fdopen() fails for some reason */
1816 	    umask_save = umask(077);
1817 	    fp_out = mch_fopen((char *)tempname, WRITEBIN);
1818 	    (void)umask(umask_save);
1819 #else
1820 	    int	fd;
1821 
1822 	    /* Use mch_open() to be able to use O_NOFOLLOW and set file
1823 	     * protection:
1824 	     * Unix: same as original file, but strip s-bit.  Reset umask to
1825 	     * avoid it getting in the way.
1826 	     * Others: r&w for user only. */
1827 # ifdef UNIX
1828 	    umask_save = umask(0);
1829 	    fd = mch_open((char *)tempname,
1830 		    O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW,
1831 				       (int)((st_old.st_mode & 0777) | 0600));
1832 	    (void)umask(umask_save);
1833 # else
1834 	    fd = mch_open((char *)tempname,
1835 			    O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600);
1836 # endif
1837 	    if (fd < 0)
1838 		fp_out = NULL;
1839 	    else
1840 		fp_out = fdopen(fd, WRITEBIN);
1841 #endif /* VMS */
1842 
1843 	    /*
1844 	     * If we can't create in the same directory, try creating a
1845 	     * "normal" temp file.
1846 	     */
1847 	    if (fp_out == NULL)
1848 	    {
1849 		vim_free(tempname);
1850 		if ((tempname = vim_tempname('o')) != NULL)
1851 		    fp_out = mch_fopen((char *)tempname, WRITEBIN);
1852 	    }
1853 
1854 #if defined(UNIX) && defined(HAVE_FCHOWN)
1855 	    /*
1856 	     * Make sure the owner can read/write it.  This only works for
1857 	     * root.
1858 	     */
1859 	    if (fp_out != NULL)
1860 		(void)fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
1861 #endif
1862 	}
1863     }
1864 
1865     /*
1866      * Check if the new viminfo file can be written to.
1867      */
1868     if (fp_out == NULL)
1869     {
1870 	EMSG2(_("E138: Can't write viminfo file %s!"),
1871 		       (fp_in == NULL || tempname == NULL) ? fname : tempname);
1872 	if (fp_in != NULL)
1873 	    fclose(fp_in);
1874 	goto end;
1875     }
1876 
1877     if (p_verbose > 0)
1878     {
1879 	verbose_enter();
1880 	smsg((char_u *)_("Writing viminfo file \"%s\""), fname);
1881 	verbose_leave();
1882     }
1883 
1884     viminfo_errcnt = 0;
1885     do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE);
1886 
1887     fclose(fp_out);	    /* errors are ignored !? */
1888     if (fp_in != NULL)
1889     {
1890 	fclose(fp_in);
1891 
1892 	/*
1893 	 * In case of an error keep the original viminfo file.
1894 	 * Otherwise rename the newly written file.
1895 	 */
1896 	if (viminfo_errcnt || vim_rename(tempname, fname) == -1)
1897 	    mch_remove(tempname);
1898 
1899 #ifdef WIN3264
1900 	/* If the viminfo file was hidden then also hide the new file. */
1901 	if (perm > 0 && (perm & FILE_ATTRIBUTE_HIDDEN))
1902 	    mch_hide(fname);
1903 #endif
1904     }
1905 
1906 end:
1907     vim_free(fname);
1908     vim_free(tempname);
1909 }
1910 
1911 /*
1912  * Get the viminfo file name to use.
1913  * If "file" is given and not empty, use it (has already been expanded by
1914  * cmdline functions).
1915  * Otherwise use "-i file_name", value from 'viminfo' or the default, and
1916  * expand environment variables.
1917  * Returns an allocated string.  NULL when out of memory.
1918  */
1919     static char_u *
1920 viminfo_filename(file)
1921     char_u	*file;
1922 {
1923     if (file == NULL || *file == NUL)
1924     {
1925 	if (use_viminfo != NULL)
1926 	    file = use_viminfo;
1927 	else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL)
1928 	{
1929 #ifdef VIMINFO_FILE2
1930 	    /* don't use $HOME when not defined (turned into "c:/"!). */
1931 # ifdef VMS
1932 	    if (mch_getenv((char_u *)"SYS$LOGIN") == NULL)
1933 # else
1934 	    if (mch_getenv((char_u *)"HOME") == NULL)
1935 # endif
1936 	    {
1937 		/* don't use $VIM when not available. */
1938 		expand_env((char_u *)"$VIM", NameBuff, MAXPATHL);
1939 		if (STRCMP("$VIM", NameBuff) != 0)  /* $VIM was expanded */
1940 		    file = (char_u *)VIMINFO_FILE2;
1941 		else
1942 		    file = (char_u *)VIMINFO_FILE;
1943 	    }
1944 	    else
1945 #endif
1946 		file = (char_u *)VIMINFO_FILE;
1947 	}
1948 	expand_env(file, NameBuff, MAXPATHL);
1949 	file = NameBuff;
1950     }
1951     return vim_strsave(file);
1952 }
1953 
1954 /*
1955  * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
1956  */
1957     static void
1958 do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
1959     FILE	*fp_in;
1960     FILE	*fp_out;
1961     int		want_info;
1962     int		want_marks;
1963     int		force_read;
1964 {
1965     int		count = 0;
1966     int		eof = FALSE;
1967     vir_T	vir;
1968 
1969     if ((vir.vir_line = alloc(LSIZE)) == NULL)
1970 	return;
1971     vir.vir_fd = fp_in;
1972 #ifdef FEAT_MBYTE
1973     vir.vir_conv.vc_type = CONV_NONE;
1974 #endif
1975 
1976     if (fp_in != NULL)
1977     {
1978 	if (want_info)
1979 	    eof = read_viminfo_up_to_marks(&vir, force_read, fp_out != NULL);
1980 	else
1981 	    /* Skip info, find start of marks */
1982 	    while (!(eof = viminfo_readline(&vir))
1983 		    && vir.vir_line[0] != '>')
1984 		;
1985     }
1986     if (fp_out != NULL)
1987     {
1988 	/* Write the info: */
1989 	fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"),
1990 							  VIM_VERSION_MEDIUM);
1991 	fprintf(fp_out, _("# You may edit it if you're careful!\n\n"));
1992 #ifdef FEAT_MBYTE
1993 	fprintf(fp_out, _("# Value of 'encoding' when this file was written\n"));
1994 	fprintf(fp_out, "*encoding=%s\n\n", p_enc);
1995 #endif
1996 	write_viminfo_search_pattern(fp_out);
1997 	write_viminfo_sub_string(fp_out);
1998 #ifdef FEAT_CMDHIST
1999 	write_viminfo_history(fp_out);
2000 #endif
2001 	write_viminfo_registers(fp_out);
2002 #ifdef FEAT_EVAL
2003 	write_viminfo_varlist(fp_out);
2004 #endif
2005 	write_viminfo_filemarks(fp_out);
2006 	write_viminfo_bufferlist(fp_out);
2007 	count = write_viminfo_marks(fp_out);
2008     }
2009     if (fp_in != NULL && want_marks)
2010 	copy_viminfo_marks(&vir, fp_out, count, eof);
2011 
2012     vim_free(vir.vir_line);
2013 #ifdef FEAT_MBYTE
2014     if (vir.vir_conv.vc_type != CONV_NONE)
2015 	convert_setup(&vir.vir_conv, NULL, NULL);
2016 #endif
2017 }
2018 
2019 /*
2020  * read_viminfo_up_to_marks() -- Only called from do_viminfo().  Reads in the
2021  * first part of the viminfo file which contains everything but the marks that
2022  * are local to a file.  Returns TRUE when end-of-file is reached. -- webb
2023  */
2024     static int
2025 read_viminfo_up_to_marks(virp, forceit, writing)
2026     vir_T	*virp;
2027     int		forceit;
2028     int		writing;
2029 {
2030     int		eof;
2031     buf_T	*buf;
2032 
2033 #ifdef FEAT_CMDHIST
2034     prepare_viminfo_history(forceit ? 9999 : 0);
2035 #endif
2036     eof = viminfo_readline(virp);
2037     while (!eof && virp->vir_line[0] != '>')
2038     {
2039 	switch (virp->vir_line[0])
2040 	{
2041 		/* Characters reserved for future expansion, ignored now */
2042 	    case '+': /* "+40 /path/dir file", for running vim without args */
2043 	    case '|': /* to be defined */
2044 	    case '^': /* to be defined */
2045 	    case '<': /* long line - ignored */
2046 		/* A comment or empty line. */
2047 	    case NUL:
2048 	    case '\r':
2049 	    case '\n':
2050 	    case '#':
2051 		eof = viminfo_readline(virp);
2052 		break;
2053 	    case '*': /* "*encoding=value" */
2054 		eof = viminfo_encoding(virp);
2055 		break;
2056 	    case '!': /* global variable */
2057 #ifdef FEAT_EVAL
2058 		eof = read_viminfo_varlist(virp, writing);
2059 #else
2060 		eof = viminfo_readline(virp);
2061 #endif
2062 		break;
2063 	    case '%': /* entry for buffer list */
2064 		eof = read_viminfo_bufferlist(virp, writing);
2065 		break;
2066 	    case '"':
2067 		eof = read_viminfo_register(virp, forceit);
2068 		break;
2069 	    case '/':	    /* Search string */
2070 	    case '&':	    /* Substitute search string */
2071 	    case '~':	    /* Last search string, followed by '/' or '&' */
2072 		eof = read_viminfo_search_pattern(virp, forceit);
2073 		break;
2074 	    case '$':
2075 		eof = read_viminfo_sub_string(virp, forceit);
2076 		break;
2077 	    case ':':
2078 	    case '?':
2079 	    case '=':
2080 	    case '@':
2081 #ifdef FEAT_CMDHIST
2082 		eof = read_viminfo_history(virp);
2083 #else
2084 		eof = viminfo_readline(virp);
2085 #endif
2086 		break;
2087 	    case '-':
2088 	    case '\'':
2089 		eof = read_viminfo_filemark(virp, forceit);
2090 		break;
2091 	    default:
2092 		if (viminfo_error("E575: ", _("Illegal starting char"),
2093 			    virp->vir_line))
2094 		    eof = TRUE;
2095 		else
2096 		    eof = viminfo_readline(virp);
2097 		break;
2098 	}
2099     }
2100 
2101 #ifdef FEAT_CMDHIST
2102     /* Finish reading history items. */
2103     finish_viminfo_history();
2104 #endif
2105 
2106     /* Change file names to buffer numbers for fmarks. */
2107     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
2108 	fmarks_check_names(buf);
2109 
2110     return eof;
2111 }
2112 
2113 /*
2114  * Compare the 'encoding' value in the viminfo file with the current value of
2115  * 'encoding'.  If different and the 'c' flag is in 'viminfo', setup for
2116  * conversion of text with iconv() in viminfo_readstring().
2117  */
2118     static int
2119 viminfo_encoding(virp)
2120     vir_T	*virp;
2121 {
2122 #ifdef FEAT_MBYTE
2123     char_u	*p;
2124     int		i;
2125 
2126     if (get_viminfo_parameter('c') != 0)
2127     {
2128 	p = vim_strchr(virp->vir_line, '=');
2129 	if (p != NULL)
2130 	{
2131 	    /* remove trailing newline */
2132 	    ++p;
2133 	    for (i = 0; vim_isprintc(p[i]); ++i)
2134 		;
2135 	    p[i] = NUL;
2136 
2137 	    convert_setup(&virp->vir_conv, p, p_enc);
2138 	}
2139     }
2140 #endif
2141     return viminfo_readline(virp);
2142 }
2143 
2144 /*
2145  * Read a line from the viminfo file.
2146  * Returns TRUE for end-of-file;
2147  */
2148     int
2149 viminfo_readline(virp)
2150     vir_T	*virp;
2151 {
2152     return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
2153 }
2154 
2155 /*
2156  * check string read from viminfo file
2157  * remove '\n' at the end of the line
2158  * - replace CTRL-V CTRL-V with CTRL-V
2159  * - replace CTRL-V 'n'    with '\n'
2160  *
2161  * Check for a long line as written by viminfo_writestring().
2162  *
2163  * Return the string in allocated memory (NULL when out of memory).
2164  */
2165 /*ARGSUSED*/
2166     char_u *
2167 viminfo_readstring(virp, off, convert)
2168     vir_T	*virp;
2169     int		off;		    /* offset for virp->vir_line */
2170     int		convert;	    /* convert the string */
2171 {
2172     char_u	*retval;
2173     char_u	*s, *d;
2174     long	len;
2175 
2176     if (virp->vir_line[off] == Ctrl_V && vim_isdigit(virp->vir_line[off + 1]))
2177     {
2178 	len = atol((char *)virp->vir_line + off + 1);
2179 	retval = lalloc(len, TRUE);
2180 	if (retval == NULL)
2181 	{
2182 	    /* Line too long?  File messed up?  Skip next line. */
2183 	    (void)vim_fgets(virp->vir_line, 10, virp->vir_fd);
2184 	    return NULL;
2185 	}
2186 	(void)vim_fgets(retval, (int)len, virp->vir_fd);
2187 	s = retval + 1;	    /* Skip the leading '<' */
2188     }
2189     else
2190     {
2191 	retval = vim_strsave(virp->vir_line + off);
2192 	if (retval == NULL)
2193 	    return NULL;
2194 	s = retval;
2195     }
2196 
2197     /* Change CTRL-V CTRL-V to CTRL-V and CTRL-V n to \n in-place. */
2198     d = retval;
2199     while (*s != NUL && *s != '\n')
2200     {
2201 	if (s[0] == Ctrl_V && s[1] != NUL)
2202 	{
2203 	    if (s[1] == 'n')
2204 		*d++ = '\n';
2205 	    else
2206 		*d++ = Ctrl_V;
2207 	    s += 2;
2208 	}
2209 	else
2210 	    *d++ = *s++;
2211     }
2212     *d = NUL;
2213 
2214 #ifdef FEAT_MBYTE
2215     if (convert && virp->vir_conv.vc_type != CONV_NONE && *retval != NUL)
2216     {
2217 	d = string_convert(&virp->vir_conv, retval, NULL);
2218 	if (d != NULL)
2219 	{
2220 	    vim_free(retval);
2221 	    retval = d;
2222 	}
2223     }
2224 #endif
2225 
2226     return retval;
2227 }
2228 
2229 /*
2230  * write string to viminfo file
2231  * - replace CTRL-V with CTRL-V CTRL-V
2232  * - replace '\n'   with CTRL-V 'n'
2233  * - add a '\n' at the end
2234  *
2235  * For a long line:
2236  * - write " CTRL-V <length> \n " in first line
2237  * - write " < <string> \n "	  in second line
2238  */
2239     void
2240 viminfo_writestring(fd, p)
2241     FILE	*fd;
2242     char_u	*p;
2243 {
2244     int		c;
2245     char_u	*s;
2246     int		len = 0;
2247 
2248     for (s = p; *s != NUL; ++s)
2249     {
2250 	if (*s == Ctrl_V || *s == '\n')
2251 	    ++len;
2252 	++len;
2253     }
2254 
2255     /* If the string will be too long, write its length and put it in the next
2256      * line.  Take into account that some room is needed for what comes before
2257      * the string (e.g., variable name).  Add something to the length for the
2258      * '<', NL and trailing NUL. */
2259     if (len > LSIZE / 2)
2260 	fprintf(fd, IF_EB("\026%d\n<", CTRL_V_STR "%d\n<"), len + 3);
2261 
2262     while ((c = *p++) != NUL)
2263     {
2264 	if (c == Ctrl_V || c == '\n')
2265 	{
2266 	    putc(Ctrl_V, fd);
2267 	    if (c == '\n')
2268 		c = 'n';
2269 	}
2270 	putc(c, fd);
2271     }
2272     putc('\n', fd);
2273 }
2274 #endif /* FEAT_VIMINFO */
2275 
2276 /*
2277  * Implementation of ":fixdel", also used by get_stty().
2278  *  <BS>    resulting <Del>
2279  *   ^?		^H
2280  * not ^?	^?
2281  */
2282 /*ARGSUSED*/
2283     void
2284 do_fixdel(eap)
2285     exarg_T	*eap;
2286 {
2287     char_u  *p;
2288 
2289     p = find_termcode((char_u *)"kb");
2290     add_termcode((char_u *)"kD", p != NULL
2291 	    && *p == DEL ? (char_u *)CTRL_H_STR : DEL_STR, FALSE);
2292 }
2293 
2294     void
2295 print_line_no_prefix(lnum, use_number, list)
2296     linenr_T	lnum;
2297     int		use_number;
2298     int		list;
2299 {
2300     char_u	numbuf[30];
2301 
2302     if (curwin->w_p_nu || use_number)
2303     {
2304 	sprintf((char *)numbuf, "%*ld ", number_width(curwin), (long)lnum);
2305 	msg_puts_attr(numbuf, hl_attr(HLF_N));	/* Highlight line nrs */
2306     }
2307     msg_prt_line(ml_get(lnum), list);
2308 }
2309 
2310 /*
2311  * Print a text line.  Also in silent mode ("ex -s").
2312  */
2313     void
2314 print_line(lnum, use_number, list)
2315     linenr_T	lnum;
2316     int		use_number;
2317     int		list;
2318 {
2319     int		save_silent = silent_mode;
2320 
2321     msg_start();
2322     silent_mode = FALSE;
2323     info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
2324     print_line_no_prefix(lnum, use_number, list);
2325     if (save_silent)
2326     {
2327 	msg_putchar('\n');
2328 	cursor_on();		/* msg_start() switches it off */
2329 	out_flush();
2330 	silent_mode = save_silent;
2331 	info_message = FALSE;
2332     }
2333 }
2334 
2335 /*
2336  * ":file[!] [fname]".
2337  */
2338     void
2339 ex_file(eap)
2340     exarg_T	*eap;
2341 {
2342     char_u	*fname, *sfname, *xfname;
2343     buf_T	*buf;
2344 
2345     /* ":0file" removes the file name.  Check for illegal uses ":3file",
2346      * "0file name", etc. */
2347     if (eap->addr_count > 0
2348 	    && (*eap->arg != NUL
2349 		|| eap->line2 > 0
2350 		|| eap->addr_count > 1))
2351     {
2352 	EMSG(_(e_invarg));
2353 	return;
2354     }
2355 
2356     if (*eap->arg != NUL || eap->addr_count == 1)
2357     {
2358 #ifdef FEAT_AUTOCMD
2359 	buf = curbuf;
2360 	apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
2361 	/* buffer changed, don't change name now */
2362 	if (buf != curbuf)
2363 	    return;
2364 # ifdef FEAT_EVAL
2365 	if (aborting())	    /* autocmds may abort script processing */
2366 	    return;
2367 # endif
2368 #endif
2369 	/*
2370 	 * The name of the current buffer will be changed.
2371 	 * A new (unlisted) buffer entry needs to be made to hold the old file
2372 	 * name, which will become the alternate file name.
2373 	 * But don't set the alternate file name if the buffer didn't have a
2374 	 * name.
2375 	 */
2376 	fname = curbuf->b_ffname;
2377 	sfname = curbuf->b_sfname;
2378 	xfname = curbuf->b_fname;
2379 	curbuf->b_ffname = NULL;
2380 	curbuf->b_sfname = NULL;
2381 	if (setfname(curbuf, eap->arg, NULL, TRUE) == FAIL)
2382 	{
2383 	    curbuf->b_ffname = fname;
2384 	    curbuf->b_sfname = sfname;
2385 	    return;
2386 	}
2387 	curbuf->b_flags |= BF_NOTEDITED;
2388 	if (xfname != NULL && *xfname != NUL)
2389 	{
2390 	    buf = buflist_new(fname, xfname, curwin->w_cursor.lnum, 0);
2391 	    if (buf != NULL && !cmdmod.keepalt)
2392 		curwin->w_alt_fnum = buf->b_fnum;
2393 	}
2394 	vim_free(fname);
2395 	vim_free(sfname);
2396 #ifdef FEAT_AUTOCMD
2397 	apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
2398 #endif
2399     }
2400     /* print full file name if :cd used */
2401     fileinfo(FALSE, FALSE, eap->forceit);
2402 }
2403 
2404 /*
2405  * ":update".
2406  */
2407     void
2408 ex_update(eap)
2409     exarg_T	*eap;
2410 {
2411     if (curbufIsChanged())
2412 	(void)do_write(eap);
2413 }
2414 
2415 /*
2416  * ":write" and ":saveas".
2417  */
2418     void
2419 ex_write(eap)
2420     exarg_T	*eap;
2421 {
2422     if (eap->usefilter)		/* input lines to shell command */
2423 	do_bang(1, eap, FALSE, TRUE, FALSE);
2424     else
2425 	(void)do_write(eap);
2426 }
2427 
2428 /*
2429  * write current buffer to file 'eap->arg'
2430  * if 'eap->append' is TRUE, append to the file
2431  *
2432  * if *eap->arg == NUL write to current file
2433  *
2434  * return FAIL for failure, OK otherwise
2435  */
2436     int
2437 do_write(eap)
2438     exarg_T	*eap;
2439 {
2440     int		other;
2441     char_u	*fname = NULL;		/* init to shut up gcc */
2442     char_u	*ffname;
2443     int		retval = FAIL;
2444     char_u	*free_fname = NULL;
2445 #ifdef FEAT_BROWSE
2446     char_u	*browse_file = NULL;
2447 #endif
2448     buf_T	*alt_buf = NULL;
2449 
2450     if (not_writing())		/* check 'write' option */
2451 	return FAIL;
2452 
2453     ffname = eap->arg;
2454 #ifdef FEAT_BROWSE
2455     if (cmdmod.browse)
2456     {
2457 	browse_file = do_browse(BROWSE_SAVE, (char_u *)_("Save As"), ffname,
2458 						    NULL, NULL, NULL, curbuf);
2459 	if (browse_file == NULL)
2460 	    goto theend;
2461 	ffname = browse_file;
2462     }
2463 #endif
2464     if (*ffname == NUL)
2465     {
2466 	if (eap->cmdidx == CMD_saveas)
2467 	{
2468 	    EMSG(_(e_argreq));
2469 	    goto theend;
2470 	}
2471 	other = FALSE;
2472     }
2473     else
2474     {
2475 	fname = ffname;
2476 	free_fname = fix_fname(ffname);
2477 	/*
2478 	 * When out-of-memory, keep unexpanded file name, because we MUST be
2479 	 * able to write the file in this situation.
2480 	 */
2481 	if (free_fname != NULL)
2482 	    ffname = free_fname;
2483 	other = otherfile(ffname);
2484     }
2485 
2486     /*
2487      * If we have a new file, put its name in the list of alternate file names.
2488      */
2489     if (other)
2490     {
2491 	if (vim_strchr(p_cpo, CPO_ALTWRITE) != NULL
2492 						 || eap->cmdidx == CMD_saveas)
2493 	    alt_buf = setaltfname(ffname, fname, (linenr_T)1);
2494 	else
2495 	    alt_buf = buflist_findname(ffname);
2496 	if (alt_buf != NULL && alt_buf->b_ml.ml_mfp != NULL)
2497 	{
2498 	    /* Overwriting a file that is loaded in another buffer is not a
2499 	     * good idea. */
2500 	    EMSG(_(e_bufloaded));
2501 	    goto theend;
2502 	}
2503     }
2504 
2505     /*
2506      * Writing to the current file is not allowed in readonly mode
2507      * and a file name is required.
2508      * "nofile" and "nowrite" buffers cannot be written implicitly either.
2509      */
2510     if (!other && (
2511 #ifdef FEAT_QUICKFIX
2512 		bt_dontwrite_msg(curbuf) ||
2513 #endif
2514 		check_fname() == FAIL || check_readonly(&eap->forceit, curbuf)))
2515 	goto theend;
2516 
2517     if (!other)
2518     {
2519 	ffname = curbuf->b_ffname;
2520 	fname = curbuf->b_fname;
2521 	/*
2522 	 * Not writing the whole file is only allowed with '!'.
2523 	 */
2524 	if (	   (eap->line1 != 1
2525 		    || eap->line2 != curbuf->b_ml.ml_line_count)
2526 		&& !eap->forceit
2527 		&& !eap->append
2528 		&& !p_wa)
2529 	{
2530 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2531 	    if (p_confirm || cmdmod.confirm)
2532 	    {
2533 		if (vim_dialog_yesno(VIM_QUESTION, NULL,
2534 			       (char_u *)_("Write partial file?"), 2) != VIM_YES)
2535 		    goto theend;
2536 		eap->forceit = TRUE;
2537 	    }
2538 	    else
2539 #endif
2540 	    {
2541 		EMSG(_("E140: Use ! to write partial buffer"));
2542 		goto theend;
2543 	    }
2544 	}
2545     }
2546 
2547     if (check_overwrite(eap, curbuf, fname, ffname, other) == OK)
2548     {
2549 	if (eap->cmdidx == CMD_saveas && alt_buf != NULL)
2550 	{
2551 #ifdef FEAT_AUTOCMD
2552 	    buf_T	*was_curbuf = curbuf;
2553 
2554 	    apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
2555 	    apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, alt_buf);
2556 # ifdef FEAT_EVAL
2557 	    if (curbuf != was_curbuf || aborting())
2558 # else
2559 	    if (curbuf != was_curbuf)
2560 # endif
2561 	    {
2562 		/* buffer changed, don't change name now */
2563 		retval = FAIL;
2564 		goto theend;
2565 	    }
2566 #endif
2567 	    /* Exchange the file names for the current and the alternate
2568 	     * buffer.  This makes it look like we are now editing the buffer
2569 	     * under the new name.  Must be done before buf_write(), because
2570 	     * if there is no file name and 'cpo' contains 'F', it will set
2571 	     * the file name. */
2572 	    fname = alt_buf->b_fname;
2573 	    alt_buf->b_fname = curbuf->b_fname;
2574 	    curbuf->b_fname = fname;
2575 	    fname = alt_buf->b_ffname;
2576 	    alt_buf->b_ffname = curbuf->b_ffname;
2577 	    curbuf->b_ffname = fname;
2578 	    fname = alt_buf->b_sfname;
2579 	    alt_buf->b_sfname = curbuf->b_sfname;
2580 	    curbuf->b_sfname = fname;
2581 	    buf_name_changed(curbuf);
2582 #ifdef FEAT_AUTOCMD
2583 	    apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
2584 	    apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, alt_buf);
2585 	    if (!alt_buf->b_p_bl)
2586 	    {
2587 		alt_buf->b_p_bl = TRUE;
2588 		apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, alt_buf);
2589 	    }
2590 # ifdef FEAT_EVAL
2591 	    if (curbuf != was_curbuf || aborting())
2592 # else
2593 	    if (curbuf != was_curbuf)
2594 # endif
2595 	    {
2596 		/* buffer changed, don't write the file */
2597 		retval = FAIL;
2598 		goto theend;
2599 	    }
2600 
2601 	    /* If 'filetype' was empty try detecting it now. */
2602 	    if (*curbuf->b_p_ft == NUL)
2603 	    {
2604 		(void)do_doautocmd((char_u *)"filetypedetect BufRead", TRUE);
2605 		do_modelines(0);
2606 	    }
2607 #endif
2608 	}
2609 
2610 	retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
2611 				 eap, eap->append, eap->forceit, TRUE, FALSE);
2612 
2613     }
2614 
2615 theend:
2616 #ifdef FEAT_BROWSE
2617     vim_free(browse_file);
2618 #endif
2619     vim_free(free_fname);
2620     return retval;
2621 }
2622 
2623 /*
2624  * Check if it is allowed to overwrite a file.  If b_flags has BF_NOTEDITED,
2625  * BF_NEW or BF_READERR, check for overwriting current file.
2626  * May set eap->forceit if a dialog says it's OK to overwrite.
2627  * Return OK if it's OK, FAIL if it is not.
2628  */
2629 /*ARGSUSED*/
2630     static int
2631 check_overwrite(eap, buf, fname, ffname, other)
2632     exarg_T	*eap;
2633     buf_T	*buf;
2634     char_u	*fname;	    /* file name to be used (can differ from
2635 			       buf->ffname) */
2636     char_u	*ffname;    /* full path version of fname */
2637     int		other;	    /* writing under other name */
2638 {
2639     /*
2640      * write to other file or b_flags set or not writing the whole file:
2641      * overwriting only allowed with '!'
2642      */
2643     if (       (other
2644 		|| (buf->b_flags & BF_NOTEDITED)
2645 		|| ((buf->b_flags & BF_NEW)
2646 		    && vim_strchr(p_cpo, CPO_OVERNEW) == NULL)
2647 		|| (buf->b_flags & BF_READERR))
2648 	    && !p_wa
2649 	    && vim_fexists(ffname))
2650     {
2651 	if (!eap->forceit && !eap->append)
2652 	{
2653 #ifdef UNIX
2654 	    /* with UNIX it is possible to open a directory */
2655 	    if (mch_isdir(ffname))
2656 	    {
2657 		EMSG2(_(e_isadir2), ffname);
2658 		return FAIL;
2659 	    }
2660 #endif
2661 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2662 	    if (p_confirm || cmdmod.confirm)
2663 	    {
2664 		char_u	buff[IOSIZE];
2665 
2666 		dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname);
2667 		if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
2668 		    return FAIL;
2669 		eap->forceit = TRUE;
2670 	    }
2671 	    else
2672 #endif
2673 	    {
2674 		EMSG(_(e_exists));
2675 		return FAIL;
2676 	    }
2677 	}
2678 
2679 	/* For ":w! filename" check that no swap file exists for "filename". */
2680 	if (other && !emsg_silent)
2681 	{
2682 	    char_u	dir[MAXPATHL];
2683 	    char_u	*p;
2684 	    int		r;
2685 	    char_u	*swapname;
2686 
2687 	    /* We only try the first entry in 'directory', without checking if
2688 	     * it's writable.  If the "." directory is not writable the write
2689 	     * will probably fail anyway.
2690 	     * Use 'shortname' of the current buffer, since there is no buffer
2691 	     * for the written file. */
2692 	    if (*p_dir == NUL)
2693 		STRCPY(dir, ".");
2694 	    else
2695 	    {
2696 		p = p_dir;
2697 		copy_option_part(&p, dir, MAXPATHL, ",");
2698 	    }
2699 	    swapname = makeswapname(fname, ffname, curbuf, dir);
2700 	    r = vim_fexists(swapname);
2701 	    vim_free(swapname);
2702 	    if (r)
2703 	    {
2704 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2705 		if (p_confirm || cmdmod.confirm)
2706 		{
2707 		    char_u	buff[IOSIZE];
2708 
2709 		    dialog_msg(buff,
2710 			    _("Swap file \"%s\" exists, overwrite anyway?"),
2711 								    swapname);
2712 		    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2)
2713 								   != VIM_YES)
2714 			return FAIL;
2715 		    eap->forceit = TRUE;
2716 		}
2717 		else
2718 #endif
2719 		{
2720 		    EMSG2(_("E768: Swap file exists: %s (:silent! overrides)"),
2721 								    swapname);
2722 		    return FAIL;
2723 		}
2724 	    }
2725 	}
2726     }
2727     return OK;
2728 }
2729 
2730 /*
2731  * Handle ":wnext", ":wNext" and ":wprevious" commands.
2732  */
2733     void
2734 ex_wnext(eap)
2735     exarg_T	*eap;
2736 {
2737     int		i;
2738 
2739     if (eap->cmd[1] == 'n')
2740 	i = curwin->w_arg_idx + (int)eap->line2;
2741     else
2742 	i = curwin->w_arg_idx - (int)eap->line2;
2743     eap->line1 = 1;
2744     eap->line2 = curbuf->b_ml.ml_line_count;
2745     if (do_write(eap) != FAIL)
2746 	do_argfile(eap, i);
2747 }
2748 
2749 /*
2750  * ":wall", ":wqall" and ":xall": Write all changed files (and exit).
2751  */
2752     void
2753 do_wqall(eap)
2754     exarg_T	*eap;
2755 {
2756     buf_T	*buf;
2757     int		error = 0;
2758     int		save_forceit = eap->forceit;
2759 
2760     if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall)
2761 	exiting = TRUE;
2762 
2763     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
2764     {
2765 	if (bufIsChanged(buf))
2766 	{
2767 	    /*
2768 	     * Check if there is a reason the buffer cannot be written:
2769 	     * 1. if the 'write' option is set
2770 	     * 2. if there is no file name (even after browsing)
2771 	     * 3. if the 'readonly' is set (even after a dialog)
2772 	     * 4. if overwriting is allowed (even after a dialog)
2773 	     */
2774 	    if (not_writing())
2775 	    {
2776 		++error;
2777 		break;
2778 	    }
2779 #ifdef FEAT_BROWSE
2780 	    /* ":browse wall": ask for file name if there isn't one */
2781 	    if (buf->b_ffname == NULL && cmdmod.browse)
2782 		browse_save_fname(buf);
2783 #endif
2784 	    if (buf->b_ffname == NULL)
2785 	    {
2786 		EMSGN(_("E141: No file name for buffer %ld"), (long)buf->b_fnum);
2787 		++error;
2788 	    }
2789 	    else if (check_readonly(&eap->forceit, buf)
2790 		    || check_overwrite(eap, buf, buf->b_fname, buf->b_ffname,
2791 							       FALSE) == FAIL)
2792 	    {
2793 		++error;
2794 	    }
2795 	    else
2796 	    {
2797 		if (buf_write_all(buf, eap->forceit) == FAIL)
2798 		    ++error;
2799 #ifdef FEAT_AUTOCMD
2800 		/* an autocommand may have deleted the buffer */
2801 		if (!buf_valid(buf))
2802 		    buf = firstbuf;
2803 #endif
2804 	    }
2805 	    eap->forceit = save_forceit;    /* check_overwrite() may set it */
2806 	}
2807     }
2808     if (exiting)
2809     {
2810 	if (!error)
2811 	    getout(0);		/* exit Vim */
2812 	not_exiting();
2813     }
2814 }
2815 
2816 /*
2817  * Check the 'write' option.
2818  * Return TRUE and give a message when it's not st.
2819  */
2820     int
2821 not_writing()
2822 {
2823     if (p_write)
2824 	return FALSE;
2825     EMSG(_("E142: File not written: Writing is disabled by 'write' option"));
2826     return TRUE;
2827 }
2828 
2829 /*
2830  * Check if a buffer is read-only.  Ask for overruling in a dialog.
2831  * Return TRUE and give an error message when the buffer is readonly.
2832  */
2833     static int
2834 check_readonly(forceit, buf)
2835     int		*forceit;
2836     buf_T	*buf;
2837 {
2838     if (!*forceit && buf->b_p_ro)
2839     {
2840 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2841 	if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
2842 	{
2843 	    char_u	buff[IOSIZE];
2844 
2845 	    dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
2846 		    buf->b_fname);
2847 
2848 	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
2849 	    {
2850 		/* Set forceit, to force the writing of a readonly file */
2851 		*forceit = TRUE;
2852 		return FALSE;
2853 	    }
2854 	    else
2855 		return TRUE;
2856 	}
2857 	else
2858 #endif
2859 	    EMSG(_(e_readonly));
2860 	return TRUE;
2861     }
2862     return FALSE;
2863 }
2864 
2865 /*
2866  * Try to abandon current file and edit a new or existing file.
2867  * 'fnum' is the number of the file, if zero use ffname/sfname.
2868  *
2869  * Return 1 for "normal" error, 2 for "not written" error, 0 for success
2870  * -1 for succesfully opening another file.
2871  * 'lnum' is the line number for the cursor in the new file (if non-zero).
2872  */
2873     int
2874 getfile(fnum, ffname, sfname, setpm, lnum, forceit)
2875     int		fnum;
2876     char_u	*ffname;
2877     char_u	*sfname;
2878     int		setpm;
2879     linenr_T	lnum;
2880     int		forceit;
2881 {
2882     int		other;
2883     int		retval;
2884     char_u	*free_me = NULL;
2885 
2886     if (text_locked())
2887 	return 1;
2888 
2889     if (fnum == 0)
2890     {
2891 					/* make ffname full path, set sfname */
2892 	fname_expand(curbuf, &ffname, &sfname);
2893 	other = otherfile(ffname);
2894 	free_me = ffname;		/* has been allocated, free() later */
2895     }
2896     else
2897 	other = (fnum != curbuf->b_fnum);
2898 
2899     if (other)
2900 	++no_wait_return;	    /* don't wait for autowrite message */
2901     if (other && !forceit && curbuf->b_nwindows == 1 && !P_HID(curbuf)
2902 		   && curbufIsChanged() && autowrite(curbuf, forceit) == FAIL)
2903     {
2904 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2905 	if (p_confirm && p_write)
2906 	    dialog_changed(curbuf, FALSE);
2907 	if (curbufIsChanged())
2908 #endif
2909 	{
2910 	    if (other)
2911 		--no_wait_return;
2912 	    EMSG(_(e_nowrtmsg));
2913 	    retval = 2;	/* file has been changed */
2914 	    goto theend;
2915 	}
2916     }
2917     if (other)
2918 	--no_wait_return;
2919     if (setpm)
2920 	setpcmark();
2921     if (!other)
2922     {
2923 	if (lnum != 0)
2924 	    curwin->w_cursor.lnum = lnum;
2925 	check_cursor_lnum();
2926 	beginline(BL_SOL | BL_FIX);
2927 	retval = 0;	/* it's in the same file */
2928     }
2929     else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
2930 		(P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0)) == OK)
2931 	retval = -1;	/* opened another file */
2932     else
2933 	retval = 1;	/* error encountered */
2934 
2935 theend:
2936     vim_free(free_me);
2937     return retval;
2938 }
2939 
2940 /*
2941  * start editing a new file
2942  *
2943  *     fnum: file number; if zero use ffname/sfname
2944  *   ffname: the file name
2945  *		- full path if sfname used,
2946  *		- any file name if sfname is NULL
2947  *		- empty string to re-edit with the same file name (but may be
2948  *		    in a different directory)
2949  *		- NULL to start an empty buffer
2950  *   sfname: the short file name (or NULL)
2951  *	eap: contains the command to be executed after loading the file and
2952  *	     forced 'ff' and 'fenc'
2953  *  newlnum: if > 0: put cursor on this line number (if possible)
2954  *	     if ECMD_LASTL: use last position in loaded file
2955  *	     if ECMD_LAST: use last position in all files
2956  *	     if ECMD_ONE: use first line
2957  *    flags:
2958  *	   ECMD_HIDE: if TRUE don't free the current buffer
2959  *     ECMD_SET_HELP: set b_help flag of (new) buffer before opening file
2960  *	 ECMD_OLDBUF: use existing buffer if it exists
2961  *	ECMD_FORCEIT: ! used for Ex command
2962  *	 ECMD_ADDBUF: don't edit, just add to buffer list
2963  *
2964  * return FAIL for failure, OK otherwise
2965  */
2966     int
2967 do_ecmd(fnum, ffname, sfname, eap, newlnum, flags)
2968     int		fnum;
2969     char_u	*ffname;
2970     char_u	*sfname;
2971     exarg_T	*eap;			/* can be NULL! */
2972     linenr_T	newlnum;
2973     int		flags;
2974 {
2975     int		other_file;		/* TRUE if editing another file */
2976     int		oldbuf;			/* TRUE if using existing buffer */
2977 #ifdef FEAT_AUTOCMD
2978     int		auto_buf = FALSE;	/* TRUE if autocommands brought us
2979 					   into the buffer unexpectedly */
2980     char_u	*new_name = NULL;
2981     int		did_set_swapcommand = FALSE;
2982 #endif
2983     buf_T	*buf;
2984 #if defined(FEAT_AUTOCMD) || defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2985     buf_T	*old_curbuf = curbuf;
2986 #endif
2987     char_u	*free_fname = NULL;
2988 #ifdef FEAT_BROWSE
2989     char_u	*browse_file = NULL;
2990 #endif
2991     int		retval = FAIL;
2992     long	n;
2993     linenr_T	lnum;
2994     linenr_T	topline = 0;
2995     int		newcol = -1;
2996     int		solcol = -1;
2997     pos_T	*pos;
2998 #ifdef FEAT_SUN_WORKSHOP
2999     char_u	*cp;
3000 #endif
3001     char_u	*command = NULL;
3002 
3003     if (eap != NULL)
3004 	command = eap->do_ecmd_cmd;
3005 
3006     if (fnum != 0)
3007     {
3008 	if (fnum == curbuf->b_fnum)	/* file is already being edited */
3009 	    return OK;			/* nothing to do */
3010 	other_file = TRUE;
3011     }
3012     else
3013     {
3014 #ifdef FEAT_BROWSE
3015 	if (cmdmod.browse)
3016 	{
3017 	    if (
3018 # ifdef FEAT_GUI
3019 		!gui.in_use &&
3020 # endif
3021 		    au_has_group((char_u *)"FileExplorer"))
3022 	    {
3023 		/* No browsing supported but we do have the file explorer:
3024 		 * Edit the directory. */
3025 		if (ffname == NULL || !mch_isdir(ffname))
3026 		    ffname = (char_u *)".";
3027 	    }
3028 	    else
3029 	    {
3030 		browse_file = do_browse(0, (char_u *)_("Edit File"), ffname,
3031 						    NULL, NULL, NULL, curbuf);
3032 		if (browse_file == NULL)
3033 		    goto theend;
3034 		ffname = browse_file;
3035 	    }
3036 	}
3037 #endif
3038 	/* if no short name given, use ffname for short name */
3039 	if (sfname == NULL)
3040 	    sfname = ffname;
3041 #ifdef USE_FNAME_CASE
3042 # ifdef USE_LONG_FNAME
3043 	if (USE_LONG_FNAME)
3044 # endif
3045 	    if (sfname != NULL)
3046 		fname_case(sfname, 0);   /* set correct case for sfname */
3047 #endif
3048 
3049 #ifdef FEAT_LISTCMDS
3050 	if ((flags & ECMD_ADDBUF) && (ffname == NULL || *ffname == NUL))
3051 	    goto theend;
3052 #endif
3053 
3054 	if (ffname == NULL)
3055 	    other_file = TRUE;
3056 					    /* there is no file name */
3057 	else if (*ffname == NUL && curbuf->b_ffname == NULL)
3058 	    other_file = FALSE;
3059 	else
3060 	{
3061 	    if (*ffname == NUL)		    /* re-edit with same file name */
3062 	    {
3063 		ffname = curbuf->b_ffname;
3064 		sfname = curbuf->b_fname;
3065 	    }
3066 	    free_fname = fix_fname(ffname); /* may expand to full path name */
3067 	    if (free_fname != NULL)
3068 		ffname = free_fname;
3069 	    other_file = otherfile(ffname);
3070 #ifdef FEAT_SUN_WORKSHOP
3071 	    if (usingSunWorkShop && p_acd
3072 				   && (cp = vim_strrchr(sfname, '/')) != NULL)
3073 		sfname = ++cp;
3074 #endif
3075 	}
3076     }
3077 
3078     /*
3079      * if the file was changed we may not be allowed to abandon it
3080      * - if we are going to re-edit the same file
3081      * - or if we are the only window on this file and if ECMD_HIDE is FALSE
3082      */
3083     if (  ((!other_file && !(flags & ECMD_OLDBUF))
3084 	    || (curbuf->b_nwindows == 1
3085 		&& !(flags & (ECMD_HIDE | ECMD_ADDBUF))))
3086 	&& check_changed(curbuf, p_awa, !other_file,
3087 					(flags & ECMD_FORCEIT), FALSE))
3088     {
3089 	if (fnum == 0 && other_file && ffname != NULL)
3090 	    (void)setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum);
3091 	goto theend;
3092     }
3093 
3094 #ifdef FEAT_VISUAL
3095     /*
3096      * End Visual mode before switching to another buffer, so the text can be
3097      * copied into the GUI selection buffer.
3098      */
3099     reset_VIsual();
3100 #endif
3101 
3102 #ifdef FEAT_AUTOCMD
3103     if ((command != NULL || newlnum > (linenr_T)0)
3104 	    && *get_vim_var_str(VV_SWAPCOMMAND) == NUL)
3105     {
3106 	int	len;
3107 	char_u	*p;
3108 
3109 	/* Set v:swapcommand for the SwapExists autocommands. */
3110 	if (command != NULL)
3111 	    len = STRLEN(command) + 3;
3112 	else
3113 	    len = 30;
3114 	p = alloc((unsigned)len);
3115 	if (p != NULL)
3116 	{
3117 	    if (command != NULL)
3118 		vim_snprintf((char *)p, len, ":%s\r", command);
3119 	    else
3120 		vim_snprintf((char *)p, len, "%ldG", (long)newlnum);
3121 	    set_vim_var_string(VV_SWAPCOMMAND, p, -1);
3122 	    did_set_swapcommand = TRUE;
3123 	    vim_free(p);
3124 	}
3125     }
3126 #endif
3127 
3128     /*
3129      * If we are starting to edit another file, open a (new) buffer.
3130      * Otherwise we re-use the current buffer.
3131      */
3132     if (other_file)
3133     {
3134 #ifdef FEAT_LISTCMDS
3135 	if (!(flags & ECMD_ADDBUF))
3136 #endif
3137 	{
3138 	    if (!cmdmod.keepalt)
3139 		curwin->w_alt_fnum = curbuf->b_fnum;
3140 	    buflist_altfpos();
3141 	}
3142 
3143 	if (fnum)
3144 	    buf = buflist_findnr(fnum);
3145 	else
3146 	{
3147 #ifdef FEAT_LISTCMDS
3148 	    if (flags & ECMD_ADDBUF)
3149 	    {
3150 		linenr_T	tlnum = 1L;
3151 
3152 		if (command != NULL)
3153 		{
3154 		    tlnum = atol((char *)command);
3155 		    if (tlnum <= 0)
3156 			tlnum = 1L;
3157 		}
3158 		(void)buflist_new(ffname, sfname, tlnum, BLN_LISTED);
3159 		goto theend;
3160 	    }
3161 #endif
3162 	    buf = buflist_new(ffname, sfname, 0L,
3163 		    BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
3164 	}
3165 	if (buf == NULL)
3166 	    goto theend;
3167 	if (buf->b_ml.ml_mfp == NULL)		/* no memfile yet */
3168 	{
3169 	    oldbuf = FALSE;
3170 	    buf->b_nwindows = 0;
3171 	}
3172 	else					/* existing memfile */
3173 	{
3174 	    oldbuf = TRUE;
3175 	    (void)buf_check_timestamp(buf, FALSE);
3176 	    /* Check if autocommands made buffer invalid or changed the current
3177 	     * buffer. */
3178 	    if (!buf_valid(buf)
3179 #ifdef FEAT_AUTOCMD
3180 		    || curbuf != old_curbuf
3181 #endif
3182 		    )
3183 		goto theend;
3184 #ifdef FEAT_EVAL
3185 	    if (aborting())	    /* autocmds may abort script processing */
3186 		goto theend;
3187 #endif
3188 	}
3189 
3190 	/* May jump to last used line number for a loaded buffer or when asked
3191 	 * for explicitly */
3192 	if ((oldbuf && newlnum == ECMD_LASTL) || newlnum == ECMD_LAST)
3193 	{
3194 	    pos = buflist_findfpos(buf);
3195 	    newlnum = pos->lnum;
3196 	    solcol = pos->col;
3197 	}
3198 
3199 	/*
3200 	 * Make the (new) buffer the one used by the current window.
3201 	 * If the old buffer becomes unused, free it if ECMD_HIDE is FALSE.
3202 	 * If the current buffer was empty and has no file name, curbuf
3203 	 * is returned by buflist_new().
3204 	 */
3205 	if (buf != curbuf)
3206 	{
3207 #ifdef FEAT_AUTOCMD
3208 	    /*
3209 	     * Be careful: The autocommands may delete any buffer and change
3210 	     * the current buffer.
3211 	     * - If the buffer we are going to edit is deleted, give up.
3212 	     * - If the current buffer is deleted, prefer to load the new
3213 	     *   buffer when loading a buffer is required.  This avoids
3214 	     *   loading another buffer which then must be closed again.
3215 	     * - If we ended up in the new buffer already, need to skip a few
3216 	     *	 things, set auto_buf.
3217 	     */
3218 	    if (buf->b_fname != NULL)
3219 		new_name = vim_strsave(buf->b_fname);
3220 	    au_new_curbuf = buf;
3221 	    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
3222 	    if (!buf_valid(buf))	/* new buffer has been deleted */
3223 	    {
3224 		delbuf_msg(new_name);	/* frees new_name */
3225 		goto theend;
3226 	    }
3227 # ifdef FEAT_EVAL
3228 	    if (aborting())	    /* autocmds may abort script processing */
3229 	    {
3230 		vim_free(new_name);
3231 		goto theend;
3232 	    }
3233 # endif
3234 	    if (buf == curbuf)		/* already in new buffer */
3235 		auto_buf = TRUE;
3236 	    else
3237 	    {
3238 		if (curbuf == old_curbuf)
3239 #endif
3240 		    buf_copy_options(buf, BCO_ENTER);
3241 
3242 		/* close the link to the current buffer */
3243 		close_buffer(curwin, curbuf,
3244 				      (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD);
3245 
3246 #ifdef FEAT_AUTOCMD
3247 # ifdef FEAT_EVAL
3248 		if (aborting())	    /* autocmds may abort script processing */
3249 		{
3250 		    vim_free(new_name);
3251 		    goto theend;
3252 		}
3253 # endif
3254 		/* Be careful again, like above. */
3255 		if (!buf_valid(buf))	/* new buffer has been deleted */
3256 		{
3257 		    delbuf_msg(new_name);	/* frees new_name */
3258 		    goto theend;
3259 		}
3260 		if (buf == curbuf)		/* already in new buffer */
3261 		    auto_buf = TRUE;
3262 		else
3263 #endif
3264 		{
3265 		    curwin->w_buffer = buf;
3266 		    curbuf = buf;
3267 		    ++curbuf->b_nwindows;
3268 		    /* set 'fileformat' */
3269 		    if (*p_ffs && !oldbuf)
3270 			set_fileformat(default_fileformat(), OPT_LOCAL);
3271 		}
3272 
3273 		/* May get the window options from the last time this buffer
3274 		 * was in this window (or another window).  If not used
3275 		 * before, reset the local window options to the global
3276 		 * values.  Also restores old folding stuff. */
3277 		get_winopts(buf);
3278 
3279 #ifdef FEAT_AUTOCMD
3280 	    }
3281 	    vim_free(new_name);
3282 	    au_new_curbuf = NULL;
3283 #endif
3284 	}
3285 	else
3286 	    ++curbuf->b_nwindows;
3287 
3288 	curwin->w_pcmark.lnum = 1;
3289 	curwin->w_pcmark.col = 0;
3290     }
3291     else /* !other_file */
3292     {
3293 	if (
3294 #ifdef FEAT_LISTCMDS
3295 		(flags & ECMD_ADDBUF) ||
3296 #endif
3297 		check_fname() == FAIL)
3298 	    goto theend;
3299 	oldbuf = (flags & ECMD_OLDBUF);
3300     }
3301 
3302     if ((flags & ECMD_SET_HELP) || keep_help_flag)
3303     {
3304 	char_u	*p;
3305 
3306 	curbuf->b_help = TRUE;
3307 #ifdef FEAT_QUICKFIX
3308 	set_string_option_direct((char_u *)"buftype", -1,
3309 				     (char_u *)"help", OPT_FREE|OPT_LOCAL, 0);
3310 #endif
3311 
3312 	/*
3313 	 * Always set these options after jumping to a help tag, because the
3314 	 * user may have an autocommand that gets in the way.
3315 	 * Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and
3316 	 * latin1 word characters (for translated help files).
3317 	 * Only set it when needed, buf_init_chartab() is some work.
3318 	 */
3319 	p =
3320 #ifdef EBCDIC
3321 		(char_u *)"65-255,^*,^|,^\"";
3322 #else
3323 		(char_u *)"!-~,^*,^|,^\",192-255";
3324 #endif
3325 	if (STRCMP(curbuf->b_p_isk, p) != 0)
3326 	{
3327 	    set_string_option_direct((char_u *)"isk", -1, p,
3328 						       OPT_FREE|OPT_LOCAL, 0);
3329 	    check_buf_options(curbuf);
3330 	    (void)buf_init_chartab(curbuf, FALSE);
3331 	}
3332 
3333 	curbuf->b_p_ts = 8;		/* 'tabstop' is 8 */
3334 	curwin->w_p_list = FALSE;	/* no list mode */
3335 
3336 	curbuf->b_p_ma = FALSE;		/* not modifiable */
3337 	curbuf->b_p_bin = FALSE;	/* reset 'bin' before reading file */
3338 	curwin->w_p_nu = 0;		/* no line numbers */
3339 #ifdef FEAT_SCROLLBIND
3340 	curwin->w_p_scb = FALSE;	/* no scroll binding */
3341 #endif
3342 #ifdef FEAT_ARABIC
3343 	curwin->w_p_arab = FALSE;	/* no arabic mode */
3344 #endif
3345 #ifdef FEAT_RIGHTLEFT
3346 	curwin->w_p_rl  = FALSE;	/* help window is left-to-right */
3347 #endif
3348 #ifdef FEAT_FOLDING
3349 	curwin->w_p_fen = FALSE;	/* No folding in the help window */
3350 #endif
3351 #ifdef FEAT_DIFF
3352 	curwin->w_p_diff = FALSE;	/* No 'diff' */
3353 #endif
3354 #ifdef FEAT_SPELL
3355 	curwin->w_p_spell = FALSE;	/* No spell checking */
3356 #endif
3357 
3358 #ifdef FEAT_AUTOCMD
3359 	buf = curbuf;
3360 #endif
3361 	set_buflisted(FALSE);
3362     }
3363     else
3364     {
3365 #ifdef FEAT_AUTOCMD
3366 	buf = curbuf;
3367 #endif
3368 	/* Don't make a buffer listed if it's a help buffer.  Useful when
3369 	 * using CTRL-O to go back to a help file. */
3370 	if (!curbuf->b_help)
3371 	    set_buflisted(TRUE);
3372     }
3373 
3374 #ifdef FEAT_AUTOCMD
3375     /* If autocommands change buffers under our fingers, forget about
3376      * editing the file. */
3377     if (buf != curbuf)
3378 	goto theend;
3379 # ifdef FEAT_EVAL
3380     if (aborting())	    /* autocmds may abort script processing */
3381 	goto theend;
3382 # endif
3383 
3384     /* Since we are starting to edit a file, consider the filetype to be
3385      * unset.  Helps for when an autocommand changes files and expects syntax
3386      * highlighting to work in the other file. */
3387     did_filetype = FALSE;
3388 #endif
3389 
3390 /*
3391  * other_file	oldbuf
3392  *  FALSE	FALSE	    re-edit same file, buffer is re-used
3393  *  FALSE	TRUE	    re-edit same file, nothing changes
3394  *  TRUE	FALSE	    start editing new file, new buffer
3395  *  TRUE	TRUE	    start editing in existing buffer (nothing to do)
3396  */
3397     if (!other_file && !oldbuf)		/* re-use the buffer */
3398     {
3399 	set_last_cursor(curwin);	/* may set b_last_cursor */
3400 	if (newlnum == ECMD_LAST || newlnum == ECMD_LASTL)
3401 	{
3402 	    newlnum = curwin->w_cursor.lnum;
3403 	    solcol = curwin->w_cursor.col;
3404 	}
3405 #ifdef FEAT_AUTOCMD
3406 	buf = curbuf;
3407 	if (buf->b_fname != NULL)
3408 	    new_name = vim_strsave(buf->b_fname);
3409 	else
3410 	    new_name = NULL;
3411 #endif
3412 	buf_freeall(curbuf, FALSE, FALSE);   /* free all things for buffer */
3413 #ifdef FEAT_AUTOCMD
3414 	/* If autocommands deleted the buffer we were going to re-edit, give
3415 	 * up and jump to the end. */
3416 	if (!buf_valid(buf))
3417 	{
3418 	    delbuf_msg(new_name);	/* frees new_name */
3419 	    goto theend;
3420 	}
3421 	vim_free(new_name);
3422 
3423 	/* If autocommands change buffers under our fingers, forget about
3424 	 * re-editing the file.  Should do the buf_clear_file(), but perhaps
3425 	 * the autocommands changed the buffer... */
3426 	if (buf != curbuf)
3427 	    goto theend;
3428 # ifdef FEAT_EVAL
3429 	if (aborting())	    /* autocmds may abort script processing */
3430 	    goto theend;
3431 # endif
3432 #endif
3433 	buf_clear_file(curbuf);
3434 	curbuf->b_op_start.lnum = 0;	/* clear '[ and '] marks */
3435 	curbuf->b_op_end.lnum = 0;
3436     }
3437 
3438 /*
3439  * If we get here we are sure to start editing
3440  */
3441     /* don't redraw until the cursor is in the right line */
3442     ++RedrawingDisabled;
3443 
3444     /* Assume success now */
3445     retval = OK;
3446 
3447     /*
3448      * Reset cursor position, could be used by autocommands.
3449      */
3450     check_cursor();
3451 
3452     /*
3453      * Check if we are editing the w_arg_idx file in the argument list.
3454      */
3455     check_arg_idx(curwin);
3456 
3457 #ifdef FEAT_AUTOCMD
3458     if (!auto_buf)
3459 #endif
3460     {
3461 	/*
3462 	 * Set cursor and init window before reading the file and executing
3463 	 * autocommands.  This allows for the autocommands to position the
3464 	 * cursor.
3465 	 */
3466 	curwin_init();
3467 
3468 #ifdef FEAT_FOLDING
3469 	/* It's like all lines in the buffer changed.  Need to update
3470 	 * automatic folding. */
3471 	foldUpdateAll(curwin);
3472 #endif
3473 
3474 #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG)
3475 	if (p_acd && curbuf->b_ffname != NULL
3476 				     && vim_chdirfile(curbuf->b_ffname) == OK)
3477 	    shorten_fnames(TRUE);
3478 #endif
3479 	/*
3480 	 * Careful: open_buffer() and apply_autocmds() may change the current
3481 	 * buffer and window.
3482 	 */
3483 	lnum = curwin->w_cursor.lnum;
3484 	topline = curwin->w_topline;
3485 	if (!oldbuf)			    /* need to read the file */
3486 	{
3487 #if defined(HAS_SWAP_EXISTS_ACTION)
3488 	    swap_exists_action = SEA_DIALOG;
3489 #endif
3490 	    curbuf->b_flags |= BF_CHECK_RO; /* set/reset 'ro' flag */
3491 
3492 	    /*
3493 	     * Open the buffer and read the file.
3494 	     */
3495 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
3496 	    if (should_abort(open_buffer(FALSE, eap)))
3497 		retval = FAIL;
3498 #else
3499 	    (void)open_buffer(FALSE, eap);
3500 #endif
3501 
3502 #if defined(HAS_SWAP_EXISTS_ACTION)
3503 	    if (swap_exists_action == SEA_QUIT)
3504 		retval = FAIL;
3505 	    handle_swap_exists(old_curbuf);
3506 #endif
3507 	}
3508 #ifdef FEAT_AUTOCMD
3509 	else
3510 	{
3511 	    /* Read the modelines, but only to set window-local options.  Any
3512 	     * buffer-local options have already been set and may have been
3513 	     * changed by the user. */
3514 	    do_modelines(OPT_WINONLY);
3515 
3516 	    apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf,
3517 								    &retval);
3518 	    apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
3519 								    &retval);
3520 	}
3521 	check_arg_idx(curwin);
3522 #endif
3523 
3524 	/*
3525 	 * If autocommands change the cursor position or topline, we should
3526 	 * keep it.
3527 	 */
3528 	if (curwin->w_cursor.lnum != lnum)
3529 	{
3530 	    newlnum = curwin->w_cursor.lnum;
3531 	    newcol = curwin->w_cursor.col;
3532 	}
3533 	if (curwin->w_topline == topline)
3534 	    topline = 0;
3535 
3536 	/* Even when cursor didn't move we need to recompute topline. */
3537 	changed_line_abv_curs();
3538 
3539 #ifdef FEAT_TITLE
3540 	maketitle();
3541 #endif
3542     }
3543 
3544 #ifdef FEAT_DIFF
3545     /* Tell the diff stuff that this buffer is new and/or needs updating.
3546      * Also needed when re-editing the same buffer, because unloading will
3547      * have removed it as a diff buffer. */
3548     if (curwin->w_p_diff)
3549     {
3550 	diff_buf_add(curbuf);
3551 	diff_invalidate(curbuf);
3552     }
3553 #endif
3554 
3555     if (command == NULL)
3556     {
3557 	if (newcol >= 0)	/* position set by autocommands */
3558 	{
3559 	    curwin->w_cursor.lnum = newlnum;
3560 	    curwin->w_cursor.col = newcol;
3561 	    check_cursor();
3562 	}
3563 	else if (newlnum > 0)	/* line number from caller or old position */
3564 	{
3565 	    curwin->w_cursor.lnum = newlnum;
3566 	    check_cursor_lnum();
3567 	    if (solcol >= 0 && !p_sol)
3568 	    {
3569 		/* 'sol' is off: Use last known column. */
3570 		curwin->w_cursor.col = solcol;
3571 		check_cursor_col();
3572 #ifdef FEAT_VIRTUALEDIT
3573 		curwin->w_cursor.coladd = 0;
3574 #endif
3575 		curwin->w_set_curswant = TRUE;
3576 	    }
3577 	    else
3578 		beginline(BL_SOL | BL_FIX);
3579 	}
3580 	else			/* no line number, go to last line in Ex mode */
3581 	{
3582 	    if (exmode_active)
3583 		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
3584 	    beginline(BL_WHITE | BL_FIX);
3585 	}
3586     }
3587 
3588 #ifdef FEAT_WINDOWS
3589     /* Check if cursors in other windows on the same buffer are still valid */
3590     check_lnums(FALSE);
3591 #endif
3592 
3593     /*
3594      * Did not read the file, need to show some info about the file.
3595      * Do this after setting the cursor.
3596      */
3597     if (oldbuf
3598 #ifdef FEAT_AUTOCMD
3599 		&& !auto_buf
3600 #endif
3601 			    )
3602     {
3603 	int	msg_scroll_save = msg_scroll;
3604 
3605 	/* Obey the 'O' flag in 'cpoptions': overwrite any previous file
3606 	 * message. */
3607 	if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
3608 	    msg_scroll = FALSE;
3609 	if (!msg_scroll)	/* wait a bit when overwriting an error msg */
3610 	    check_for_delay(FALSE);
3611 	msg_start();
3612 	msg_scroll = msg_scroll_save;
3613 	msg_scrolled_ign = TRUE;
3614 
3615 	fileinfo(FALSE, TRUE, FALSE);
3616 
3617 	msg_scrolled_ign = FALSE;
3618     }
3619 
3620     if (command != NULL)
3621 	do_cmdline(command, NULL, NULL, DOCMD_VERBOSE);
3622 
3623 #ifdef FEAT_KEYMAP
3624     if (curbuf->b_kmap_state & KEYMAP_INIT)
3625 	keymap_init();
3626 #endif
3627 
3628     --RedrawingDisabled;
3629     if (!skip_redraw)
3630     {
3631 	n = p_so;
3632 	if (topline == 0 && command == NULL)
3633 	    p_so = 999;			/* force cursor halfway the window */
3634 	update_topline();
3635 #ifdef FEAT_SCROLLBIND
3636 	curwin->w_scbind_pos = curwin->w_topline;
3637 #endif
3638 	p_so = n;
3639 	redraw_curbuf_later(NOT_VALID);	/* redraw this buffer later */
3640     }
3641 
3642     if (p_im)
3643 	need_start_insertmode = TRUE;
3644 
3645 #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG)
3646     /* Change directories when the acd option is set on. */
3647     if (p_acd && curbuf->b_ffname != NULL
3648 				     && vim_chdirfile(curbuf->b_ffname) == OK)
3649 	shorten_fnames(TRUE);
3650 
3651     if (gui.in_use && curbuf->b_ffname != NULL)
3652     {
3653 # ifdef FEAT_SUN_WORKSHOP
3654 	if (usingSunWorkShop)
3655 	    workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro);
3656 # endif
3657 # ifdef FEAT_NETBEANS_INTG
3658 	if (usingNetbeans & ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
3659 	    netbeans_file_opened(curbuf);
3660 # endif
3661     }
3662 #endif
3663 
3664 theend:
3665 #ifdef FEAT_AUTOCMD
3666     if (did_set_swapcommand)
3667 	set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
3668 #endif
3669 #ifdef FEAT_BROWSE
3670     vim_free(browse_file);
3671 #endif
3672     vim_free(free_fname);
3673     return retval;
3674 }
3675 
3676 #ifdef FEAT_AUTOCMD
3677     static void
3678 delbuf_msg(name)
3679     char_u	*name;
3680 {
3681     EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
3682 	    name == NULL ? (char_u *)"" : name);
3683     vim_free(name);
3684     au_new_curbuf = NULL;
3685 }
3686 #endif
3687 
3688 static int append_indent = 0;	    /* autoindent for first line */
3689 
3690 /*
3691  * ":insert" and ":append", also used by ":change"
3692  */
3693     void
3694 ex_append(eap)
3695     exarg_T	*eap;
3696 {
3697     char_u	*theline;
3698     int		did_undo = FALSE;
3699     linenr_T	lnum = eap->line2;
3700     int		indent = 0;
3701     char_u	*p;
3702     int		vcol;
3703     int		empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
3704 
3705     /* the ! flag toggles autoindent */
3706     if (eap->forceit)
3707 	curbuf->b_p_ai = !curbuf->b_p_ai;
3708 
3709     /* First autoindent comes from the line we start on */
3710     if (eap->cmdidx != CMD_change && curbuf->b_p_ai && lnum > 0)
3711 	append_indent = get_indent_lnum(lnum);
3712 
3713     if (eap->cmdidx != CMD_append)
3714 	--lnum;
3715 
3716     /* when the buffer is empty append to line 0 and delete the dummy line */
3717     if (empty && lnum == 1)
3718 	lnum = 0;
3719 
3720     State = INSERT;		    /* behave like in Insert mode */
3721     if (curbuf->b_p_iminsert == B_IMODE_LMAP)
3722 	State |= LANGMAP;
3723 
3724     for (;;)
3725     {
3726 	msg_scroll = TRUE;
3727 	need_wait_return = FALSE;
3728 	if (curbuf->b_p_ai)
3729 	{
3730 	    if (append_indent >= 0)
3731 	    {
3732 		indent = append_indent;
3733 		append_indent = -1;
3734 	    }
3735 	    else if (lnum > 0)
3736 		indent = get_indent_lnum(lnum);
3737 	}
3738 	ex_keep_indent = FALSE;
3739 	if (eap->getline == NULL)
3740 	{
3741 	    /* No getline() function, use the lines that follow. This ends
3742 	     * when there is no more. */
3743 	    if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
3744 		break;
3745 	    p = vim_strchr(eap->nextcmd, NL);
3746 	    if (p == NULL)
3747 		p = eap->nextcmd + STRLEN(eap->nextcmd);
3748 	    theline = vim_strnsave(eap->nextcmd, (int)(p - eap->nextcmd));
3749 	    if (*p != NUL)
3750 		++p;
3751 	    eap->nextcmd = p;
3752 	}
3753 	else
3754 	    theline = eap->getline(
3755 #ifdef FEAT_EVAL
3756 		    eap->cstack->cs_looplevel > 0 ? -1 :
3757 #endif
3758 		    NUL, eap->cookie, indent);
3759 	lines_left = Rows - 1;
3760 	if (theline == NULL)
3761 	    break;
3762 
3763 	/* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */
3764 	if (ex_keep_indent)
3765 	    append_indent = indent;
3766 
3767 	/* Look for the "." after automatic indent. */
3768 	vcol = 0;
3769 	for (p = theline; indent > vcol; ++p)
3770 	{
3771 	    if (*p == ' ')
3772 		++vcol;
3773 	    else if (*p == TAB)
3774 		vcol += 8 - vcol % 8;
3775 	    else
3776 		break;
3777 	}
3778 	if ((p[0] == '.' && p[1] == NUL)
3779 		|| (!did_undo && u_save(lnum, lnum + 1 + (empty ? 1 : 0))
3780 								     == FAIL))
3781 	{
3782 	    vim_free(theline);
3783 	    break;
3784 	}
3785 
3786 	/* don't use autoindent if nothing was typed. */
3787 	if (p[0] == NUL)
3788 	    theline[0] = NUL;
3789 
3790 	did_undo = TRUE;
3791 	ml_append(lnum, theline, (colnr_T)0, FALSE);
3792 	appended_lines_mark(lnum, 1L);
3793 
3794 	vim_free(theline);
3795 	++lnum;
3796 
3797 	if (empty)
3798 	{
3799 	    ml_delete(2L, FALSE);
3800 	    empty = FALSE;
3801 	}
3802     }
3803     State = NORMAL;
3804 
3805     if (eap->forceit)
3806 	curbuf->b_p_ai = !curbuf->b_p_ai;
3807 
3808     /* "start" is set to eap->line2+1 unless that position is invalid (when
3809      * eap->line2 pointed to the end of the buffer and nothig was appended)
3810      * "end" is set to lnum when something has been appended, otherwise
3811      * it is the same than "start"  -- Acevedo */
3812     curbuf->b_op_start.lnum = (eap->line2 < curbuf->b_ml.ml_line_count) ?
3813 	eap->line2 + 1 : curbuf->b_ml.ml_line_count;
3814     if (eap->cmdidx != CMD_append)
3815 	--curbuf->b_op_start.lnum;
3816     curbuf->b_op_end.lnum = (eap->line2 < lnum)
3817 					     ? lnum : curbuf->b_op_start.lnum;
3818     curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
3819     curwin->w_cursor.lnum = lnum;
3820     check_cursor_lnum();
3821     beginline(BL_SOL | BL_FIX);
3822 
3823     need_wait_return = FALSE;	/* don't use wait_return() now */
3824     ex_no_reprint = TRUE;
3825 }
3826 
3827 /*
3828  * ":change"
3829  */
3830     void
3831 ex_change(eap)
3832     exarg_T	*eap;
3833 {
3834     linenr_T	lnum;
3835 
3836     if (eap->line2 >= eap->line1
3837 	    && u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
3838 	return;
3839 
3840     /* the ! flag toggles autoindent */
3841     if (eap->forceit ? !curbuf->b_p_ai : curbuf->b_p_ai)
3842 	append_indent = get_indent_lnum(eap->line1);
3843 
3844     for (lnum = eap->line2; lnum >= eap->line1; --lnum)
3845     {
3846 	if (curbuf->b_ml.ml_flags & ML_EMPTY)	    /* nothing to delete */
3847 	    break;
3848 	ml_delete(eap->line1, FALSE);
3849     }
3850     deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum));
3851 
3852     /* ":append" on the line above the deleted lines. */
3853     eap->line2 = eap->line1;
3854     ex_append(eap);
3855 }
3856 
3857     void
3858 ex_z(eap)
3859     exarg_T	*eap;
3860 {
3861     char_u	*x;
3862     int		bigness;
3863     char_u	*kind;
3864     int		minus = 0;
3865     linenr_T	start, end, curs, i;
3866     int		j;
3867     linenr_T	lnum = eap->line2;
3868 
3869     /* Vi compatible: ":z!" uses display height, without a count uses
3870      * 'scroll' */
3871     if (eap->forceit)
3872 	bigness = curwin->w_height;
3873     else if (firstwin == lastwin)
3874 	bigness = curwin->w_p_scr * 2;
3875     else
3876 	bigness = curwin->w_height - 3;
3877     if (bigness < 1)
3878 	bigness = 1;
3879 
3880     x = eap->arg;
3881     kind = x;
3882     if (*kind == '-' || *kind == '+' || *kind == '='
3883 					      || *kind == '^' || *kind == '.')
3884 	++x;
3885     while (*x == '-' || *x == '+')
3886 	++x;
3887 
3888     if (*x != 0)
3889     {
3890 	if (!VIM_ISDIGIT(*x))
3891 	{
3892 	    EMSG(_("E144: non-numeric argument to :z"));
3893 	    return;
3894 	}
3895 	else
3896 	{
3897 	    bigness = atoi((char *)x);
3898 	    p_window = bigness;
3899 	    if (*kind == '=')
3900 		bigness += 2;
3901 	}
3902     }
3903 
3904     /* the number of '-' and '+' multiplies the distance */
3905     if (*kind == '-' || *kind == '+')
3906 	for (x = kind + 1; *x == *kind; ++x)
3907 	    ;
3908 
3909     switch (*kind)
3910     {
3911 	case '-':
3912 	    start = lnum - bigness * (x - kind);
3913 	    end = start + bigness;
3914 	    curs = end;
3915 	    break;
3916 
3917 	case '=':
3918 	    start = lnum - (bigness + 1) / 2 + 1;
3919 	    end = lnum + (bigness + 1) / 2 - 1;
3920 	    curs = lnum;
3921 	    minus = 1;
3922 	    break;
3923 
3924 	case '^':
3925 	    start = lnum - bigness * 2;
3926 	    end = lnum - bigness;
3927 	    curs = lnum - bigness;
3928 	    break;
3929 
3930 	case '.':
3931 	    start = lnum - (bigness + 1) / 2 + 1;
3932 	    end = lnum + (bigness + 1) / 2 - 1;
3933 	    curs = end;
3934 	    break;
3935 
3936 	default:  /* '+' */
3937 	    start = lnum;
3938 	    if (*kind == '+')
3939 		start += bigness * (x - kind - 1) + 1;
3940 	    else if (eap->addr_count == 0)
3941 		++start;
3942 	    end = start + bigness - 1;
3943 	    curs = end;
3944 	    break;
3945     }
3946 
3947     if (start < 1)
3948 	start = 1;
3949 
3950     if (end > curbuf->b_ml.ml_line_count)
3951 	end = curbuf->b_ml.ml_line_count;
3952 
3953     if (curs > curbuf->b_ml.ml_line_count)
3954 	curs = curbuf->b_ml.ml_line_count;
3955 
3956     for (i = start; i <= end; i++)
3957     {
3958 	if (minus && i == lnum)
3959 	{
3960 	    msg_putchar('\n');
3961 
3962 	    for (j = 1; j < Columns; j++)
3963 		msg_putchar('-');
3964 	}
3965 
3966 	print_line(i, eap->flags & EXFLAG_NR, eap->flags & EXFLAG_LIST);
3967 
3968 	if (minus && i == lnum)
3969 	{
3970 	    msg_putchar('\n');
3971 
3972 	    for (j = 1; j < Columns; j++)
3973 		msg_putchar('-');
3974 	}
3975     }
3976 
3977     curwin->w_cursor.lnum = curs;
3978     ex_no_reprint = TRUE;
3979 }
3980 
3981 /*
3982  * Check if the restricted flag is set.
3983  * If so, give an error message and return TRUE.
3984  * Otherwise, return FALSE.
3985  */
3986     int
3987 check_restricted()
3988 {
3989     if (restricted)
3990     {
3991 	EMSG(_("E145: Shell commands not allowed in rvim"));
3992 	return TRUE;
3993     }
3994     return FALSE;
3995 }
3996 
3997 /*
3998  * Check if the secure flag is set (.exrc or .vimrc in current directory).
3999  * If so, give an error message and return TRUE.
4000  * Otherwise, return FALSE.
4001  */
4002     int
4003 check_secure()
4004 {
4005     if (secure)
4006     {
4007 	secure = 2;
4008 	EMSG(_(e_curdir));
4009 	return TRUE;
4010     }
4011 #ifdef HAVE_SANDBOX
4012     /*
4013      * In the sandbox more things are not allowed, including the things
4014      * disallowed in secure mode.
4015      */
4016     if (sandbox != 0)
4017     {
4018 	EMSG(_(e_sandbox));
4019 	return TRUE;
4020     }
4021 #endif
4022     return FALSE;
4023 }
4024 
4025 static char_u	*old_sub = NULL;	/* previous substitute pattern */
4026 static int	global_need_beginline;	/* call beginline() after ":g" */
4027 
4028 /* do_sub()
4029  *
4030  * Perform a substitution from line eap->line1 to line eap->line2 using the
4031  * command pointed to by eap->arg which should be of the form:
4032  *
4033  * /pattern/substitution/{flags}
4034  *
4035  * The usual escapes are supported as described in the regexp docs.
4036  */
4037     void
4038 do_sub(eap)
4039     exarg_T	*eap;
4040 {
4041     linenr_T	lnum;
4042     long	i = 0;
4043     regmmatch_T regmatch;
4044     static int	do_all = FALSE;		/* do multiple substitutions per line */
4045     static int	do_ask = FALSE;		/* ask for confirmation */
4046     static int	do_count = FALSE;	/* count only */
4047     static int	do_error = TRUE;	/* if false, ignore errors */
4048     static int	do_print = FALSE;	/* print last line with subs. */
4049     static int	do_list = FALSE;	/* list last line with subs. */
4050     static int	do_number = FALSE;	/* list last line with line nr*/
4051     static int	do_ic = 0;		/* ignore case flag */
4052     char_u	*pat = NULL, *sub = NULL;	/* init for GCC */
4053     int		delimiter;
4054     int		sublen;
4055     int		got_quit = FALSE;
4056     int		got_match = FALSE;
4057     int		temp;
4058     int		which_pat;
4059     char_u	*cmd;
4060     int		save_State;
4061     linenr_T	first_line = 0;		/* first changed line */
4062     linenr_T	last_line= 0;		/* below last changed line AFTER the
4063 					 * change */
4064     linenr_T	old_line_count = curbuf->b_ml.ml_line_count;
4065     linenr_T	line2;
4066     long	nmatch;			/* number of lines in match */
4067     linenr_T	sub_firstlnum;		/* nr of first sub line */
4068     char_u	*sub_firstline;		/* allocated copy of first sub line */
4069     int		endcolumn = FALSE;	/* cursor in last column when done */
4070     pos_T	old_cursor = curwin->w_cursor;
4071 
4072     cmd = eap->arg;
4073     if (!global_busy)
4074     {
4075 	sub_nsubs = 0;
4076 	sub_nlines = 0;
4077     }
4078 
4079 #ifdef FEAT_FKMAP	/* reverse the flow of the Farsi characters */
4080     if (p_altkeymap && curwin->w_p_rl)
4081 	lrF_sub(cmd);
4082 #endif
4083 
4084     if (eap->cmdidx == CMD_tilde)
4085 	which_pat = RE_LAST;	/* use last used regexp */
4086     else
4087 	which_pat = RE_SUBST;	/* use last substitute regexp */
4088 
4089 				/* new pattern and substitution */
4090     if (eap->cmd[0] == 's' && *cmd != NUL && !vim_iswhite(*cmd)
4091 		&& vim_strchr((char_u *)"0123456789cegriIp|\"", *cmd) == NULL)
4092     {
4093 				/* don't accept alphanumeric for separator */
4094 	if (isalpha(*cmd))
4095 	{
4096 	    EMSG(_("E146: Regular expressions can't be delimited by letters"));
4097 	    return;
4098 	}
4099 	/*
4100 	 * undocumented vi feature:
4101 	 *  "\/sub/" and "\?sub?" use last used search pattern (almost like
4102 	 *  //sub/r).  "\&sub&" use last substitute pattern (like //sub/).
4103 	 */
4104 	if (*cmd == '\\')
4105 	{
4106 	    ++cmd;
4107 	    if (vim_strchr((char_u *)"/?&", *cmd) == NULL)
4108 	    {
4109 		EMSG(_(e_backslash));
4110 		return;
4111 	    }
4112 	    if (*cmd != '&')
4113 		which_pat = RE_SEARCH;	    /* use last '/' pattern */
4114 	    pat = (char_u *)"";		    /* empty search pattern */
4115 	    delimiter = *cmd++;		    /* remember delimiter character */
4116 	}
4117 	else		/* find the end of the regexp */
4118 	{
4119 	    which_pat = RE_LAST;	    /* use last used regexp */
4120 	    delimiter = *cmd++;		    /* remember delimiter character */
4121 	    pat = cmd;			    /* remember start of search pat */
4122 	    cmd = skip_regexp(cmd, delimiter, p_magic, &eap->arg);
4123 	    if (cmd[0] == delimiter)	    /* end delimiter found */
4124 		*cmd++ = NUL;		    /* replace it with a NUL */
4125 	}
4126 
4127 	/*
4128 	 * Small incompatibility: vi sees '\n' as end of the command, but in
4129 	 * Vim we want to use '\n' to find/substitute a NUL.
4130 	 */
4131 	sub = cmd;	    /* remember the start of the substitution */
4132 
4133 	while (cmd[0])
4134 	{
4135 	    if (cmd[0] == delimiter)		/* end delimiter found */
4136 	    {
4137 		*cmd++ = NUL;			/* replace it with a NUL */
4138 		break;
4139 	    }
4140 	    if (cmd[0] == '\\' && cmd[1] != 0)	/* skip escaped characters */
4141 		++cmd;
4142 	    mb_ptr_adv(cmd);
4143 	}
4144 
4145 	if (!eap->skip)
4146 	{
4147 	    /* In POSIX vi ":s/pat/%/" uses the previous subst. string. */
4148 	    if (STRCMP(sub, "%") == 0
4149 				 && vim_strchr(p_cpo, CPO_SUBPERCENT) != NULL)
4150 	    {
4151 		if (old_sub == NULL)	/* there is no previous command */
4152 		{
4153 		    EMSG(_(e_nopresub));
4154 		    return;
4155 		}
4156 		sub = old_sub;
4157 	    }
4158 	    else
4159 	    {
4160 		vim_free(old_sub);
4161 		old_sub = vim_strsave(sub);
4162 	    }
4163 	}
4164     }
4165     else if (!eap->skip)	/* use previous pattern and substitution */
4166     {
4167 	if (old_sub == NULL)	/* there is no previous command */
4168 	{
4169 	    EMSG(_(e_nopresub));
4170 	    return;
4171 	}
4172 	pat = NULL;		/* search_regcomp() will use previous pattern */
4173 	sub = old_sub;
4174 
4175 	/* Vi compatibility quirk: repeating with ":s" keeps the cursor in the
4176 	 * last column after using "$". */
4177 	endcolumn = (curwin->w_curswant == MAXCOL);
4178     }
4179 
4180     /*
4181      * Find trailing options.  When '&' is used, keep old options.
4182      */
4183     if (*cmd == '&')
4184 	++cmd;
4185     else
4186     {
4187 	if (!p_ed)
4188 	{
4189 	    if (p_gd)		/* default is global on */
4190 		do_all = TRUE;
4191 	    else
4192 		do_all = FALSE;
4193 	    do_ask = FALSE;
4194 	}
4195 	do_error = TRUE;
4196 	do_print = FALSE;
4197 	do_count = FALSE;
4198 	do_ic = 0;
4199     }
4200     while (*cmd)
4201     {
4202 	/*
4203 	 * Note that 'g' and 'c' are always inverted, also when p_ed is off.
4204 	 * 'r' is never inverted.
4205 	 */
4206 	if (*cmd == 'g')
4207 	    do_all = !do_all;
4208 	else if (*cmd == 'c')
4209 	    do_ask = !do_ask;
4210 	else if (*cmd == 'n')
4211 	    do_count = TRUE;
4212 	else if (*cmd == 'e')
4213 	    do_error = !do_error;
4214 	else if (*cmd == 'r')	    /* use last used regexp */
4215 	    which_pat = RE_LAST;
4216 	else if (*cmd == 'p')
4217 	    do_print = TRUE;
4218 	else if (*cmd == '#')
4219 	{
4220 	    do_print = TRUE;
4221 	    do_number = TRUE;
4222 	}
4223 	else if (*cmd == 'l')
4224 	{
4225 	    do_print = TRUE;
4226 	    do_list = TRUE;
4227 	}
4228 	else if (*cmd == 'i')	    /* ignore case */
4229 	    do_ic = 'i';
4230 	else if (*cmd == 'I')	    /* don't ignore case */
4231 	    do_ic = 'I';
4232 	else
4233 	    break;
4234 	++cmd;
4235     }
4236     if (do_count)
4237 	do_ask = FALSE;
4238 
4239     /*
4240      * check for a trailing count
4241      */
4242     cmd = skipwhite(cmd);
4243     if (VIM_ISDIGIT(*cmd))
4244     {
4245 	i = getdigits(&cmd);
4246 	if (i <= 0 && !eap->skip && do_error)
4247 	{
4248 	    EMSG(_(e_zerocount));
4249 	    return;
4250 	}
4251 	eap->line1 = eap->line2;
4252 	eap->line2 += i - 1;
4253 	if (eap->line2 > curbuf->b_ml.ml_line_count)
4254 	    eap->line2 = curbuf->b_ml.ml_line_count;
4255     }
4256 
4257     /*
4258      * check for trailing command or garbage
4259      */
4260     cmd = skipwhite(cmd);
4261     if (*cmd && *cmd != '"')	    /* if not end-of-line or comment */
4262     {
4263 	eap->nextcmd = check_nextcmd(cmd);
4264 	if (eap->nextcmd == NULL)
4265 	{
4266 	    EMSG(_(e_trailing));
4267 	    return;
4268 	}
4269     }
4270 
4271     if (eap->skip)	    /* not executing commands, only parsing */
4272 	return;
4273 
4274     if (search_regcomp(pat, RE_SUBST, which_pat, SEARCH_HIS, &regmatch) == FAIL)
4275     {
4276 	if (do_error)
4277 	    EMSG(_(e_invcmd));
4278 	return;
4279     }
4280 
4281     /* the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase' */
4282     if (do_ic == 'i')
4283 	regmatch.rmm_ic = TRUE;
4284     else if (do_ic == 'I')
4285 	regmatch.rmm_ic = FALSE;
4286 
4287     sub_firstline = NULL;
4288 
4289     /*
4290      * ~ in the substitute pattern is replaced with the old pattern.
4291      * We do it here once to avoid it to be replaced over and over again.
4292      * But don't do it when it starts with "\=", then it's an expression.
4293      */
4294     if (!(sub[0] == '\\' && sub[1] == '='))
4295 	sub = regtilde(sub, p_magic);
4296 
4297     /*
4298      * Check for a match on each line.
4299      */
4300     line2 = eap->line2;
4301     for (lnum = eap->line1; lnum <= line2 && !(got_quit
4302 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
4303 		|| aborting()
4304 #endif
4305 		); ++lnum)
4306     {
4307 	sub_firstlnum = lnum;
4308 	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
4309 	if (nmatch)
4310 	{
4311 	    colnr_T	copycol;
4312 	    colnr_T	matchcol;
4313 	    colnr_T	prev_matchcol = MAXCOL;
4314 	    char_u	*new_end, *new_start = NULL;
4315 	    unsigned	new_start_len = 0;
4316 	    char_u	*p1;
4317 	    int		did_sub = FALSE;
4318 	    int		lastone;
4319 	    unsigned	len, needed_len;
4320 	    long	nmatch_tl = 0;	/* nr of lines matched below lnum */
4321 	    int		do_again;	/* do it again after joining lines */
4322 	    int		skip_match = FALSE;
4323 
4324 	    /*
4325 	     * The new text is build up step by step, to avoid too much
4326 	     * copying.  There are these pieces:
4327 	     * sub_firstline	The old text, unmodifed.
4328 	     * copycol		Column in the old text where we started
4329 	     *			looking for a match; from here old text still
4330 	     *			needs to be copied to the new text.
4331 	     * matchcol		Column number of the old text where to look
4332 	     *			for the next match.  It's just after the
4333 	     *			previous match or one further.
4334 	     * prev_matchcol	Column just after the previous match (if any).
4335 	     *			Mostly equal to matchcol, except for the first
4336 	     *			match and after skipping an empty match.
4337 	     * regmatch.*pos	Where the pattern matched in the old text.
4338 	     * new_start	The new text, all that has been produced so
4339 	     *			far.
4340 	     * new_end		The new text, where to append new text.
4341 	     *
4342 	     * lnum		The line number where we were looking for the
4343 	     *			first match in the old line.
4344 	     * sub_firstlnum	The line number in the buffer where to look
4345 	     *			for a match.  Can be different from "lnum"
4346 	     *			when the pattern or substitute string contains
4347 	     *			line breaks.
4348 	     *
4349 	     * Special situations:
4350 	     * - When the substitute string contains a line break, the part up
4351 	     *   to the line break is inserted in the text, but the copy of
4352 	     *   the original line is kept.  "sub_firstlnum" is adjusted for
4353 	     *   the inserted lines.
4354 	     * - When the matched pattern contains a line break, the old line
4355 	     *   is taken from the line at the end of the pattern.  The lines
4356 	     *   in the match are deleted later, "sub_firstlnum" is adjusted
4357 	     *   accordingly.
4358 	     *
4359 	     * The new text is built up in new_start[].  It has some extra
4360 	     * room to avoid using alloc()/free() too often.  new_start_len is
4361 	     * the lenght of the allocated memory at new_start.
4362 	     *
4363 	     * Make a copy of the old line, so it won't be taken away when
4364 	     * updating the screen or handling a multi-line match.  The "old_"
4365 	     * pointers point into this copy.
4366 	     */
4367 	    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
4368 	    if (sub_firstline == NULL)
4369 	    {
4370 		vim_free(new_start);
4371 		goto outofmem;
4372 	    }
4373 	    copycol = 0;
4374 	    matchcol = 0;
4375 
4376 	    /* At first match, remember current cursor position. */
4377 	    if (!got_match)
4378 	    {
4379 		setpcmark();
4380 		got_match = TRUE;
4381 	    }
4382 
4383 	    /*
4384 	     * Loop until nothing more to replace in this line.
4385 	     * 1. Handle match with empty string.
4386 	     * 2. If do_ask is set, ask for confirmation.
4387 	     * 3. substitute the string.
4388 	     * 4. if do_all is set, find next match
4389 	     * 5. break if there isn't another match in this line
4390 	     */
4391 	    for (;;)
4392 	    {
4393 		/* Save the line number of the last change for the final
4394 		 * cursor position (just like Vi). */
4395 		curwin->w_cursor.lnum = lnum;
4396 		do_again = FALSE;
4397 
4398 		/*
4399 		 * 1. Match empty string does not count, except for first
4400 		 * match.  This reproduces the strange vi behaviour.
4401 		 * This also catches endless loops.
4402 		 */
4403 		if (matchcol == prev_matchcol
4404 			&& regmatch.endpos[0].lnum == 0
4405 			&& matchcol == regmatch.endpos[0].col)
4406 		{
4407 		    if (sub_firstline[matchcol] == NUL)
4408 			/* We already were at the end of the line.  Don't look
4409 			 * for a match in this line again. */
4410 			skip_match = TRUE;
4411 		    else
4412 			++matchcol; /* search for a match at next column */
4413 		    goto skip;
4414 		}
4415 
4416 		/* Normally we continue searching for a match just after the
4417 		 * previous match. */
4418 		matchcol = regmatch.endpos[0].col;
4419 		prev_matchcol = matchcol;
4420 
4421 		/*
4422 		 * 2. If do_count is set only increase the counter.
4423 		 *    If do_ask is set, ask for confirmation.
4424 		 */
4425 		if (do_count)
4426 		{
4427 		    /* For a multi-line match, put matchcol at the NUL at
4428 		     * the end of the line and set nmatch to one, so that
4429 		     * we continue looking for a match on the next line.
4430 		     * Avoids that ":s/\nB\@=//gc" get stuck. */
4431 		    if (nmatch > 1)
4432 		    {
4433 			matchcol = STRLEN(sub_firstline);
4434 			nmatch = 1;
4435 		    }
4436 		    sub_nsubs++;
4437 		    did_sub = TRUE;
4438 		    goto skip;
4439 		}
4440 
4441 		if (do_ask)
4442 		{
4443 		    /* change State to CONFIRM, so that the mouse works
4444 		     * properly */
4445 		    save_State = State;
4446 		    State = CONFIRM;
4447 #ifdef FEAT_MOUSE
4448 		    setmouse();		/* disable mouse in xterm */
4449 #endif
4450 		    curwin->w_cursor.col = regmatch.startpos[0].col;
4451 
4452 		    /* When 'cpoptions' contains "u" don't sync undo when
4453 		     * asking for confirmation. */
4454 		    if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
4455 			++no_u_sync;
4456 
4457 		    /*
4458 		     * Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
4459 		     */
4460 		    while (do_ask)
4461 		    {
4462 			if (exmode_active)
4463 			{
4464 			    char_u	*resp;
4465 			    colnr_T	sc, ec;
4466 
4467 			    print_line_no_prefix(lnum, FALSE, FALSE);
4468 
4469 			    getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
4470 			    curwin->w_cursor.col = regmatch.endpos[0].col - 1;
4471 			    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
4472 			    msg_start();
4473 			    for (i = 0; i < (long)sc; ++i)
4474 				msg_putchar(' ');
4475 			    for ( ; i <= (long)ec; ++i)
4476 				msg_putchar('^');
4477 
4478 			    resp = getexmodeline('?', NULL, 0);
4479 			    if (resp != NULL)
4480 			    {
4481 				i = *resp;
4482 				vim_free(resp);
4483 			    }
4484 			}
4485 			else
4486 			{
4487 #ifdef FEAT_FOLDING
4488 			    int save_p_fen = curwin->w_p_fen;
4489 
4490 			    curwin->w_p_fen = FALSE;
4491 #endif
4492 			    /* Invert the matched string.
4493 			     * Remove the inversion afterwards. */
4494 			    temp = RedrawingDisabled;
4495 			    RedrawingDisabled = 0;
4496 
4497 			    search_match_lines = regmatch.endpos[0].lnum;
4498 			    search_match_endcol = regmatch.endpos[0].col;
4499 			    highlight_match = TRUE;
4500 
4501 			    update_topline();
4502 			    validate_cursor();
4503 			    update_screen(SOME_VALID);
4504 			    highlight_match = FALSE;
4505 			    redraw_later(SOME_VALID);
4506 
4507 #ifdef FEAT_FOLDING
4508 			    curwin->w_p_fen = save_p_fen;
4509 #endif
4510 			    if (msg_row == Rows - 1)
4511 				msg_didout = FALSE;	/* avoid a scroll-up */
4512 			    msg_starthere();
4513 			    i = msg_scroll;
4514 			    msg_scroll = 0;		/* truncate msg when
4515 							   needed */
4516 			    msg_no_more = TRUE;
4517 			    /* write message same highlighting as for
4518 			     * wait_return */
4519 			    smsg_attr(hl_attr(HLF_R),
4520 				    (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
4521 			    msg_no_more = FALSE;
4522 			    msg_scroll = i;
4523 			    showruler(TRUE);
4524 			    windgoto(msg_row, msg_col);
4525 			    RedrawingDisabled = temp;
4526 
4527 #ifdef USE_ON_FLY_SCROLL
4528 			    dont_scroll = FALSE; /* allow scrolling here */
4529 #endif
4530 			    ++no_mapping;	/* don't map this key */
4531 			    ++allow_keys;	/* allow special keys */
4532 			    i = safe_vgetc();
4533 			    --allow_keys;
4534 			    --no_mapping;
4535 
4536 			    /* clear the question */
4537 			    msg_didout = FALSE;	/* don't scroll up */
4538 			    msg_col = 0;
4539 			    gotocmdline(TRUE);
4540 			}
4541 
4542 			need_wait_return = FALSE; /* no hit-return prompt */
4543 			if (i == 'q' || i == ESC || i == Ctrl_C
4544 #ifdef UNIX
4545 				|| i == intr_char
4546 #endif
4547 				)
4548 			{
4549 			    got_quit = TRUE;
4550 			    break;
4551 			}
4552 			if (i == 'n')
4553 			    break;
4554 			if (i == 'y')
4555 			    break;
4556 			if (i == 'l')
4557 			{
4558 			    /* last: replace and then stop */
4559 			    do_all = FALSE;
4560 			    line2 = lnum;
4561 			    break;
4562 			}
4563 			if (i == 'a')
4564 			{
4565 			    do_ask = FALSE;
4566 			    break;
4567 			}
4568 #ifdef FEAT_INS_EXPAND
4569 			if (i == Ctrl_E)
4570 			    scrollup_clamp();
4571 			else if (i == Ctrl_Y)
4572 			    scrolldown_clamp();
4573 #endif
4574 		    }
4575 		    State = save_State;
4576 #ifdef FEAT_MOUSE
4577 		    setmouse();
4578 #endif
4579 		    if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
4580 			--no_u_sync;
4581 
4582 		    if (i == 'n')
4583 		    {
4584 			/* For a multi-line match, put matchcol at the NUL at
4585 			 * the end of the line and set nmatch to one, so that
4586 			 * we continue looking for a match on the next line.
4587 			 * Avoids that ":s/\nB\@=//gc" get stuck. */
4588 			if (nmatch > 1)
4589 			{
4590 			    matchcol = STRLEN(sub_firstline);
4591 			    nmatch = 1;
4592 			}
4593 			goto skip;
4594 		    }
4595 		    if (got_quit)
4596 			break;
4597 		}
4598 
4599 		/* Move the cursor to the start of the match, so that we can
4600 		 * use "\=col("."). */
4601 		curwin->w_cursor.col = regmatch.startpos[0].col;
4602 
4603 		/*
4604 		 * 3. substitute the string.
4605 		 */
4606 		/* get length of substitution part */
4607 		sublen = vim_regsub_multi(&regmatch, sub_firstlnum,
4608 				    sub, sub_firstline, FALSE, p_magic, TRUE);
4609 
4610 		/* When the match included the "$" of the last line it may
4611 		 * include one line too much. */
4612 		if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1)
4613 		{
4614 		    nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
4615 		    skip_match = TRUE;
4616 		}
4617 
4618 		/* Need room for:
4619 		 * - result so far in new_start (not for first sub in line)
4620 		 * - original text up to match
4621 		 * - length of substituted part
4622 		 * - original text after match
4623 		 */
4624 		if (nmatch == 1)
4625 		    p1 = sub_firstline;
4626 		else
4627 		{
4628 		    p1 = ml_get(sub_firstlnum + nmatch - 1);
4629 		    nmatch_tl += nmatch - 1;
4630 		}
4631 		i = regmatch.startpos[0].col - copycol;
4632 		needed_len = i + ((unsigned)STRLEN(p1) - regmatch.endpos[0].col)
4633 								 + sublen + 1;
4634 		if (new_start == NULL)
4635 		{
4636 		    /*
4637 		     * Get some space for a temporary buffer to do the
4638 		     * substitution into (and some extra space to avoid
4639 		     * too many calls to alloc()/free()).
4640 		     */
4641 		    new_start_len = needed_len + 50;
4642 		    if ((new_start = alloc_check(new_start_len)) == NULL)
4643 			goto outofmem;
4644 		    *new_start = NUL;
4645 		    new_end = new_start;
4646 		}
4647 		else
4648 		{
4649 		    /*
4650 		     * Check if the temporary buffer is long enough to do the
4651 		     * substitution into.  If not, make it larger (with a bit
4652 		     * extra to avoid too many calls to alloc()/free()).
4653 		     */
4654 		    len = (unsigned)STRLEN(new_start);
4655 		    needed_len += len;
4656 		    if (needed_len > new_start_len)
4657 		    {
4658 			new_start_len = needed_len + 50;
4659 			if ((p1 = alloc_check(new_start_len)) == NULL)
4660 			{
4661 			    vim_free(new_start);
4662 			    goto outofmem;
4663 			}
4664 			mch_memmove(p1, new_start, (size_t)(len + 1));
4665 			vim_free(new_start);
4666 			new_start = p1;
4667 		    }
4668 		    new_end = new_start + len;
4669 		}
4670 
4671 		/*
4672 		 * copy the text up to the part that matched
4673 		 */
4674 		mch_memmove(new_end, sub_firstline + copycol, (size_t)i);
4675 		new_end += i;
4676 
4677 		(void)vim_regsub_multi(&regmatch, sub_firstlnum,
4678 					   sub, new_end, TRUE, p_magic, TRUE);
4679 		sub_nsubs++;
4680 		did_sub = TRUE;
4681 
4682 		/* Move the cursor to the start of the line, to avoid that it
4683 		 * is beyond the end of the line after the substitution. */
4684 		curwin->w_cursor.col = 0;
4685 
4686 		/* For a multi-line match, make a copy of the last matched
4687 		 * line and continue in that one. */
4688 		if (nmatch > 1)
4689 		{
4690 		    sub_firstlnum += nmatch - 1;
4691 		    vim_free(sub_firstline);
4692 		    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
4693 		    /* When going beyond the last line, stop substituting. */
4694 		    if (sub_firstlnum <= line2)
4695 			do_again = TRUE;
4696 		    else
4697 			do_all = FALSE;
4698 		}
4699 
4700 		/* Remember next character to be copied. */
4701 		copycol = regmatch.endpos[0].col;
4702 
4703 		/*
4704 		 * Now the trick is to replace CTRL-M chars with a real line
4705 		 * break.  This would make it impossible to insert a CTRL-M in
4706 		 * the text.  The line break can be avoided by preceding the
4707 		 * CTRL-M with a backslash.  To be able to insert a backslash,
4708 		 * they must be doubled in the string and are halved here.
4709 		 * That is Vi compatible.
4710 		 */
4711 		for (p1 = new_end; *p1; ++p1)
4712 		{
4713 		    if (p1[0] == '\\' && p1[1] != NUL)  /* remove backslash */
4714 			mch_memmove(p1, p1 + 1, STRLEN(p1));
4715 		    else if (*p1 == CAR)
4716 		    {
4717 			if (u_inssub(lnum) == OK)   /* prepare for undo */
4718 			{
4719 			    *p1 = NUL;		    /* truncate up to the CR */
4720 			    ml_append(lnum - 1, new_start,
4721 					(colnr_T)(p1 - new_start + 1), FALSE);
4722 			    mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
4723 			    if (do_ask)
4724 				appended_lines(lnum - 1, 1L);
4725 			    else
4726 			    {
4727 				if (first_line == 0)
4728 				    first_line = lnum;
4729 				last_line = lnum + 1;
4730 			    }
4731 			    /* All line numbers increase. */
4732 			    ++sub_firstlnum;
4733 			    ++lnum;
4734 			    ++line2;
4735 			    /* move the cursor to the new line, like Vi */
4736 			    ++curwin->w_cursor.lnum;
4737 			    STRCPY(new_start, p1 + 1);	/* copy the rest */
4738 			    p1 = new_start - 1;
4739 			}
4740 		    }
4741 #ifdef FEAT_MBYTE
4742 		    else if (has_mbyte)
4743 			p1 += (*mb_ptr2len)(p1) - 1;
4744 #endif
4745 		}
4746 
4747 		/*
4748 		 * 4. If do_all is set, find next match.
4749 		 * Prevent endless loop with patterns that match empty
4750 		 * strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g.
4751 		 * But ":s/\n/#/" is OK.
4752 		 */
4753 skip:
4754 		/* We already know that we did the last subst when we are at
4755 		 * the end of the line, except that a pattern like
4756 		 * "bar\|\nfoo" may match at the NUL. */
4757 		lastone = (skip_match
4758 			|| got_int
4759 			|| got_quit
4760 			|| !(do_all || do_again)
4761 			|| (sub_firstline[matchcol] == NUL && nmatch <= 1
4762 					 && !re_multiline(regmatch.regprog)));
4763 		nmatch = -1;
4764 
4765 		/*
4766 		 * Replace the line in the buffer when needed.  This is
4767 		 * skipped when there are more matches.
4768 		 * The check for nmatch_tl is needed for when multi-line
4769 		 * matching must replace the lines before trying to do another
4770 		 * match, otherwise "\@<=" won't work.
4771 		 * When asking the user we like to show the already replaced
4772 		 * text, but don't do it when "\<@=" or "\<@!" is used, it
4773 		 * changes what matches.
4774 		 */
4775 		if (lastone
4776 			|| (do_ask && !re_lookbehind(regmatch.regprog))
4777 			|| nmatch_tl > 0
4778 			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
4779 				       curbuf, sub_firstlnum, matchcol)) == 0)
4780 		{
4781 		    if (new_start != NULL)
4782 		    {
4783 			/*
4784 			 * Copy the rest of the line, that didn't match.
4785 			 * "matchcol" has to be adjusted, we use the end of
4786 			 * the line as reference, because the substitute may
4787 			 * have changed the number of characters.  Same for
4788 			 * "prev_matchcol".
4789 			 */
4790 			STRCAT(new_start, sub_firstline + copycol);
4791 			matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
4792 			prev_matchcol = (colnr_T)STRLEN(sub_firstline)
4793 							      - prev_matchcol;
4794 
4795 			if (u_savesub(lnum) != OK)
4796 			    break;
4797 			ml_replace(lnum, new_start, TRUE);
4798 
4799 			if (nmatch_tl > 0)
4800 			{
4801 			    /*
4802 			     * Matched lines have now been substituted and are
4803 			     * useless, delete them.  The part after the match
4804 			     * has been appended to new_start, we don't need
4805 			     * it in the buffer.
4806 			     */
4807 			    ++lnum;
4808 			    if (u_savedel(lnum, nmatch_tl) != OK)
4809 				break;
4810 			    for (i = 0; i < nmatch_tl; ++i)
4811 				ml_delete(lnum, (int)FALSE);
4812 			    mark_adjust(lnum, lnum + nmatch_tl - 1,
4813 						   (long)MAXLNUM, -nmatch_tl);
4814 			    if (do_ask)
4815 				deleted_lines(lnum, nmatch_tl);
4816 			    --lnum;
4817 			    line2 -= nmatch_tl; /* nr of lines decreases */
4818 			    nmatch_tl = 0;
4819 			}
4820 
4821 			/* When asking, undo is saved each time, must also set
4822 			 * changed flag each time. */
4823 			if (do_ask)
4824 			    changed_bytes(lnum, 0);
4825 			else
4826 			{
4827 			    if (first_line == 0)
4828 				first_line = lnum;
4829 			    last_line = lnum + 1;
4830 			}
4831 
4832 			sub_firstlnum = lnum;
4833 			vim_free(sub_firstline);    /* free the temp buffer */
4834 			sub_firstline = new_start;
4835 			new_start = NULL;
4836 			matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
4837 			prev_matchcol = (colnr_T)STRLEN(sub_firstline)
4838 							      - prev_matchcol;
4839 			copycol = 0;
4840 		    }
4841 		    if (nmatch == -1 && !lastone)
4842 			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
4843 						     sub_firstlnum, matchcol);
4844 
4845 		    /*
4846 		     * 5. break if there isn't another match in this line
4847 		     */
4848 		    if (nmatch <= 0)
4849 			break;
4850 		}
4851 
4852 		line_breakcheck();
4853 	    }
4854 
4855 	    if (did_sub)
4856 		++sub_nlines;
4857 	    vim_free(sub_firstline);	/* free the copy of the original line */
4858 	    sub_firstline = NULL;
4859 	}
4860 
4861 	line_breakcheck();
4862     }
4863 
4864     if (first_line != 0)
4865     {
4866 	/* Need to subtract the number of added lines from "last_line" to get
4867 	 * the line number before the change (same as adding the number of
4868 	 * deleted lines). */
4869 	i = curbuf->b_ml.ml_line_count - old_line_count;
4870 	changed_lines(first_line, 0, last_line - i, i);
4871     }
4872 
4873 outofmem:
4874     vim_free(sub_firstline); /* may have to free allocated copy of the line */
4875 
4876     /* ":s/pat//n" doesn't move the cursor */
4877     if (do_count)
4878 	curwin->w_cursor = old_cursor;
4879 
4880     if (sub_nsubs)
4881     {
4882 	/* Set the '[ and '] marks. */
4883 	curbuf->b_op_start.lnum = eap->line1;
4884 	curbuf->b_op_end.lnum = line2;
4885 	curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
4886 
4887 	if (!global_busy)
4888 	{
4889 	    if (endcolumn)
4890 		coladvance((colnr_T)MAXCOL);
4891 	    else
4892 		beginline(BL_WHITE | BL_FIX);
4893 	    if (!do_sub_msg(do_count) && do_ask)
4894 		MSG("");
4895 	}
4896 	else
4897 	    global_need_beginline = TRUE;
4898 	if (do_print)
4899 	    print_line(curwin->w_cursor.lnum, do_number, do_list);
4900     }
4901     else if (!global_busy)
4902     {
4903 	if (got_int)		/* interrupted */
4904 	    EMSG(_(e_interr));
4905 	else if (got_match)	/* did find something but nothing substituted */
4906 	    MSG("");
4907 	else if (do_error)	/* nothing found */
4908 	    EMSG2(_(e_patnotf2), get_search_pat());
4909     }
4910 
4911     vim_free(regmatch.regprog);
4912 }
4913 
4914 /*
4915  * Give message for number of substitutions.
4916  * Can also be used after a ":global" command.
4917  * Return TRUE if a message was given.
4918  */
4919     int
4920 do_sub_msg(count_only)
4921     int	    count_only;		/* used 'n' flag for ":s" */
4922 {
4923     int	    len = 0;
4924 
4925     /*
4926      * Only report substitutions when:
4927      * - more than 'report' substitutions
4928      * - command was typed by user, or number of changed lines > 'report'
4929      * - giving messages is not disabled by 'lazyredraw'
4930      */
4931     if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
4932 		|| count_only)
4933 	    && messaging())
4934     {
4935 	if (got_int)
4936 	{
4937 	    STRCPY(msg_buf, _("(Interrupted) "));
4938 	    len = STRLEN(msg_buf);
4939 	}
4940 	if (sub_nsubs == 1)
4941 	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
4942 		    "%s", count_only ? _("1 match") : _("1 substitution"));
4943 	else
4944 	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
4945 		    count_only ? _("%ld matches") : _("%ld substitutions"),
4946 								   sub_nsubs);
4947 	len = STRLEN(msg_buf);
4948 	if (sub_nlines == 1)
4949 	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
4950 		    "%s", _(" on 1 line"));
4951 	else
4952 	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
4953 		    _(" on %ld lines"), (long)sub_nlines);
4954 	if (msg(msg_buf))
4955 	    /* save message to display it after redraw */
4956 	    set_keep_msg(msg_buf, 0);
4957 	return TRUE;
4958     }
4959     if (got_int)
4960     {
4961 	EMSG(_(e_interr));
4962 	return TRUE;
4963     }
4964     return FALSE;
4965 }
4966 
4967 /*
4968  * Execute a global command of the form:
4969  *
4970  * g/pattern/X : execute X on all lines where pattern matches
4971  * v/pattern/X : execute X on all lines where pattern does not match
4972  *
4973  * where 'X' is an EX command
4974  *
4975  * The command character (as well as the trailing slash) is optional, and
4976  * is assumed to be 'p' if missing.
4977  *
4978  * This is implemented in two passes: first we scan the file for the pattern and
4979  * set a mark for each line that (not) matches. secondly we execute the command
4980  * for each line that has a mark. This is required because after deleting
4981  * lines we do not know where to search for the next match.
4982  */
4983     void
4984 ex_global(eap)
4985     exarg_T	*eap;
4986 {
4987     linenr_T	lnum;		/* line number according to old situation */
4988     int		ndone = 0;
4989     int		type;		/* first char of cmd: 'v' or 'g' */
4990     char_u	*cmd;		/* command argument */
4991 
4992     char_u	delim;		/* delimiter, normally '/' */
4993     char_u	*pat;
4994     regmmatch_T	regmatch;
4995     int		match;
4996     int		which_pat;
4997 
4998     if (global_busy)
4999     {
5000 	EMSG(_("E147: Cannot do :global recursive"));	/* will increment global_busy */
5001 	return;
5002     }
5003 
5004     if (eap->forceit)		    /* ":global!" is like ":vglobal" */
5005 	type = 'v';
5006     else
5007 	type = *eap->cmd;
5008     cmd = eap->arg;
5009     which_pat = RE_LAST;	    /* default: use last used regexp */
5010     sub_nsubs = 0;
5011     sub_nlines = 0;
5012 
5013     /*
5014      * undocumented vi feature:
5015      *	"\/" and "\?": use previous search pattern.
5016      *		 "\&": use previous substitute pattern.
5017      */
5018     if (*cmd == '\\')
5019     {
5020 	++cmd;
5021 	if (vim_strchr((char_u *)"/?&", *cmd) == NULL)
5022 	{
5023 	    EMSG(_(e_backslash));
5024 	    return;
5025 	}
5026 	if (*cmd == '&')
5027 	    which_pat = RE_SUBST;	/* use previous substitute pattern */
5028 	else
5029 	    which_pat = RE_SEARCH;	/* use previous search pattern */
5030 	++cmd;
5031 	pat = (char_u *)"";
5032     }
5033     else if (*cmd == NUL)
5034     {
5035 	EMSG(_("E148: Regular expression missing from global"));
5036 	return;
5037     }
5038     else
5039     {
5040 	delim = *cmd;		/* get the delimiter */
5041 	if (delim)
5042 	    ++cmd;		/* skip delimiter if there is one */
5043 	pat = cmd;		/* remember start of pattern */
5044 	cmd = skip_regexp(cmd, delim, p_magic, &eap->arg);
5045 	if (cmd[0] == delim)		    /* end delimiter found */
5046 	    *cmd++ = NUL;		    /* replace it with a NUL */
5047     }
5048 
5049 #ifdef FEAT_FKMAP	/* when in Farsi mode, reverse the character flow */
5050     if (p_altkeymap && curwin->w_p_rl)
5051 	lrFswap(pat,0);
5052 #endif
5053 
5054     if (search_regcomp(pat, RE_BOTH, which_pat, SEARCH_HIS, &regmatch) == FAIL)
5055     {
5056 	EMSG(_(e_invcmd));
5057 	return;
5058     }
5059 
5060     /*
5061      * pass 1: set marks for each (not) matching line
5062      */
5063     for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum)
5064     {
5065 	/* a match on this line? */
5066 	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
5067 	if ((type == 'g' && match) || (type == 'v' && !match))
5068 	{
5069 	    ml_setmarked(lnum);
5070 	    ndone++;
5071 	}
5072 	line_breakcheck();
5073     }
5074 
5075     /*
5076      * pass 2: execute the command for each line that has been marked
5077      */
5078     if (got_int)
5079 	MSG(_(e_interr));
5080     else if (ndone == 0)
5081     {
5082 	if (type == 'v')
5083 	    smsg((char_u *)_("Pattern found in every line: %s"), pat);
5084 	else
5085 	    smsg((char_u *)_(e_patnotf2), pat);
5086     }
5087     else
5088 	global_exe(cmd);
5089 
5090     ml_clearmarked();	   /* clear rest of the marks */
5091     vim_free(regmatch.regprog);
5092 }
5093 
5094 /*
5095  * Execute "cmd" on lines marked with ml_setmarked().
5096  */
5097     void
5098 global_exe(cmd)
5099     char_u	*cmd;
5100 {
5101     linenr_T	old_lcount;	/* b_ml.ml_line_count before the command */
5102     linenr_T	lnum;		/* line number according to old situation */
5103 
5104     /*
5105      * Set current position only once for a global command.
5106      * If global_busy is set, setpcmark() will not do anything.
5107      * If there is an error, global_busy will be incremented.
5108      */
5109     setpcmark();
5110 
5111     /* When the command writes a message, don't overwrite the command. */
5112     msg_didout = TRUE;
5113 
5114     global_need_beginline = FALSE;
5115     global_busy = 1;
5116     old_lcount = curbuf->b_ml.ml_line_count;
5117     while (!got_int && (lnum = ml_firstmarked()) != 0 && global_busy == 1)
5118     {
5119 	curwin->w_cursor.lnum = lnum;
5120 	curwin->w_cursor.col = 0;
5121 	if (*cmd == NUL || *cmd == '\n')
5122 	    do_cmdline((char_u *)"p", NULL, NULL, DOCMD_NOWAIT);
5123 	else
5124 	    do_cmdline(cmd, NULL, NULL, DOCMD_NOWAIT);
5125 	ui_breakcheck();
5126     }
5127 
5128     global_busy = 0;
5129     if (global_need_beginline)
5130 	beginline(BL_WHITE | BL_FIX);
5131     else
5132 	check_cursor();	/* cursor may be beyond the end of the line */
5133 
5134     /* the cursor may not have moved in the text but a change in a previous
5135      * line may move it on the screen */
5136     changed_line_abv_curs();
5137 
5138     /* If it looks like no message was written, allow overwriting the
5139      * command with the report for number of changes. */
5140     if (msg_col == 0 && msg_scrolled == 0)
5141 	msg_didout = FALSE;
5142 
5143     /* If subsitutes done, report number of substitues, otherwise report
5144      * number of extra or deleted lines. */
5145     if (!do_sub_msg(FALSE))
5146 	msgmore(curbuf->b_ml.ml_line_count - old_lcount);
5147 }
5148 
5149 #ifdef FEAT_VIMINFO
5150     int
5151 read_viminfo_sub_string(virp, force)
5152     vir_T	*virp;
5153     int		force;
5154 {
5155     if (old_sub != NULL && force)
5156 	vim_free(old_sub);
5157     if (force || old_sub == NULL)
5158 	old_sub = viminfo_readstring(virp, 1, TRUE);
5159     return viminfo_readline(virp);
5160 }
5161 
5162     void
5163 write_viminfo_sub_string(fp)
5164     FILE    *fp;
5165 {
5166     if (get_viminfo_parameter('/') != 0 && old_sub != NULL)
5167     {
5168 	fprintf(fp, _("\n# Last Substitute String:\n$"));
5169 	viminfo_writestring(fp, old_sub);
5170     }
5171 }
5172 #endif /* FEAT_VIMINFO */
5173 
5174 #if defined(EXITFREE) || defined(PROTO)
5175     void
5176 free_old_sub()
5177 {
5178     vim_free(old_sub);
5179 }
5180 #endif
5181 
5182 #if (defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)) || defined(PROTO)
5183 /*
5184  * Set up for a tagpreview.
5185  * Return TRUE when it was created.
5186  */
5187     int
5188 prepare_tagpreview()
5189 {
5190     win_T	*wp;
5191 
5192 # ifdef FEAT_GUI
5193     need_mouse_correct = TRUE;
5194 # endif
5195 
5196     /*
5197      * If there is already a preview window open, use that one.
5198      */
5199     if (!curwin->w_p_pvw)
5200     {
5201 	for (wp = firstwin; wp != NULL; wp = wp->w_next)
5202 	    if (wp->w_p_pvw)
5203 		break;
5204 	if (wp != NULL)
5205 	    win_enter(wp, TRUE);
5206 	else
5207 	{
5208 	    /*
5209 	     * There is no preview window open yet.  Create one.
5210 	     */
5211 	    if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0)
5212 								      == FAIL)
5213 		return FALSE;
5214 	    curwin->w_p_pvw = TRUE;
5215 	    curwin->w_p_wfh = TRUE;
5216 # ifdef FEAT_SCROLLBIND
5217 	    curwin->w_p_scb = FALSE;	    /* don't take over 'scrollbind' */
5218 # endif
5219 # ifdef FEAT_DIFF
5220 	    curwin->w_p_diff = FALSE;	    /* no 'diff' */
5221 # endif
5222 # ifdef FEAT_FOLDING
5223 	    curwin->w_p_fdc = 0;	    /* no 'foldcolumn' */
5224 # endif
5225 	    return TRUE;
5226 	}
5227     }
5228     return FALSE;
5229 }
5230 
5231 #endif
5232 
5233 
5234 /*
5235  * ":help": open a read-only window on a help file
5236  */
5237     void
5238 ex_help(eap)
5239     exarg_T	*eap;
5240 {
5241     char_u	*arg;
5242     char_u	*tag;
5243     FILE	*helpfd;	/* file descriptor of help file */
5244     int		n;
5245     int		i;
5246 #ifdef FEAT_WINDOWS
5247     win_T	*wp;
5248 #endif
5249     int		num_matches;
5250     char_u	**matches;
5251     char_u	*p;
5252     int		empty_fnum = 0;
5253     int		alt_fnum = 0;
5254     buf_T	*buf;
5255 #ifdef FEAT_MULTI_LANG
5256     int		len;
5257     char_u	*lang;
5258 #endif
5259 
5260     if (eap != NULL)
5261     {
5262 	/*
5263 	 * A ":help" command ends at the first LF, or at a '|' that is
5264 	 * followed by some text.  Set nextcmd to the following command.
5265 	 */
5266 	for (arg = eap->arg; *arg; ++arg)
5267 	{
5268 	    if (*arg == '\n' || *arg == '\r'
5269 		    || (*arg == '|' && arg[1] != NUL && arg[1] != '|'))
5270 	    {
5271 		*arg++ = NUL;
5272 		eap->nextcmd = arg;
5273 		break;
5274 	    }
5275 	}
5276 	arg = eap->arg;
5277 
5278 	if (eap->forceit && *arg == NUL)
5279 	{
5280 	    EMSG(_("E478: Don't panic!"));
5281 	    return;
5282 	}
5283 
5284 	if (eap->skip)	    /* not executing commands */
5285 	    return;
5286     }
5287     else
5288 	arg = (char_u *)"";
5289 
5290     /* remove trailing blanks */
5291     p = arg + STRLEN(arg) - 1;
5292     while (p > arg && vim_iswhite(*p) && p[-1] != '\\')
5293 	*p-- = NUL;
5294 
5295 #ifdef FEAT_MULTI_LANG
5296     /* Check for a specified language */
5297     lang = check_help_lang(arg);
5298 #endif
5299 
5300     /* When no argument given go to the index. */
5301     if (*arg == NUL)
5302 	arg = (char_u *)"help.txt";
5303 
5304     /*
5305      * Check if there is a match for the argument.
5306      */
5307     n = find_help_tags(arg, &num_matches, &matches,
5308 						 eap != NULL && eap->forceit);
5309 
5310     i = 0;
5311 #ifdef FEAT_MULTI_LANG
5312     if (n != FAIL && lang != NULL)
5313 	/* Find first item with the requested language. */
5314 	for (i = 0; i < num_matches; ++i)
5315 	{
5316 	    len = STRLEN(matches[i]);
5317 	    if (len > 3 && matches[i][len - 3] == '@'
5318 				  && STRICMP(matches[i] + len - 2, lang) == 0)
5319 		break;
5320 	}
5321 #endif
5322     if (i >= num_matches || n == FAIL)
5323     {
5324 #ifdef FEAT_MULTI_LANG
5325 	if (lang != NULL)
5326 	    EMSG3(_("E661: Sorry, no '%s' help for %s"), lang, arg);
5327 	else
5328 #endif
5329 	    EMSG2(_("E149: Sorry, no help for %s"), arg);
5330 	if (n != FAIL)
5331 	    FreeWild(num_matches, matches);
5332 	return;
5333     }
5334 
5335     /* The first match (in the requested language) is the best match. */
5336     tag = vim_strsave(matches[i]);
5337     FreeWild(num_matches, matches);
5338 
5339 #ifdef FEAT_GUI
5340     need_mouse_correct = TRUE;
5341 #endif
5342 
5343     /*
5344      * Re-use an existing help window or open a new one.
5345      * Always open a new one for ":tab help".
5346      */
5347     if (!curwin->w_buffer->b_help
5348 #ifdef FEAT_WINDOWS
5349 	    || cmdmod.tab != 0
5350 #endif
5351 	    )
5352     {
5353 #ifdef FEAT_WINDOWS
5354 	if (cmdmod.tab != 0)
5355 	    wp = NULL;
5356 	else
5357 	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
5358 		if (wp->w_buffer != NULL && wp->w_buffer->b_help)
5359 		    break;
5360 	if (wp != NULL && wp->w_buffer->b_nwindows > 0)
5361 	    win_enter(wp, TRUE);
5362 	else
5363 #endif
5364 	{
5365 	    /*
5366 	     * There is no help window yet.
5367 	     * Try to open the file specified by the "helpfile" option.
5368 	     */
5369 	    if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL)
5370 	    {
5371 		smsg((char_u *)_("Sorry, help file \"%s\" not found"), p_hf);
5372 		goto erret;
5373 	    }
5374 	    fclose(helpfd);
5375 
5376 #ifdef FEAT_WINDOWS
5377 	    /* Split off help window; put it at far top if no position
5378 	     * specified, the current window is vertically split and
5379 	     * narrow. */
5380 	    n = WSP_HELP;
5381 # ifdef FEAT_VERTSPLIT
5382 	    if (cmdmod.split == 0 && curwin->w_width != Columns
5383 						  && curwin->w_width < 80)
5384 		n |= WSP_TOP;
5385 # endif
5386 	    if (win_split(0, n) == FAIL)
5387 		goto erret;
5388 #else
5389 	    /* use current window */
5390 	    if (!can_abandon(curbuf, FALSE))
5391 		goto erret;
5392 #endif
5393 
5394 #ifdef FEAT_WINDOWS
5395 	    if (curwin->w_height < p_hh)
5396 		win_setheight((int)p_hh);
5397 #endif
5398 
5399 	    /*
5400 	     * Open help file (do_ecmd() will set b_help flag, readfile() will
5401 	     * set b_p_ro flag).
5402 	     * Set the alternate file to the previously edited file.
5403 	     */
5404 	    alt_fnum = curbuf->b_fnum;
5405 	    (void)do_ecmd(0, NULL, NULL, NULL, ECMD_LASTL,
5406 						   ECMD_HIDE + ECMD_SET_HELP);
5407 	    if (!cmdmod.keepalt)
5408 		curwin->w_alt_fnum = alt_fnum;
5409 	    empty_fnum = curbuf->b_fnum;
5410 	}
5411     }
5412 
5413     if (!p_im)
5414 	restart_edit = 0;	    /* don't want insert mode in help file */
5415 
5416     if (tag != NULL)
5417 	do_tag(tag, DT_HELP, 1, FALSE, TRUE);
5418 
5419     /* Delete the empty buffer if we're not using it. */
5420     if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum)
5421     {
5422 	buf = buflist_findnr(empty_fnum);
5423 	if (buf != NULL)
5424 	    wipe_buffer(buf, TRUE);
5425     }
5426 
5427     /* keep the previous alternate file */
5428     if (alt_fnum != 0 && curwin->w_alt_fnum == empty_fnum && !cmdmod.keepalt)
5429 	curwin->w_alt_fnum = alt_fnum;
5430 
5431 erret:
5432     vim_free(tag);
5433 }
5434 
5435 
5436 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
5437 /*
5438  * In an argument search for a language specifiers in the form "@xx".
5439  * Changes the "@" to NUL if found, and returns a pointer to "xx".
5440  * Returns NULL if not found.
5441  */
5442     char_u *
5443 check_help_lang(arg)
5444     char_u *arg;
5445 {
5446     int len = STRLEN(arg);
5447 
5448     if (len >= 3 && arg[len - 3] == '@' && ASCII_ISALPHA(arg[len - 2])
5449 					       && ASCII_ISALPHA(arg[len - 1]))
5450     {
5451 	arg[len - 3] = NUL;		/* remove the '@' */
5452 	return arg + len - 2;
5453     }
5454     return NULL;
5455 }
5456 #endif
5457 
5458 /*
5459  * Return a heuristic indicating how well the given string matches.  The
5460  * smaller the number, the better the match.  This is the order of priorities,
5461  * from best match to worst match:
5462  *	- Match with least alpha-numeric characters is better.
5463  *	- Match with least total characters is better.
5464  *	- Match towards the start is better.
5465  *	- Match starting with "+" is worse (feature instead of command)
5466  * Assumption is made that the matched_string passed has already been found to
5467  * match some string for which help is requested.  webb.
5468  */
5469     int
5470 help_heuristic(matched_string, offset, wrong_case)
5471     char_u	*matched_string;
5472     int		offset;			/* offset for match */
5473     int		wrong_case;		/* no matching case */
5474 {
5475     int		num_letters;
5476     char_u	*p;
5477 
5478     num_letters = 0;
5479     for (p = matched_string; *p; p++)
5480 	if (ASCII_ISALNUM(*p))
5481 	    num_letters++;
5482 
5483     /*
5484      * Multiply the number of letters by 100 to give it a much bigger
5485      * weighting than the number of characters.
5486      * If there only is a match while ignoring case, add 5000.
5487      * If the match starts in the middle of a word, add 10000 to put it
5488      * somewhere in the last half.
5489      * If the match is more than 2 chars from the start, multiply by 200 to
5490      * put it after matches at the start.
5491      */
5492     if (ASCII_ISALNUM(matched_string[offset]) && offset > 0
5493 				 && ASCII_ISALNUM(matched_string[offset - 1]))
5494 	offset += 10000;
5495     else if (offset > 2)
5496 	offset *= 200;
5497     if (wrong_case)
5498 	offset += 5000;
5499     /* Features are less interesting than the subjects themselves, but "+"
5500      * alone is not a feature. */
5501     if (matched_string[0] == '+' && matched_string[1] != NUL)
5502 	offset += 100;
5503     return (int)(100 * num_letters + STRLEN(matched_string) + offset);
5504 }
5505 
5506 /*
5507  * Compare functions for qsort() below, that checks the help heuristics number
5508  * that has been put after the tagname by find_tags().
5509  */
5510     static int
5511 #ifdef __BORLANDC__
5512 _RTLENTRYF
5513 #endif
5514 help_compare(s1, s2)
5515     const void	*s1;
5516     const void	*s2;
5517 {
5518     char    *p1;
5519     char    *p2;
5520 
5521     p1 = *(char **)s1 + strlen(*(char **)s1) + 1;
5522     p2 = *(char **)s2 + strlen(*(char **)s2) + 1;
5523     return strcmp(p1, p2);
5524 }
5525 
5526 /*
5527  * Find all help tags matching "arg", sort them and return in matches[], with
5528  * the number of matches in num_matches.
5529  * The matches will be sorted with a "best" match algorithm.
5530  * When "keep_lang" is TRUE try keeping the language of the current buffer.
5531  */
5532     int
5533 find_help_tags(arg, num_matches, matches, keep_lang)
5534     char_u	*arg;
5535     int		*num_matches;
5536     char_u	***matches;
5537     int		keep_lang;
5538 {
5539     char_u	*s, *d;
5540     int		i;
5541     static char *(mtable[]) = {"*", "g*", "[*", "]*", ":*",
5542 			       "/*", "/\\*", "\"*", "**",
5543 			       "/\\(\\)",
5544 			       "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
5545 			       "/\\?", "/\\z(\\)", "\\=", ":s\\=",
5546 			       "[count]", "[quotex]", "[range]",
5547 			       "[pattern]", "\\|", "\\%$"};
5548     static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star",
5549 			       "/star", "/\\\\star", "quotestar", "starstar",
5550 			       "/\\\\(\\\\)",
5551 			       "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
5552 			       "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
5553 			       "\\[count]", "\\[quotex]", "\\[range]",
5554 			       "\\[pattern]", "\\\\bar", "/\\\\%\\$"};
5555     int flags;
5556 
5557     d = IObuff;		    /* assume IObuff is long enough! */
5558 
5559     /*
5560      * Recognize a few exceptions to the rule.	Some strings that contain '*'
5561      * with "star".  Otherwise '*' is recognized as a wildcard.
5562      */
5563     for (i = sizeof(mtable) / sizeof(char *); --i >= 0; )
5564 	if (STRCMP(arg, mtable[i]) == 0)
5565 	{
5566 	    STRCPY(d, rtable[i]);
5567 	    break;
5568 	}
5569 
5570     if (i < 0)	/* no match in table */
5571     {
5572 	/* Replace "\S" with "/\\S", etc.  Otherwise every tag is matched.
5573 	 * Also replace "\%^" and "\%(", they match every tag too.
5574 	 * Also "\zs", "\z1", etc.
5575 	 * Also "\@<", "\@=", "\@<=", etc.
5576 	 * And also "\_$" and "\_^". */
5577 	if (arg[0] == '\\'
5578 		&& ((arg[1] != NUL && arg[2] == NUL)
5579 		    || (vim_strchr((char_u *)"%_z@", arg[1]) != NULL
5580 							   && arg[2] != NUL)))
5581 	{
5582 	    STRCPY(d, "/\\\\");
5583 	    STRCPY(d + 3, arg + 1);
5584 	    /* Check for "/\\_$", should be "/\\_\$" */
5585 	    if (d[3] == '_' && d[4] == '$')
5586 		STRCPY(d + 4, "\\$");
5587 	}
5588 	else
5589 	{
5590 	  /* replace "[:...:]" with "\[:...:]"; "[+...]" with "\[++...]" */
5591 	    if (arg[0] == '[' && (arg[1] == ':'
5592 					 || (arg[1] == '+' && arg[2] == '+')))
5593 	      *d++ = '\\';
5594 
5595 	  for (s = arg; *s; ++s)
5596 	  {
5597 	    /*
5598 	     * Replace "|" with "bar" and '"' with "quote" to match the name of
5599 	     * the tags for these commands.
5600 	     * Replace "*" with ".*" and "?" with "." to match command line
5601 	     * completion.
5602 	     * Insert a backslash before '~', '$' and '.' to avoid their
5603 	     * special meaning.
5604 	     */
5605 	    if (d - IObuff > IOSIZE - 10)	/* getting too long!? */
5606 		break;
5607 	    switch (*s)
5608 	    {
5609 		case '|':   STRCPY(d, "bar");
5610 			    d += 3;
5611 			    continue;
5612 		case '"':   STRCPY(d, "quote");
5613 			    d += 5;
5614 			    continue;
5615 		case '*':   *d++ = '.';
5616 			    break;
5617 		case '?':   *d++ = '.';
5618 			    continue;
5619 		case '$':
5620 		case '.':
5621 		case '~':   *d++ = '\\';
5622 			    break;
5623 	    }
5624 
5625 	    /*
5626 	     * Replace "^x" by "CTRL-X". Don't do this for "^_" to make
5627 	     * ":help i_^_CTRL-D" work.
5628 	     * Insert '-' before and after "CTRL-X" when applicable.
5629 	     */
5630 	    if (*s < ' ' || (*s == '^' && s[1] && (ASCII_ISALPHA(s[1])
5631 			   || vim_strchr((char_u *)"?@[\\]^", s[1]) != NULL)))
5632 	    {
5633 		if (d > IObuff && d[-1] != '_')
5634 		    *d++ = '_';		/* prepend a '_' */
5635 		STRCPY(d, "CTRL-");
5636 		d += 5;
5637 		if (*s < ' ')
5638 		{
5639 #ifdef EBCDIC
5640 		    *d++ = CtrlChar(*s);
5641 #else
5642 		    *d++ = *s + '@';
5643 #endif
5644 		    if (d[-1] == '\\')
5645 			*d++ = '\\';	/* double a backslash */
5646 		}
5647 		else
5648 		    *d++ = *++s;
5649 		if (s[1] != NUL && s[1] != '_')
5650 		    *d++ = '_';		/* append a '_' */
5651 		continue;
5652 	    }
5653 	    else if (*s == '^')		/* "^" or "CTRL-^" or "^_" */
5654 		*d++ = '\\';
5655 
5656 	    /*
5657 	     * Insert a backslash before a backslash after a slash, for search
5658 	     * pattern tags: "/\|" --> "/\\|".
5659 	     */
5660 	    else if (s[0] == '\\' && s[1] != '\\'
5661 					       && *arg == '/' && s == arg + 1)
5662 		*d++ = '\\';
5663 
5664 	    /* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
5665 	     * "CTRL-\_CTRL-N" */
5666 	    if (STRNICMP(s, "CTRL-\\_", 7) == 0)
5667 	    {
5668 		STRCPY(d, "CTRL-\\\\");
5669 		d += 7;
5670 		s += 6;
5671 	    }
5672 
5673 	    *d++ = *s;
5674 
5675 	    /*
5676 	     * If tag starts with ', toss everything after a second '. Fixes
5677 	     * CTRL-] on 'option'. (would include the trailing '.').
5678 	     */
5679 	    if (*s == '\'' && s > arg && *arg == '\'')
5680 		break;
5681 	  }
5682 	  *d = NUL;
5683 	}
5684     }
5685 
5686     *matches = (char_u **)"";
5687     *num_matches = 0;
5688     flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE;
5689     if (keep_lang)
5690 	flags |= TAG_KEEP_LANG;
5691     if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == OK
5692 	    && *num_matches > 0)
5693 	/* Sort the matches found on the heuristic number that is after the
5694 	 * tag name. */
5695 	qsort((void *)*matches, (size_t)*num_matches,
5696 					      sizeof(char_u *), help_compare);
5697     return OK;
5698 }
5699 
5700 /*
5701  * After reading a help file: May cleanup a help buffer when syntax
5702  * highlighting is not used.
5703  */
5704     void
5705 fix_help_buffer()
5706 {
5707     linenr_T	lnum;
5708     char_u	*line;
5709     int		in_example = FALSE;
5710     int		len;
5711     char_u	*p;
5712     char_u	*rt;
5713     int		mustfree;
5714 
5715     /* set filetype to "help". */
5716     set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL);
5717 
5718 #ifdef FEAT_SYN_HL
5719     if (!syntax_present(curbuf))
5720 #endif
5721     {
5722 	for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
5723 	{
5724 	    line = ml_get_buf(curbuf, lnum, FALSE);
5725 	    len = (int)STRLEN(line);
5726 	    if (in_example && len > 0 && !vim_iswhite(line[0]))
5727 	    {
5728 		/* End of example: non-white or '<' in first column. */
5729 		if (line[0] == '<')
5730 		{
5731 		    /* blank-out a '<' in the first column */
5732 		    line = ml_get_buf(curbuf, lnum, TRUE);
5733 		    line[0] = ' ';
5734 		}
5735 		in_example = FALSE;
5736 	    }
5737 	    if (!in_example && len > 0)
5738 	    {
5739 		if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' '))
5740 		{
5741 		    /* blank-out a '>' in the last column (start of example) */
5742 		    line = ml_get_buf(curbuf, lnum, TRUE);
5743 		    line[len - 1] = ' ';
5744 		    in_example = TRUE;
5745 		}
5746 		else if (line[len - 1] == '~')
5747 		{
5748 		    /* blank-out a '~' at the end of line (header marker) */
5749 		    line = ml_get_buf(curbuf, lnum, TRUE);
5750 		    line[len - 1] = ' ';
5751 		}
5752 	    }
5753 	}
5754     }
5755 
5756     /*
5757      * In the "help.txt" file, add the locally added help files.
5758      * This uses the very first line in the help file.
5759      */
5760     if (fnamecmp(gettail(curbuf->b_fname), "help.txt") == 0)
5761     {
5762 	for (lnum = 1; lnum < curbuf->b_ml.ml_line_count; ++lnum)
5763 	{
5764 	    line = ml_get_buf(curbuf, lnum, FALSE);
5765 	    if (strstr((char *)line, "*local-additions*") != NULL)
5766 	    {
5767 		/* Go through all directories in 'runtimepath', skipping
5768 		 * $VIMRUNTIME. */
5769 		p = p_rtp;
5770 		while (*p != NUL)
5771 		{
5772 		    copy_option_part(&p, NameBuff, MAXPATHL, ",");
5773 		    mustfree = FALSE;
5774 		    rt = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
5775 		    if (fullpathcmp(rt, NameBuff, FALSE) != FPC_SAME)
5776 		    {
5777 			int	fcount;
5778 			char_u	**fnames;
5779 			FILE	*fd;
5780 			char_u	*s;
5781 			int	fi;
5782 #ifdef FEAT_MBYTE
5783 			vimconv_T	vc;
5784 			char_u		*cp;
5785 #endif
5786 
5787 			/* Find all "doc/ *.txt" files in this directory. */
5788 			add_pathsep(NameBuff);
5789 			STRCAT(NameBuff, "doc/*.txt");
5790 			if (gen_expand_wildcards(1, &NameBuff, &fcount,
5791 					     &fnames, EW_FILE|EW_SILENT) == OK
5792 				&& fcount > 0)
5793 			{
5794 			    for (fi = 0; fi < fcount; ++fi)
5795 			    {
5796 				fd = mch_fopen((char *)fnames[fi], "r");
5797 				if (fd != NULL)
5798 				{
5799 				    vim_fgets(IObuff, IOSIZE, fd);
5800 				    if (IObuff[0] == '*'
5801 					    && (s = vim_strchr(IObuff + 1, '*'))
5802 								      != NULL)
5803 				    {
5804 #ifdef FEAT_MBYTE
5805 					int	this_utf = MAYBE;
5806 #endif
5807 					/* Change tag definition to a
5808 					 * reference and remove <CR>/<NL>. */
5809 					IObuff[0] = '|';
5810 					*s = '|';
5811 					while (*s != NUL)
5812 					{
5813 					    if (*s == '\r' || *s == '\n')
5814 						*s = NUL;
5815 #ifdef FEAT_MBYTE
5816 					    /* The text is utf-8 when a byte
5817 					     * above 127 is found and no
5818 					     * illegal byte sequence is found.
5819 					     */
5820 					    if (*s >= 0x80 && this_utf != FALSE)
5821 					    {
5822 						int	l;
5823 
5824 						this_utf = TRUE;
5825 						l = utf_ptr2len(s);
5826 						if (l == 1)
5827 						    this_utf = FALSE;
5828 						s += l - 1;
5829 					    }
5830 #endif
5831 					    ++s;
5832 					}
5833 #ifdef FEAT_MBYTE
5834 					/* The help file is latin1 or utf-8;
5835 					 * conversion to the current
5836 					 * 'encoding' may be required. */
5837 					vc.vc_type = CONV_NONE;
5838 					convert_setup(&vc, (char_u *)(
5839 						    this_utf == TRUE ? "utf-8"
5840 							  : "latin1"), p_enc);
5841 					if (vc.vc_type == CONV_NONE)
5842 					    /* No conversion needed. */
5843 					    cp = IObuff;
5844 					else
5845 					{
5846 					    /* Do the conversion.  If it fails
5847 					     * use the unconverted text. */
5848 					    cp = string_convert(&vc, IObuff,
5849 									NULL);
5850 					    if (cp == NULL)
5851 						cp = IObuff;
5852 					}
5853 					convert_setup(&vc, NULL, NULL);
5854 
5855 					ml_append(lnum, cp, (colnr_T)0, FALSE);
5856 					if (cp != IObuff)
5857 					    vim_free(cp);
5858 #else
5859 					ml_append(lnum, IObuff, (colnr_T)0,
5860 								       FALSE);
5861 #endif
5862 					++lnum;
5863 				    }
5864 				    fclose(fd);
5865 				}
5866 			    }
5867 			    FreeWild(fcount, fnames);
5868 			}
5869 		    }
5870 		    if (mustfree)
5871 			vim_free(rt);
5872 		}
5873 		break;
5874 	    }
5875 	}
5876     }
5877 }
5878 
5879 /*
5880  * ":exusage"
5881  */
5882 /*ARGSUSED*/
5883     void
5884 ex_exusage(eap)
5885     exarg_T	*eap;
5886 {
5887     do_cmdline_cmd((char_u *)"help ex-cmd-index");
5888 }
5889 
5890 /*
5891  * ":viusage"
5892  */
5893 /*ARGSUSED*/
5894     void
5895 ex_viusage(eap)
5896     exarg_T	*eap;
5897 {
5898     do_cmdline_cmd((char_u *)"help normal-index");
5899 }
5900 
5901 #if defined(FEAT_EX_EXTRA) || defined(PROTO)
5902 static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang));
5903 
5904 /*
5905  * ":helptags"
5906  */
5907     void
5908 ex_helptags(eap)
5909     exarg_T	*eap;
5910 {
5911     garray_T	ga;
5912     int		i, j;
5913     int		len;
5914 #ifdef FEAT_MULTI_LANG
5915     char_u	lang[2];
5916 #endif
5917     char_u	ext[5];
5918     char_u	fname[8];
5919     int		filecount;
5920     char_u	**files;
5921 
5922     if (!mch_isdir(eap->arg))
5923     {
5924 	EMSG2(_("E150: Not a directory: %s"), eap->arg);
5925 	return;
5926     }
5927 
5928 #ifdef FEAT_MULTI_LANG
5929     /* Get a list of all files in the directory. */
5930     STRCPY(NameBuff, eap->arg);
5931     add_pathsep(NameBuff);
5932     STRCAT(NameBuff, "*");
5933     if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
5934 						    EW_FILE|EW_SILENT) == FAIL
5935 	    || filecount == 0)
5936     {
5937 	EMSG2("E151: No match: %s", NameBuff);
5938 	return;
5939     }
5940 
5941     /* Go over all files in the directory to find out what languages are
5942      * present. */
5943     ga_init2(&ga, 1, 10);
5944     for (i = 0; i < filecount; ++i)
5945     {
5946 	len = STRLEN(files[i]);
5947 	if (len > 4)
5948 	{
5949 	    if (STRICMP(files[i] + len - 4, ".txt") == 0)
5950 	    {
5951 		/* ".txt" -> language "en" */
5952 		lang[0] = 'e';
5953 		lang[1] = 'n';
5954 	    }
5955 	    else if (files[i][len - 4] == '.'
5956 		    && ASCII_ISALPHA(files[i][len - 3])
5957 		    && ASCII_ISALPHA(files[i][len - 2])
5958 		    && TOLOWER_ASC(files[i][len - 1]) == 'x')
5959 	    {
5960 		/* ".abx" -> language "ab" */
5961 		lang[0] = TOLOWER_ASC(files[i][len - 3]);
5962 		lang[1] = TOLOWER_ASC(files[i][len - 2]);
5963 	    }
5964 	    else
5965 		continue;
5966 
5967 	    /* Did we find this language already? */
5968 	    for (j = 0; j < ga.ga_len; j += 2)
5969 		if (STRNCMP(lang, ((char_u *)ga.ga_data) + j, 2) == 0)
5970 		    break;
5971 	    if (j == ga.ga_len)
5972 	    {
5973 		/* New language, add it. */
5974 		if (ga_grow(&ga, 2) == FAIL)
5975 		    break;
5976 		((char_u *)ga.ga_data)[ga.ga_len++] = lang[0];
5977 		((char_u *)ga.ga_data)[ga.ga_len++] = lang[1];
5978 	    }
5979 	}
5980     }
5981 
5982     /*
5983      * Loop over the found languages to generate a tags file for each one.
5984      */
5985     for (j = 0; j < ga.ga_len; j += 2)
5986     {
5987 	STRCPY(fname, "tags-xx");
5988 	fname[5] = ((char_u *)ga.ga_data)[j];
5989 	fname[6] = ((char_u *)ga.ga_data)[j + 1];
5990 	if (fname[5] == 'e' && fname[6] == 'n')
5991 	{
5992 	    /* English is an exception: use ".txt" and "tags". */
5993 	    fname[4] = NUL;
5994 	    STRCPY(ext, ".txt");
5995 	}
5996 	else
5997 	{
5998 	    /* Language "ab" uses ".abx" and "tags-ab". */
5999 	    STRCPY(ext, ".xxx");
6000 	    ext[1] = fname[5];
6001 	    ext[2] = fname[6];
6002 	}
6003 	helptags_one(eap->arg, ext, fname);
6004     }
6005 
6006     ga_clear(&ga);
6007     FreeWild(filecount, files);
6008 
6009 #else
6010     /* No language support, just use "*.txt" and "tags". */
6011     helptags_one(eap->arg, (char_u *)".txt", (char_u *)"tags");
6012 #endif
6013 }
6014 
6015     static void
6016 helptags_one(dir, ext, tagfname)
6017     char_u	*dir;	    /* doc directory */
6018     char_u	*ext;	    /* suffix, ".txt", ".itx", ".frx", etc. */
6019     char_u	*tagfname;    /* "tags" for English, "tags-it" for Italian. */
6020 {
6021     FILE	*fd_tags;
6022     FILE	*fd;
6023     garray_T	ga;
6024     int		filecount;
6025     char_u	**files;
6026     char_u	*p1, *p2;
6027     int		fi;
6028     char_u	*s;
6029     int		i;
6030     char_u	*fname;
6031 # ifdef FEAT_MBYTE
6032     int		utf8 = MAYBE;
6033     int		this_utf8;
6034     int		firstline;
6035     int		mix = FALSE;	/* detected mixed encodings */
6036 # endif
6037 
6038     /*
6039      * Find all *.txt files.
6040      */
6041     STRCPY(NameBuff, dir);
6042     add_pathsep(NameBuff);
6043     STRCAT(NameBuff, "*");
6044     STRCAT(NameBuff, ext);
6045     if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
6046 						    EW_FILE|EW_SILENT) == FAIL
6047 	    || filecount == 0)
6048     {
6049 	if (!got_int)
6050 	    EMSG2("E151: No match: %s", NameBuff);
6051 	return;
6052     }
6053 
6054     /*
6055      * Open the tags file for writing.
6056      * Do this before scanning through all the files.
6057      */
6058     STRCPY(NameBuff, dir);
6059     add_pathsep(NameBuff);
6060     STRCAT(NameBuff, tagfname);
6061     fd_tags = mch_fopen((char *)NameBuff, "w");
6062     if (fd_tags == NULL)
6063     {
6064 	EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
6065 	FreeWild(filecount, files);
6066 	return;
6067     }
6068 
6069     /*
6070      * If generating tags for "$VIMRUNTIME/doc" add the "help-tags" tag.
6071      */
6072     ga_init2(&ga, (int)sizeof(char_u *), 100);
6073     if (fullpathcmp((char_u *)"$VIMRUNTIME/doc", dir, FALSE) == FPC_SAME)
6074     {
6075 	if (ga_grow(&ga, 1) == FAIL)
6076 	    got_int = TRUE;
6077 	else
6078 	{
6079 	    s = alloc(18 + STRLEN(tagfname));
6080 	    if (s == NULL)
6081 		got_int = TRUE;
6082 	    else
6083 	    {
6084 		sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
6085 		((char_u **)ga.ga_data)[ga.ga_len] = s;
6086 		++ga.ga_len;
6087 	    }
6088 	}
6089     }
6090 
6091     /*
6092      * Go over all the files and extract the tags.
6093      */
6094     for (fi = 0; fi < filecount && !got_int; ++fi)
6095     {
6096 	fd = mch_fopen((char *)files[fi], "r");
6097 	if (fd == NULL)
6098 	{
6099 	    EMSG2(_("E153: Unable to open %s for reading"), files[fi]);
6100 	    continue;
6101 	}
6102 	fname = gettail(files[fi]);
6103 
6104 # ifdef FEAT_MBYTE
6105 	firstline = TRUE;
6106 # endif
6107 	while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int)
6108 	{
6109 # ifdef FEAT_MBYTE
6110 	    if (firstline)
6111 	    {
6112 		/* Detect utf-8 file by a non-ASCII char in the first line. */
6113 		this_utf8 = MAYBE;
6114 		for (s = IObuff; *s != NUL; ++s)
6115 		    if (*s >= 0x80)
6116 		    {
6117 			int l;
6118 
6119 			this_utf8 = TRUE;
6120 			l = utf_ptr2len(s);
6121 			if (l == 1)
6122 			{
6123 			    /* Illegal UTF-8 byte sequence. */
6124 			    this_utf8 = FALSE;
6125 			    break;
6126 			}
6127 			s += l - 1;
6128 		    }
6129 		if (this_utf8 == MAYBE)	    /* only ASCII characters found */
6130 		    this_utf8 = FALSE;
6131 		if (utf8 == MAYBE)	    /* first file */
6132 		    utf8 = this_utf8;
6133 		else if (utf8 != this_utf8)
6134 		{
6135 		    EMSG2(_("E670: Mix of help file encodings within a language: %s"), files[fi]);
6136 		    mix = !got_int;
6137 		    got_int = TRUE;
6138 		}
6139 		firstline = FALSE;
6140 	    }
6141 # endif
6142 	    p1 = vim_strchr(IObuff, '*');	/* find first '*' */
6143 	    while (p1 != NULL)
6144 	    {
6145 		p2 = vim_strchr(p1 + 1, '*');	/* find second '*' */
6146 		if (p2 != NULL && p2 > p1 + 1)	/* skip "*" and "**" */
6147 		{
6148 		    for (s = p1 + 1; s < p2; ++s)
6149 			if (*s == ' ' || *s == '\t' || *s == '|')
6150 			    break;
6151 
6152 		    /*
6153 		     * Only accept a *tag* when it consists of valid
6154 		     * characters, there is white space before it and is
6155 		     * followed by a white character or end-of-line.
6156 		     */
6157 		    if (s == p2
6158 			    && (p1 == IObuff || p1[-1] == ' ' || p1[-1] == '\t')
6159 			    && (vim_strchr((char_u *)" \t\n\r", s[1]) != NULL
6160 				|| s[1] == '\0'))
6161 		    {
6162 			*p2 = '\0';
6163 			++p1;
6164 			if (ga_grow(&ga, 1) == FAIL)
6165 			{
6166 			    got_int = TRUE;
6167 			    break;
6168 			}
6169 			s = alloc((unsigned)(p2 - p1 + STRLEN(fname) + 2));
6170 			if (s == NULL)
6171 			{
6172 			    got_int = TRUE;
6173 			    break;
6174 			}
6175 			((char_u **)ga.ga_data)[ga.ga_len] = s;
6176 			++ga.ga_len;
6177 			sprintf((char *)s, "%s\t%s", p1, fname);
6178 
6179 			/* find next '*' */
6180 			p2 = vim_strchr(p2 + 1, '*');
6181 		    }
6182 		}
6183 		p1 = p2;
6184 	    }
6185 	    line_breakcheck();
6186 	}
6187 
6188 	fclose(fd);
6189     }
6190 
6191     FreeWild(filecount, files);
6192 
6193     if (!got_int)
6194     {
6195 	/*
6196 	 * Sort the tags.
6197 	 */
6198 	sort_strings((char_u **)ga.ga_data, ga.ga_len);
6199 
6200 	/*
6201 	 * Check for duplicates.
6202 	 */
6203 	for (i = 1; i < ga.ga_len; ++i)
6204 	{
6205 	    p1 = ((char_u **)ga.ga_data)[i - 1];
6206 	    p2 = ((char_u **)ga.ga_data)[i];
6207 	    while (*p1 == *p2)
6208 	    {
6209 		if (*p2 == '\t')
6210 		{
6211 		    *p2 = NUL;
6212 		    vim_snprintf((char *)NameBuff, MAXPATHL,
6213 			    _("E154: Duplicate tag \"%s\" in file %s/%s"),
6214 				     ((char_u **)ga.ga_data)[i], dir, p2 + 1);
6215 		    EMSG(NameBuff);
6216 		    *p2 = '\t';
6217 		    break;
6218 		}
6219 		++p1;
6220 		++p2;
6221 	    }
6222 	}
6223 
6224 # ifdef FEAT_MBYTE
6225 	if (utf8 == TRUE)
6226 	    fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n");
6227 # endif
6228 
6229 	/*
6230 	 * Write the tags into the file.
6231 	 */
6232 	for (i = 0; i < ga.ga_len; ++i)
6233 	{
6234 	    s = ((char_u **)ga.ga_data)[i];
6235 	    if (STRNCMP(s, "help-tags", 9) == 0)
6236 		/* help-tags entry was added in formatted form */
6237 		fprintf(fd_tags, (char *)s);
6238 	    else
6239 	    {
6240 		fprintf(fd_tags, "%s\t/*", s);
6241 		for (p1 = s; *p1 != '\t'; ++p1)
6242 		{
6243 		    /* insert backslash before '\\' and '/' */
6244 		    if (*p1 == '\\' || *p1 == '/')
6245 			putc('\\', fd_tags);
6246 		    putc(*p1, fd_tags);
6247 		}
6248 		fprintf(fd_tags, "*\n");
6249 	    }
6250 	}
6251     }
6252 #ifdef FEAT_MBYTE
6253     if (mix)
6254 	got_int = FALSE;    /* continue with other languages */
6255 #endif
6256 
6257     for (i = 0; i < ga.ga_len; ++i)
6258 	vim_free(((char_u **)ga.ga_data)[i]);
6259     ga_clear(&ga);
6260     fclose(fd_tags);	    /* there is no check for an error... */
6261 }
6262 #endif
6263 
6264 #if defined(FEAT_SIGNS) || defined(PROTO)
6265 
6266 /*
6267  * Struct to hold the sign properties.
6268  */
6269 typedef struct sign sign_T;
6270 
6271 struct sign
6272 {
6273     sign_T	*sn_next;	/* next sign in list */
6274     int		sn_typenr;	/* type number of sign (negative if not equal
6275 				   to name) */
6276     char_u	*sn_name;	/* name of sign */
6277     char_u	*sn_icon;	/* name of pixmap */
6278 #ifdef FEAT_SIGN_ICONS
6279     void	*sn_image;	/* icon image */
6280 #endif
6281     char_u	*sn_text;	/* text used instead of pixmap */
6282     int		sn_line_hl;	/* highlight ID for line */
6283     int		sn_text_hl;	/* highlight ID for text */
6284 };
6285 
6286 static sign_T	*first_sign = NULL;
6287 static int	last_sign_typenr = MAX_TYPENR;	/* is decremented */
6288 
6289 static void sign_list_defined __ARGS((sign_T *sp));
6290 
6291 /*
6292  * ":sign" command
6293  */
6294     void
6295 ex_sign(eap)
6296     exarg_T	*eap;
6297 {
6298     char_u	*arg = eap->arg;
6299     char_u	*p;
6300     int		idx;
6301     sign_T	*sp;
6302     sign_T	*sp_prev;
6303     buf_T	*buf;
6304     static char	*cmds[] = {
6305 			"define",
6306 #define SIGNCMD_DEFINE	0
6307 			"undefine",
6308 #define SIGNCMD_UNDEFINE 1
6309 			"list",
6310 #define SIGNCMD_LIST	2
6311 			"place",
6312 #define SIGNCMD_PLACE	3
6313 			"unplace",
6314 #define SIGNCMD_UNPLACE	4
6315 			"jump",
6316 #define SIGNCMD_JUMP	5
6317 #define SIGNCMD_LAST	6
6318     };
6319 
6320     /* Parse the subcommand. */
6321     p = skiptowhite(arg);
6322     if (*p != NUL)
6323 	*p++ = NUL;
6324     for (idx = 0; ; ++idx)
6325     {
6326 	if (idx == SIGNCMD_LAST)
6327 	{
6328 	    EMSG2(_("E160: Unknown sign command: %s"), arg);
6329 	    return;
6330 	}
6331 	if (STRCMP(arg, cmds[idx]) == 0)
6332 	    break;
6333     }
6334     arg = skipwhite(p);
6335 
6336     if (idx <= SIGNCMD_LIST)
6337     {
6338 	/*
6339 	 * Define, undefine or list signs.
6340 	 */
6341 	if (idx == SIGNCMD_LIST && *arg == NUL)
6342 	{
6343 	    /* ":sign list": list all defined signs */
6344 	    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6345 		sign_list_defined(sp);
6346 	}
6347 	else if (*arg == NUL)
6348 	    EMSG(_("E156: Missing sign name"));
6349 	else
6350 	{
6351 	    p = skiptowhite(arg);
6352 	    if (*p != NUL)
6353 		*p++ = NUL;
6354 	    sp_prev = NULL;
6355 	    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6356 	    {
6357 		if (STRCMP(sp->sn_name, arg) == 0)
6358 		    break;
6359 		sp_prev = sp;
6360 	    }
6361 	    if (idx == SIGNCMD_DEFINE)
6362 	    {
6363 		/* ":sign define {name} ...": define a sign */
6364 		if (sp == NULL)
6365 		{
6366 		    /* Allocate a new sign. */
6367 		    sp = (sign_T *)alloc_clear((unsigned)sizeof(sign_T));
6368 		    if (sp == NULL)
6369 			return;
6370 		    if (sp_prev == NULL)
6371 			first_sign = sp;
6372 		    else
6373 			sp_prev->sn_next = sp;
6374 		    sp->sn_name = vim_strnsave(arg, (int)(p - arg));
6375 
6376 		    /* If the name is a number use that for the typenr,
6377 		     * otherwise use a negative number. */
6378 		    if (VIM_ISDIGIT(*arg))
6379 			sp->sn_typenr = atoi((char *)arg);
6380 		    else
6381 		    {
6382 			sign_T	*lp;
6383 			int	start = last_sign_typenr;
6384 
6385 			for (lp = first_sign; lp != NULL; lp = lp->sn_next)
6386 			{
6387 			    if (lp->sn_typenr == last_sign_typenr)
6388 			    {
6389 				--last_sign_typenr;
6390 				if (last_sign_typenr == 0)
6391 				    last_sign_typenr = MAX_TYPENR;
6392 				if (last_sign_typenr == start)
6393 				{
6394 				    EMSG(_("E612: Too many signs defined"));
6395 				    return;
6396 				}
6397 				lp = first_sign;
6398 				continue;
6399 			    }
6400 			}
6401 
6402 			sp->sn_typenr = last_sign_typenr--;
6403 			if (last_sign_typenr == 0)
6404 			    last_sign_typenr = MAX_TYPENR; /* wrap around */
6405 		    }
6406 		}
6407 
6408 		/* set values for a defined sign. */
6409 		for (;;)
6410 		{
6411 		    arg = skipwhite(p);
6412 		    if (*arg == NUL)
6413 			break;
6414 		    p = skiptowhite_esc(arg);
6415 		    if (STRNCMP(arg, "icon=", 5) == 0)
6416 		    {
6417 			arg += 5;
6418 			vim_free(sp->sn_icon);
6419 			sp->sn_icon = vim_strnsave(arg, (int)(p - arg));
6420 			backslash_halve(sp->sn_icon);
6421 #ifdef FEAT_SIGN_ICONS
6422 			if (gui.in_use)
6423 			{
6424 			    out_flush();
6425 			    if (sp->sn_image != NULL)
6426 				gui_mch_destroy_sign(sp->sn_image);
6427 			    sp->sn_image = gui_mch_register_sign(sp->sn_icon);
6428 			}
6429 #endif
6430 		    }
6431 		    else if (STRNCMP(arg, "text=", 5) == 0)
6432 		    {
6433 			char_u	*s;
6434 			int	cells;
6435 			int	len;
6436 
6437 			arg += 5;
6438 #ifdef FEAT_MBYTE
6439 			/* Count cells and check for non-printable chars */
6440 			if (has_mbyte)
6441 			{
6442 			    cells = 0;
6443 			    for (s = arg; s < p; s += (*mb_ptr2len)(s))
6444 			    {
6445 				if (!vim_isprintc((*mb_ptr2char)(s)))
6446 				    break;
6447 				cells += (*mb_ptr2cells)(s);
6448 			    }
6449 			}
6450 			else
6451 #endif
6452 			{
6453 			    for (s = arg; s < p; ++s)
6454 				if (!vim_isprintc(*s))
6455 				    break;
6456 			    cells = s - arg;
6457 			}
6458 			/* Currently must be one or two display cells */
6459 			if (s != p || cells < 1 || cells > 2)
6460 			{
6461 			    *p = NUL;
6462 			    EMSG2(_("E239: Invalid sign text: %s"), arg);
6463 			    return;
6464 			}
6465 
6466 			vim_free(sp->sn_text);
6467 			/* Allocate one byte more if we need to pad up
6468 			 * with a space. */
6469 			len = p - arg + ((cells == 1) ? 1 : 0);
6470 			sp->sn_text = vim_strnsave(arg, len);
6471 
6472 			if (sp->sn_text != NULL && cells == 1)
6473 			    STRCPY(sp->sn_text + len - 1, " ");
6474 		    }
6475 		    else if (STRNCMP(arg, "linehl=", 7) == 0)
6476 		    {
6477 			arg += 7;
6478 			sp->sn_line_hl = syn_check_group(arg, (int)(p - arg));
6479 		    }
6480 		    else if (STRNCMP(arg, "texthl=", 7) == 0)
6481 		    {
6482 			arg += 7;
6483 			sp->sn_text_hl = syn_check_group(arg, (int)(p - arg));
6484 		    }
6485 		    else
6486 		    {
6487 			EMSG2(_(e_invarg2), arg);
6488 			return;
6489 		    }
6490 		}
6491 	    }
6492 	    else if (sp == NULL)
6493 		EMSG2(_("E155: Unknown sign: %s"), arg);
6494 	    else if (idx == SIGNCMD_LIST)
6495 		/* ":sign list {name}" */
6496 		sign_list_defined(sp);
6497 	    else
6498 	    {
6499 		/* ":sign undefine {name}" */
6500 		vim_free(sp->sn_name);
6501 		vim_free(sp->sn_icon);
6502 #ifdef FEAT_SIGN_ICONS
6503 		if (sp->sn_image != NULL)
6504 		{
6505 		    out_flush();
6506 		    gui_mch_destroy_sign(sp->sn_image);
6507 		}
6508 #endif
6509 		vim_free(sp->sn_text);
6510 		if (sp_prev == NULL)
6511 		    first_sign = sp->sn_next;
6512 		else
6513 		    sp_prev->sn_next = sp->sn_next;
6514 		vim_free(sp);
6515 	    }
6516 	}
6517     }
6518     else
6519     {
6520 	int		id = -1;
6521 	linenr_T	lnum = -1;
6522 	char_u		*sign_name = NULL;
6523 	char_u		*arg1;
6524 
6525 	if (*arg == NUL)
6526 	{
6527 	    if (idx == SIGNCMD_PLACE)
6528 	    {
6529 		/* ":sign place": list placed signs in all buffers */
6530 		sign_list_placed(NULL);
6531 	    }
6532 	    else if (idx == SIGNCMD_UNPLACE)
6533 	    {
6534 		/* ":sign unplace": remove placed sign at cursor */
6535 		id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum);
6536 		if (id > 0)
6537 		{
6538 		    buf_delsign(curwin->w_buffer, id);
6539 		    update_debug_sign(curwin->w_buffer, curwin->w_cursor.lnum);
6540 		}
6541 		else
6542 		    EMSG(_("E159: Missing sign number"));
6543 	    }
6544 	    else
6545 		EMSG(_(e_argreq));
6546 	    return;
6547 	}
6548 
6549 	if (idx == SIGNCMD_UNPLACE && arg[0] == '*' && arg[1] == NUL)
6550 	{
6551 	    /* ":sign unplace *": remove all placed signs */
6552 	    buf_delete_all_signs();
6553 	    return;
6554 	}
6555 
6556 	/* first arg could be placed sign id */
6557 	arg1 = arg;
6558 	if (VIM_ISDIGIT(*arg))
6559 	{
6560 	    id = getdigits(&arg);
6561 	    if (!vim_iswhite(*arg) && *arg != NUL)
6562 	    {
6563 		id = -1;
6564 		arg = arg1;
6565 	    }
6566 	    else
6567 	    {
6568 		arg = skipwhite(arg);
6569 		if (idx == SIGNCMD_UNPLACE && *arg == NUL)
6570 		{
6571 		    /* ":sign unplace {id}": remove placed sign by number */
6572 		    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
6573 			if ((lnum = buf_delsign(buf, id)) != 0)
6574 			    update_debug_sign(buf, lnum);
6575 		    return;
6576 		}
6577 	    }
6578 	}
6579 
6580 	/*
6581 	 * Check for line={lnum} name={name} and file={fname} or buffer={nr}.
6582 	 * Leave "arg" pointing to {fname}.
6583 	 */
6584 	for (;;)
6585 	{
6586 	    if (STRNCMP(arg, "line=", 5) == 0)
6587 	    {
6588 		arg += 5;
6589 		lnum = atoi((char *)arg);
6590 		arg = skiptowhite(arg);
6591 	    }
6592 	    else if (STRNCMP(arg, "name=", 5) == 0)
6593 	    {
6594 		arg += 5;
6595 		sign_name = arg;
6596 		arg = skiptowhite(arg);
6597 		if (*arg != NUL)
6598 		    *arg++ = NUL;
6599 	    }
6600 	    else if (STRNCMP(arg, "file=", 5) == 0)
6601 	    {
6602 		arg += 5;
6603 		buf = buflist_findname(arg);
6604 		break;
6605 	    }
6606 	    else if (STRNCMP(arg, "buffer=", 7) == 0)
6607 	    {
6608 		arg += 7;
6609 		buf = buflist_findnr((int)getdigits(&arg));
6610 		if (*skipwhite(arg) != NUL)
6611 		    EMSG(_(e_trailing));
6612 		break;
6613 	    }
6614 	    else
6615 	    {
6616 		EMSG(_(e_invarg));
6617 		return;
6618 	    }
6619 	    arg = skipwhite(arg);
6620 	}
6621 
6622 	if (buf == NULL)
6623 	{
6624 	    EMSG2(_("E158: Invalid buffer name: %s"), arg);
6625 	}
6626 	else if (id <= 0)
6627 	{
6628 	    if (lnum >= 0 || sign_name != NULL)
6629 		EMSG(_(e_invarg));
6630 	    else
6631 		/* ":sign place file={fname}": list placed signs in one file */
6632 		sign_list_placed(buf);
6633 	}
6634 	else if (idx == SIGNCMD_JUMP)
6635 	{
6636 	    /* ":sign jump {id} file={fname}" */
6637 	    if (lnum >= 0 || sign_name != NULL)
6638 		EMSG(_(e_invarg));
6639 	    else if ((lnum = buf_findsign(buf, id)) > 0)
6640 	    {				/* goto a sign ... */
6641 		if (buf_jump_open_win(buf) != NULL)
6642 		{			/* ... in a current window */
6643 		    curwin->w_cursor.lnum = lnum;
6644 		    check_cursor_lnum();
6645 		    beginline(BL_WHITE);
6646 		}
6647 		else
6648 		{			/* ... not currently in a window */
6649 		    char_u	*cmd;
6650 
6651 		    cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25);
6652 		    if (cmd == NULL)
6653 			return;
6654 		    sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname);
6655 		    do_cmdline_cmd(cmd);
6656 		    vim_free(cmd);
6657 		}
6658 #ifdef FEAT_FOLDING
6659 		foldOpenCursor();
6660 #endif
6661 	    }
6662 	    else
6663 		EMSGN(_("E157: Invalid sign ID: %ld"), id);
6664 	}
6665 	else if (idx == SIGNCMD_UNPLACE)
6666 	{
6667 	    /* ":sign unplace {id} file={fname}" */
6668 	    if (lnum >= 0 || sign_name != NULL)
6669 		EMSG(_(e_invarg));
6670 	    else
6671 	    {
6672 		lnum = buf_delsign(buf, id);
6673 		update_debug_sign(buf, lnum);
6674 	    }
6675 	}
6676 	    /* idx == SIGNCMD_PLACE */
6677 	else if (sign_name != NULL)
6678 	{
6679 	    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6680 		if (STRCMP(sp->sn_name, sign_name) == 0)
6681 		    break;
6682 	    if (sp == NULL)
6683 	    {
6684 		EMSG2(_("E155: Unknown sign: %s"), sign_name);
6685 		return;
6686 	    }
6687 	    if (lnum > 0)
6688 		/* ":sign place {id} line={lnum} name={name} file={fname}":
6689 		 * place a sign */
6690 		buf_addsign(buf, id, lnum, sp->sn_typenr);
6691 	    else
6692 		/* ":sign place {id} file={fname}": change sign type */
6693 		lnum = buf_change_sign_type(buf, id, sp->sn_typenr);
6694 	    update_debug_sign(buf, lnum);
6695 	}
6696 	else
6697 	    EMSG(_(e_invarg));
6698     }
6699 }
6700 
6701 #if defined(FEAT_SIGN_ICONS) || defined(PROTO)
6702 /*
6703  * Allocate the icons.  Called when the GUI has started.  Allows defining
6704  * signs before it starts.
6705  */
6706     void
6707 sign_gui_started()
6708 {
6709     sign_T	*sp;
6710 
6711     for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6712 	if (sp->sn_icon != NULL)
6713 	    sp->sn_image = gui_mch_register_sign(sp->sn_icon);
6714 }
6715 #endif
6716 
6717 /*
6718  * List one sign.
6719  */
6720     static void
6721 sign_list_defined(sp)
6722     sign_T	*sp;
6723 {
6724     char_u	*p;
6725 
6726     smsg((char_u *)"sign %s", sp->sn_name);
6727     if (sp->sn_icon != NULL)
6728     {
6729 	MSG_PUTS(" icon=");
6730 	msg_outtrans(sp->sn_icon);
6731 #ifdef FEAT_SIGN_ICONS
6732 	if (sp->sn_image == NULL)
6733 	    MSG_PUTS(_(" (NOT FOUND)"));
6734 #else
6735 	MSG_PUTS(_(" (not supported)"));
6736 #endif
6737     }
6738     if (sp->sn_text != NULL)
6739     {
6740 	MSG_PUTS(" text=");
6741 	msg_outtrans(sp->sn_text);
6742     }
6743     if (sp->sn_line_hl > 0)
6744     {
6745 	MSG_PUTS(" linehl=");
6746 	p = get_highlight_name(NULL, sp->sn_line_hl - 1);
6747 	if (p == NULL)
6748 	    MSG_PUTS("NONE");
6749 	else
6750 	    msg_puts(p);
6751     }
6752     if (sp->sn_text_hl > 0)
6753     {
6754 	MSG_PUTS(" texthl=");
6755 	p = get_highlight_name(NULL, sp->sn_text_hl - 1);
6756 	if (p == NULL)
6757 	    MSG_PUTS("NONE");
6758 	else
6759 	    msg_puts(p);
6760     }
6761 }
6762 
6763 /*
6764  * Get highlighting attribute for sign "typenr".
6765  * If "line" is TRUE: line highl, if FALSE: text highl.
6766  */
6767     int
6768 sign_get_attr(typenr, line)
6769     int		typenr;
6770     int		line;
6771 {
6772     sign_T	*sp;
6773 
6774     for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6775 	if (sp->sn_typenr == typenr)
6776 	{
6777 	    if (line)
6778 	    {
6779 		if (sp->sn_line_hl > 0)
6780 		    return syn_id2attr(sp->sn_line_hl);
6781 	    }
6782 	    else
6783 	    {
6784 		if (sp->sn_text_hl > 0)
6785 		    return syn_id2attr(sp->sn_text_hl);
6786 	    }
6787 	    break;
6788 	}
6789     return 0;
6790 }
6791 
6792 /*
6793  * Get text mark for sign "typenr".
6794  * Returns NULL if there isn't one.
6795  */
6796     char_u *
6797 sign_get_text(typenr)
6798     int		typenr;
6799 {
6800     sign_T	*sp;
6801 
6802     for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6803 	if (sp->sn_typenr == typenr)
6804 	    return sp->sn_text;
6805     return NULL;
6806 }
6807 
6808 #if defined(FEAT_SIGN_ICONS) || defined(PROTO)
6809     void *
6810 sign_get_image(typenr)
6811     int		typenr;		/* the attribute which may have a sign */
6812 {
6813     sign_T	*sp;
6814 
6815     for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6816 	if (sp->sn_typenr == typenr)
6817 	    return sp->sn_image;
6818     return NULL;
6819 }
6820 #endif
6821 
6822 /*
6823  * Get the name of a sign by its typenr.
6824  */
6825     char_u *
6826 sign_typenr2name(typenr)
6827     int		typenr;
6828 {
6829     sign_T	*sp;
6830 
6831     for (sp = first_sign; sp != NULL; sp = sp->sn_next)
6832 	if (sp->sn_typenr == typenr)
6833 	    return sp->sn_name;
6834     return (char_u *)_("[Deleted]");
6835 }
6836 
6837 #endif
6838 
6839 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
6840 /*
6841  * ":drop"
6842  * Opens the first argument in a window.  When there are two or more arguments
6843  * the argument list is redefined.
6844  */
6845     void
6846 ex_drop(eap)
6847     exarg_T	*eap;
6848 {
6849     int		split = FALSE;
6850     win_T	*wp;
6851     buf_T	*buf;
6852 # ifdef FEAT_WINDOWS
6853     tabpage_T	*tp;
6854 # endif
6855 
6856     /*
6857      * Check if the first argument is already being edited in a window.  If
6858      * so, jump to that window.
6859      * We would actually need to check all arguments, but that's complicated
6860      * and mostly only one file is dropped.
6861      * This also ignores wildcards, since it is very unlikely the user is
6862      * editing a file name with a wildcard character.
6863      */
6864     set_arglist(eap->arg);
6865 
6866 # ifdef FEAT_WINDOWS
6867     if (cmdmod.tab)
6868     {
6869 	/* ":tab drop file ...": open a tab for each argument that isn't
6870 	 * edited in a window yet.  It's like ":tab all" but without closing
6871 	 * windows or tabs. */
6872 	ex_all(eap);
6873     }
6874     else
6875 # endif
6876     {
6877 	/* ":drop file ...": Edit the first argument.  Jump to an existing
6878 	 * window if possible, edit in current window if the current buffer
6879 	 * can be abandoned, otherwise open a new window. */
6880 	buf = buflist_findnr(ARGLIST[0].ae_fnum);
6881 
6882 	FOR_ALL_TAB_WINDOWS(tp, wp)
6883 	{
6884 	    if (wp->w_buffer == buf)
6885 	    {
6886 # ifdef FEAT_WINDOWS
6887 		goto_tabpage_tp(tp);
6888 		win_enter(wp, TRUE);
6889 #  ifdef FEAT_GUI_TABLINE
6890 		if (gui_use_tabline())
6891 		    gui_mch_set_curtab(tabpage_index(curtab));
6892 #  endif
6893 # endif
6894 		curwin->w_arg_idx = 0;
6895 		return;
6896 	    }
6897 	}
6898 
6899 	/*
6900 	 * Check whether the current buffer is changed. If so, we will need
6901 	 * to split the current window or data could be lost.
6902 	 * Skip the check if the 'hidden' option is set, as in this case the
6903 	 * buffer won't be lost.
6904 	 */
6905 	if (!P_HID(curbuf))
6906 	{
6907 # ifdef FEAT_WINDOWS
6908 	    ++emsg_off;
6909 # endif
6910 	    split = check_changed(curbuf, TRUE, FALSE, FALSE, FALSE);
6911 # ifdef FEAT_WINDOWS
6912 	    --emsg_off;
6913 # else
6914 	    if (split)
6915 		return;
6916 # endif
6917 	}
6918 
6919 	/* Fake a ":sfirst" or ":first" command edit the first argument. */
6920 	if (split)
6921 	{
6922 	    eap->cmdidx = CMD_sfirst;
6923 	    eap->cmd[0] = 's';
6924 	}
6925 	else
6926 	    eap->cmdidx = CMD_first;
6927 	ex_rewind(eap);
6928     }
6929 }
6930 #endif
6931