xref: /vim-8.2.3635/src/register.c (revision 3075a455)
1 /* vi:set ts=8 sts=4 sw=4 noet:
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  * register.c: functions for managing registers
12  */
13 
14 #include "vim.h"
15 
16 /*
17  * Registers:
18  *	0 = unnamed register, for normal yanks and puts
19  *   1..9 = registers '1' to '9', for deletes
20  * 10..35 = registers 'a' to 'z' ('A' to 'Z' for appending)
21  *     36 = delete register '-'
22  *     37 = Selection register '*'. Only if FEAT_CLIPBOARD defined
23  *     38 = Clipboard register '+'. Only if FEAT_CLIPBOARD and FEAT_X11 defined
24  */
25 static yankreg_T	y_regs[NUM_REGISTERS];
26 
27 static yankreg_T	*y_current;	    // ptr to current yankreg
28 static int		y_append;	    // TRUE when appending
29 static yankreg_T	*y_previous = NULL; // ptr to last written yankreg
30 
31 static int	stuff_yank(int, char_u *);
32 static void	put_reedit_in_typebuf(int silent);
33 static int	put_in_typebuf(char_u *s, int esc, int colon,
34 								 int silent);
35 static int	yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space);
36 #ifdef FEAT_CLIPBOARD
37 static void	copy_yank_reg(yankreg_T *reg);
38 #endif
39 static void	dis_msg(char_u *p, int skip_esc);
40 
41     yankreg_T *
get_y_regs(void)42 get_y_regs(void)
43 {
44     return y_regs;
45 }
46 
47     yankreg_T *
get_y_register(int reg)48 get_y_register(int reg)
49 {
50     return &y_regs[reg];
51 }
52 
53     yankreg_T *
get_y_current(void)54 get_y_current(void)
55 {
56     return y_current;
57 }
58 
59     yankreg_T *
get_y_previous(void)60 get_y_previous(void)
61 {
62     return y_previous;
63 }
64 
65     void
set_y_current(yankreg_T * yreg)66 set_y_current(yankreg_T *yreg)
67 {
68     y_current = yreg;
69 }
70 
71     void
set_y_previous(yankreg_T * yreg)72 set_y_previous(yankreg_T *yreg)
73 {
74     y_previous = yreg;
75 }
76 
77     void
reset_y_append(void)78 reset_y_append(void)
79 {
80     y_append = FALSE;
81 }
82 
83 
84 #if defined(FEAT_EVAL) || defined(PROTO)
85 /*
86  * Keep the last expression line here, for repeating.
87  */
88 static char_u	*expr_line = NULL;
89 static exarg_T	*expr_eap = NULL;
90 
91 /*
92  * Get an expression for the "\"=expr1" or "CTRL-R =expr1"
93  * Returns '=' when OK, NUL otherwise.
94  */
95     int
get_expr_register(void)96 get_expr_register(void)
97 {
98     char_u	*new_line;
99 
100     new_line = getcmdline('=', 0L, 0, TRUE);
101     if (new_line == NULL)
102 	return NUL;
103     if (*new_line == NUL)	// use previous line
104 	vim_free(new_line);
105     else
106 	set_expr_line(new_line, NULL);
107     return '=';
108 }
109 
110 /*
111  * Set the expression for the '=' register.
112  * Argument must be an allocated string.
113  * "eap" may be used if the next line needs to be checked when evaluating the
114  * expression.
115  */
116     void
set_expr_line(char_u * new_line,exarg_T * eap)117 set_expr_line(char_u *new_line, exarg_T *eap)
118 {
119     vim_free(expr_line);
120     expr_line = new_line;
121     expr_eap = eap;
122 }
123 
124 /*
125  * Get the result of the '=' register expression.
126  * Returns a pointer to allocated memory, or NULL for failure.
127  */
128     char_u *
get_expr_line(void)129 get_expr_line(void)
130 {
131     char_u	*expr_copy;
132     char_u	*rv;
133     static int	nested = 0;
134 
135     if (expr_line == NULL)
136 	return NULL;
137 
138     // Make a copy of the expression, because evaluating it may cause it to be
139     // changed.
140     expr_copy = vim_strsave(expr_line);
141     if (expr_copy == NULL)
142 	return NULL;
143 
144     // When we are invoked recursively limit the evaluation to 10 levels.
145     // Then return the string as-is.
146     if (nested >= 10)
147 	return expr_copy;
148 
149     ++nested;
150     rv = eval_to_string_eap(expr_copy, TRUE, expr_eap);
151     --nested;
152     vim_free(expr_copy);
153     return rv;
154 }
155 
156 /*
157  * Get the '=' register expression itself, without evaluating it.
158  */
159     static char_u *
get_expr_line_src(void)160 get_expr_line_src(void)
161 {
162     if (expr_line == NULL)
163 	return NULL;
164     return vim_strsave(expr_line);
165 }
166 #endif // FEAT_EVAL
167 
168 /*
169  * Check if 'regname' is a valid name of a yank register.
170  * Note: There is no check for 0 (default register), caller should do this
171  */
172     int
valid_yank_reg(int regname,int writing)173 valid_yank_reg(
174     int	    regname,
175     int	    writing)	    // if TRUE check for writable registers
176 {
177     if (       (regname > 0 && ASCII_ISALNUM(regname))
178 	    || (!writing && vim_strchr((char_u *)
179 #ifdef FEAT_EVAL
180 				    "/.%:="
181 #else
182 				    "/.%:"
183 #endif
184 					, regname) != NULL)
185 	    || regname == '#'
186 	    || regname == '"'
187 	    || regname == '-'
188 	    || regname == '_'
189 #ifdef FEAT_CLIPBOARD
190 	    || regname == '*'
191 	    || regname == '+'
192 #endif
193 #ifdef FEAT_DND
194 	    || (!writing && regname == '~')
195 #endif
196 							)
197 	return TRUE;
198     return FALSE;
199 }
200 
201 /*
202  * Set y_current and y_append, according to the value of "regname".
203  * Cannot handle the '_' register.
204  * Must only be called with a valid register name!
205  *
206  * If regname is 0 and writing, use register 0
207  * If regname is 0 and reading, use previous register
208  *
209  * Return TRUE when the register should be inserted literally (selection or
210  * clipboard).
211  */
212     int
get_yank_register(int regname,int writing)213 get_yank_register(int regname, int writing)
214 {
215     int	    i;
216     int	    ret = FALSE;
217 
218     y_append = FALSE;
219     if ((regname == 0 || regname == '"') && !writing && y_previous != NULL)
220     {
221 	y_current = y_previous;
222 	return ret;
223     }
224     i = regname;
225     if (VIM_ISDIGIT(i))
226 	i -= '0';
227     else if (ASCII_ISLOWER(i))
228 	i = CharOrdLow(i) + 10;
229     else if (ASCII_ISUPPER(i))
230     {
231 	i = CharOrdUp(i) + 10;
232 	y_append = TRUE;
233     }
234     else if (regname == '-')
235 	i = DELETION_REGISTER;
236 #ifdef FEAT_CLIPBOARD
237     // When selection is not available, use register 0 instead of '*'
238     else if (clip_star.available && regname == '*')
239     {
240 	i = STAR_REGISTER;
241 	ret = TRUE;
242     }
243     // When clipboard is not available, use register 0 instead of '+'
244     else if (clip_plus.available && regname == '+')
245     {
246 	i = PLUS_REGISTER;
247 	ret = TRUE;
248     }
249 #endif
250 #ifdef FEAT_DND
251     else if (!writing && regname == '~')
252 	i = TILDE_REGISTER;
253 #endif
254     else		// not 0-9, a-z, A-Z or '-': use register 0
255 	i = 0;
256     y_current = &(y_regs[i]);
257     if (writing)	// remember the register we write into for do_put()
258 	y_previous = y_current;
259     return ret;
260 }
261 
262 /*
263  * Obtain the contents of a "normal" register. The register is made empty.
264  * The returned pointer has allocated memory, use put_register() later.
265  */
266     void *
get_register(int name,int copy)267 get_register(
268     int		name,
269     int		copy)	// make a copy, if FALSE make register empty.
270 {
271     yankreg_T	*reg;
272     int		i;
273 
274 #ifdef FEAT_CLIPBOARD
275     // When Visual area changed, may have to update selection.  Obtain the
276     // selection too.
277     if (name == '*' && clip_star.available)
278     {
279 	if (clip_isautosel_star())
280 	    clip_update_selection(&clip_star);
281 	may_get_selection(name);
282     }
283     if (name == '+' && clip_plus.available)
284     {
285 	if (clip_isautosel_plus())
286 	    clip_update_selection(&clip_plus);
287 	may_get_selection(name);
288     }
289 #endif
290 
291     get_yank_register(name, 0);
292     reg = ALLOC_ONE(yankreg_T);
293     if (reg != NULL)
294     {
295 	*reg = *y_current;
296 	if (copy)
297 	{
298 	    // If we run out of memory some or all of the lines are empty.
299 	    if (reg->y_size == 0)
300 		reg->y_array = NULL;
301 	    else
302 		reg->y_array = ALLOC_MULT(char_u *, reg->y_size);
303 	    if (reg->y_array != NULL)
304 	    {
305 		for (i = 0; i < reg->y_size; ++i)
306 		    reg->y_array[i] = vim_strsave(y_current->y_array[i]);
307 	    }
308 	}
309 	else
310 	    y_current->y_array = NULL;
311     }
312     return (void *)reg;
313 }
314 
315 /*
316  * Put "reg" into register "name".  Free any previous contents and "reg".
317  */
318     void
put_register(int name,void * reg)319 put_register(int name, void *reg)
320 {
321     get_yank_register(name, 0);
322     free_yank_all();
323     *y_current = *(yankreg_T *)reg;
324     vim_free(reg);
325 
326 #ifdef FEAT_CLIPBOARD
327     // Send text written to clipboard register to the clipboard.
328     may_set_selection();
329 #endif
330 }
331 
332 #if defined(FEAT_CLIPBOARD) || defined(PROTO)
333     void
free_register(void * reg)334 free_register(void *reg)
335 {
336     yankreg_T tmp;
337 
338     tmp = *y_current;
339     *y_current = *(yankreg_T *)reg;
340     free_yank_all();
341     vim_free(reg);
342     *y_current = tmp;
343 }
344 #endif
345 
346 /*
347  * return TRUE if the current yank register has type MLINE
348  */
349     int
yank_register_mline(int regname)350 yank_register_mline(int regname)
351 {
352     if (regname != 0 && !valid_yank_reg(regname, FALSE))
353 	return FALSE;
354     if (regname == '_')		// black hole is always empty
355 	return FALSE;
356     get_yank_register(regname, FALSE);
357     return (y_current->y_type == MLINE);
358 }
359 
360 /*
361  * Start or stop recording into a yank register.
362  *
363  * Return FAIL for failure, OK otherwise.
364  */
365     int
do_record(int c)366 do_record(int c)
367 {
368     char_u	    *p;
369     static int	    regname;
370     yankreg_T	    *old_y_previous, *old_y_current;
371     int		    retval;
372 
373     if (reg_recording == 0)	    // start recording
374     {
375 	// registers 0-9, a-z and " are allowed
376 	if (c < 0 || (!ASCII_ISALNUM(c) && c != '"'))
377 	    retval = FAIL;
378 	else
379 	{
380 	    reg_recording = c;
381 	    showmode();
382 	    regname = c;
383 	    retval = OK;
384 	}
385     }
386     else			    // stop recording
387     {
388 	// Get the recorded key hits.  K_SPECIAL and CSI will be escaped, this
389 	// needs to be removed again to put it in a register.  exec_reg then
390 	// adds the escaping back later.
391 	reg_recording = 0;
392 	msg("");
393 	p = get_recorded();
394 	if (p == NULL)
395 	    retval = FAIL;
396 	else
397 	{
398 	    // Remove escaping for CSI and K_SPECIAL in multi-byte chars.
399 	    vim_unescape_csi(p);
400 
401 	    // We don't want to change the default register here, so save and
402 	    // restore the current register name.
403 	    old_y_previous = y_previous;
404 	    old_y_current = y_current;
405 
406 	    retval = stuff_yank(regname, p);
407 
408 	    y_previous = old_y_previous;
409 	    y_current = old_y_current;
410 	}
411     }
412     return retval;
413 }
414 
415 /*
416  * Stuff string "p" into yank register "regname" as a single line (append if
417  * uppercase).	"p" must have been alloced.
418  *
419  * return FAIL for failure, OK otherwise
420  */
421     static int
stuff_yank(int regname,char_u * p)422 stuff_yank(int regname, char_u *p)
423 {
424     char_u	*lp;
425     char_u	**pp;
426 
427     // check for read-only register
428     if (regname != 0 && !valid_yank_reg(regname, TRUE))
429     {
430 	vim_free(p);
431 	return FAIL;
432     }
433     if (regname == '_')		    // black hole: don't do anything
434     {
435 	vim_free(p);
436 	return OK;
437     }
438     get_yank_register(regname, TRUE);
439     if (y_append && y_current->y_array != NULL)
440     {
441 	pp = &(y_current->y_array[y_current->y_size - 1]);
442 	lp = alloc(STRLEN(*pp) + STRLEN(p) + 1);
443 	if (lp == NULL)
444 	{
445 	    vim_free(p);
446 	    return FAIL;
447 	}
448 	STRCPY(lp, *pp);
449 	STRCAT(lp, p);
450 	vim_free(p);
451 	vim_free(*pp);
452 	*pp = lp;
453     }
454     else
455     {
456 	free_yank_all();
457 	if ((y_current->y_array = ALLOC_ONE(char_u *)) == NULL)
458 	{
459 	    vim_free(p);
460 	    return FAIL;
461 	}
462 	y_current->y_array[0] = p;
463 	y_current->y_size = 1;
464 	y_current->y_type = MCHAR;  // used to be MLINE, why?
465 #ifdef FEAT_VIMINFO
466 	y_current->y_time_set = vim_time();
467 #endif
468     }
469     return OK;
470 }
471 
472 /*
473  * Last executed register (@ command)
474  */
475 static int execreg_lastc = NUL;
476 
477     int
get_execreg_lastc(void)478 get_execreg_lastc(void)
479 {
480     return execreg_lastc;
481 }
482 
483     void
set_execreg_lastc(int lastc)484 set_execreg_lastc(int lastc)
485 {
486     execreg_lastc = lastc;
487 }
488 
489 /*
490  * When executing a register as a series of ex-commands, if the
491  * line-continuation character is used for a line, then join it with one or
492  * more previous lines. Note that lines are processed backwards starting from
493  * the last line in the register.
494  *
495  * Arguments:
496  *   lines - list of lines in the register
497  *   idx - index of the line starting with \ or "\. Join this line with all the
498  *	   immediate predecessor lines that start with a \ and the first line
499  *	   that doesn't start with a \. Lines that start with a comment "\
500  *	   character are ignored.
501  *
502  * Returns the concatenated line. The index of the line that should be
503  * processed next is returned in idx.
504  */
505     static char_u *
execreg_line_continuation(char_u ** lines,long * idx)506 execreg_line_continuation(char_u **lines, long *idx)
507 {
508     garray_T	ga;
509     long	i = *idx;
510     char_u	*p;
511     int		cmd_start;
512     int		cmd_end = i;
513     int		j;
514     char_u	*str;
515 
516     ga_init2(&ga, (int)sizeof(char_u), 400);
517 
518     // search backwards to find the first line of this command.
519     // Any line not starting with \ or "\ is the start of the
520     // command.
521     while (--i > 0)
522     {
523 	p = skipwhite(lines[i]);
524 	if (*p != '\\' && (p[0] != '"' || p[1] != '\\' || p[2] != ' '))
525 	    break;
526     }
527     cmd_start = i;
528 
529     // join all the lines
530     ga_concat(&ga, lines[cmd_start]);
531     for (j = cmd_start + 1; j <= cmd_end; j++)
532     {
533 	p = skipwhite(lines[j]);
534 	if (*p == '\\')
535 	{
536 	    // Adjust the growsize to the current length to
537 	    // speed up concatenating many lines.
538 	    if (ga.ga_len > 400)
539 	    {
540 		if (ga.ga_len > 8000)
541 		    ga.ga_growsize = 8000;
542 		else
543 		    ga.ga_growsize = ga.ga_len;
544 	    }
545 	    ga_concat(&ga, p + 1);
546 	}
547     }
548     ga_append(&ga, NUL);
549     str = vim_strsave(ga.ga_data);
550     ga_clear(&ga);
551 
552     *idx = i;
553     return str;
554 }
555 
556 /*
557  * Execute a yank register: copy it into the stuff buffer.
558  *
559  * Return FAIL for failure, OK otherwise.
560  */
561     int
do_execreg(int regname,int colon,int addcr,int silent)562 do_execreg(
563     int	    regname,
564     int	    colon,		// insert ':' before each line
565     int	    addcr,		// always add '\n' to end of line
566     int	    silent)		// set "silent" flag in typeahead buffer
567 {
568     long	i;
569     char_u	*p;
570     int		retval = OK;
571     int		remap;
572 
573     // repeat previous one
574     if (regname == '@')
575     {
576 	if (execreg_lastc == NUL)
577 	{
578 	    emsg(_("E748: No previously used register"));
579 	    return FAIL;
580 	}
581 	regname = execreg_lastc;
582     }
583     // check for valid regname
584     if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE))
585     {
586 	emsg_invreg(regname);
587 	return FAIL;
588     }
589     execreg_lastc = regname;
590 
591 #ifdef FEAT_CLIPBOARD
592     regname = may_get_selection(regname);
593 #endif
594 
595     // black hole: don't stuff anything
596     if (regname == '_')
597 	return OK;
598 
599     // use last command line
600     if (regname == ':')
601     {
602 	if (last_cmdline == NULL)
603 	{
604 	    emsg(_(e_no_previous_command_line));
605 	    return FAIL;
606 	}
607 	// don't keep the cmdline containing @:
608 	VIM_CLEAR(new_last_cmdline);
609 	// Escape all control characters with a CTRL-V
610 	p = vim_strsave_escaped_ext(last_cmdline,
611 		    (char_u *)"\001\002\003\004\005\006\007"
612 			  "\010\011\012\013\014\015\016\017"
613 			  "\020\021\022\023\024\025\026\027"
614 			  "\030\031\032\033\034\035\036\037",
615 		    Ctrl_V, FALSE);
616 	if (p != NULL)
617 	{
618 	    // When in Visual mode "'<,'>" will be prepended to the command.
619 	    // Remove it when it's already there.
620 	    if (VIsual_active && STRNCMP(p, "'<,'>", 5) == 0)
621 		retval = put_in_typebuf(p + 5, TRUE, TRUE, silent);
622 	    else
623 		retval = put_in_typebuf(p, TRUE, TRUE, silent);
624 	}
625 	vim_free(p);
626     }
627 #ifdef FEAT_EVAL
628     else if (regname == '=')
629     {
630 	p = get_expr_line();
631 	if (p == NULL)
632 	    return FAIL;
633 	retval = put_in_typebuf(p, TRUE, colon, silent);
634 	vim_free(p);
635     }
636 #endif
637     else if (regname == '.')		// use last inserted text
638     {
639 	p = get_last_insert_save();
640 	if (p == NULL)
641 	{
642 	    emsg(_(e_no_inserted_text_yet));
643 	    return FAIL;
644 	}
645 	retval = put_in_typebuf(p, FALSE, colon, silent);
646 	vim_free(p);
647     }
648     else
649     {
650 	get_yank_register(regname, FALSE);
651 	if (y_current->y_array == NULL)
652 	    return FAIL;
653 
654 	// Disallow remapping for ":@r".
655 	remap = colon ? REMAP_NONE : REMAP_YES;
656 
657 	// Insert lines into typeahead buffer, from last one to first one.
658 	put_reedit_in_typebuf(silent);
659 	for (i = y_current->y_size; --i >= 0; )
660 	{
661 	    char_u *escaped;
662 	    char_u *str;
663 	    int	    free_str = FALSE;
664 
665 	    // insert NL between lines and after last line if type is MLINE
666 	    if (y_current->y_type == MLINE || i < y_current->y_size - 1
667 								     || addcr)
668 	    {
669 		if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL)
670 		    return FAIL;
671 	    }
672 
673 	    // Handle line-continuation for :@<register>
674 	    str = y_current->y_array[i];
675 	    if (colon && i > 0)
676 	    {
677 		p = skipwhite(str);
678 		if (*p == '\\' || (p[0] == '"' && p[1] == '\\' && p[2] == ' '))
679 		{
680 		    str = execreg_line_continuation(y_current->y_array, &i);
681 		    if (str == NULL)
682 			return FAIL;
683 		    free_str = TRUE;
684 		}
685 	    }
686 	    escaped = vim_strsave_escape_csi(str);
687 	    if (free_str)
688 		vim_free(str);
689 	    if (escaped == NULL)
690 		return FAIL;
691 	    retval = ins_typebuf(escaped, remap, 0, TRUE, silent);
692 	    vim_free(escaped);
693 	    if (retval == FAIL)
694 		return FAIL;
695 	    if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, silent)
696 								      == FAIL)
697 		return FAIL;
698 	}
699 	reg_executing = regname == 0 ? '"' : regname; // disable "q" command
700     }
701     return retval;
702 }
703 
704 /*
705  * If "restart_edit" is not zero, put it in the typeahead buffer, so that it's
706  * used only after other typeahead has been processed.
707  */
708     static void
put_reedit_in_typebuf(int silent)709 put_reedit_in_typebuf(int silent)
710 {
711     char_u	buf[3];
712 
713     if (restart_edit != NUL)
714     {
715 	if (restart_edit == 'V')
716 	{
717 	    buf[0] = 'g';
718 	    buf[1] = 'R';
719 	    buf[2] = NUL;
720 	}
721 	else
722 	{
723 	    buf[0] = restart_edit == 'I' ? 'i' : restart_edit;
724 	    buf[1] = NUL;
725 	}
726 	if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK)
727 	    restart_edit = NUL;
728     }
729 }
730 
731 /*
732  * Insert register contents "s" into the typeahead buffer, so that it will be
733  * executed again.
734  * When "esc" is TRUE it is to be taken literally: Escape CSI characters and
735  * no remapping.
736  */
737     static int
put_in_typebuf(char_u * s,int esc,int colon,int silent)738 put_in_typebuf(
739     char_u	*s,
740     int		esc,
741     int		colon,	    // add ':' before the line
742     int		silent)
743 {
744     int		retval = OK;
745 
746     put_reedit_in_typebuf(silent);
747     if (colon)
748 	retval = ins_typebuf((char_u *)"\n", REMAP_NONE, 0, TRUE, silent);
749     if (retval == OK)
750     {
751 	char_u	*p;
752 
753 	if (esc)
754 	    p = vim_strsave_escape_csi(s);
755 	else
756 	    p = s;
757 	if (p == NULL)
758 	    retval = FAIL;
759 	else
760 	    retval = ins_typebuf(p, esc ? REMAP_NONE : REMAP_YES,
761 							     0, TRUE, silent);
762 	if (esc)
763 	    vim_free(p);
764     }
765     if (colon && retval == OK)
766 	retval = ins_typebuf((char_u *)":", REMAP_NONE, 0, TRUE, silent);
767     return retval;
768 }
769 
770 /*
771  * Insert a yank register: copy it into the Read buffer.
772  * Used by CTRL-R command and middle mouse button in insert mode.
773  *
774  * return FAIL for failure, OK otherwise
775  */
776     int
insert_reg(int regname,int literally_arg)777 insert_reg(
778     int		regname,
779     int		literally_arg)	// insert literally, not as if typed
780 {
781     long	i;
782     int		retval = OK;
783     char_u	*arg;
784     int		allocated;
785     int		literally = literally_arg;
786 
787     // It is possible to get into an endless loop by having CTRL-R a in
788     // register a and then, in insert mode, doing CTRL-R a.
789     // If you hit CTRL-C, the loop will be broken here.
790     ui_breakcheck();
791     if (got_int)
792 	return FAIL;
793 
794     // check for valid regname
795     if (regname != NUL && !valid_yank_reg(regname, FALSE))
796 	return FAIL;
797 
798 #ifdef FEAT_CLIPBOARD
799     regname = may_get_selection(regname);
800 #endif
801 
802     if (regname == '.')			// insert last inserted text
803 	retval = stuff_inserted(NUL, 1L, TRUE);
804     else if (get_spec_reg(regname, &arg, &allocated, TRUE))
805     {
806 	if (arg == NULL)
807 	    return FAIL;
808 	stuffescaped(arg, literally);
809 	if (allocated)
810 	    vim_free(arg);
811     }
812     else				// name or number register
813     {
814 	if (get_yank_register(regname, FALSE))
815 	    literally = TRUE;
816 	if (y_current->y_array == NULL)
817 	    retval = FAIL;
818 	else
819 	{
820 	    for (i = 0; i < y_current->y_size; ++i)
821 	    {
822 		if (regname == '-')
823 		{
824 		    AppendCharToRedobuff(Ctrl_R);
825 		    AppendCharToRedobuff(regname);
826 		    do_put(regname, NULL, BACKWARD, 1L, PUT_CURSEND);
827 		}
828 		else
829 		    stuffescaped(y_current->y_array[i], literally);
830 		// Insert a newline between lines and after last line if
831 		// y_type is MLINE.
832 		if (y_current->y_type == MLINE || i < y_current->y_size - 1)
833 		    stuffcharReadbuff('\n');
834 	    }
835 	}
836     }
837 
838     return retval;
839 }
840 
841 /*
842  * If "regname" is a special register, return TRUE and store a pointer to its
843  * value in "argp".
844  */
845     int
get_spec_reg(int regname,char_u ** argp,int * allocated,int errmsg)846 get_spec_reg(
847     int		regname,
848     char_u	**argp,
849     int		*allocated,	// return: TRUE when value was allocated
850     int		errmsg)		// give error message when failing
851 {
852     int		cnt;
853 
854     *argp = NULL;
855     *allocated = FALSE;
856     switch (regname)
857     {
858 	case '%':		// file name
859 	    if (errmsg)
860 		check_fname();	// will give emsg if not set
861 	    *argp = curbuf->b_fname;
862 	    return TRUE;
863 
864 	case '#':		// alternate file name
865 	    *argp = getaltfname(errmsg);	// may give emsg if not set
866 	    return TRUE;
867 
868 #ifdef FEAT_EVAL
869 	case '=':		// result of expression
870 	    *argp = get_expr_line();
871 	    *allocated = TRUE;
872 	    return TRUE;
873 #endif
874 
875 	case ':':		// last command line
876 	    if (last_cmdline == NULL && errmsg)
877 		emsg(_(e_no_previous_command_line));
878 	    *argp = last_cmdline;
879 	    return TRUE;
880 
881 	case '/':		// last search-pattern
882 	    if (last_search_pat() == NULL && errmsg)
883 		emsg(_(e_no_previous_regular_expression));
884 	    *argp = last_search_pat();
885 	    return TRUE;
886 
887 	case '.':		// last inserted text
888 	    *argp = get_last_insert_save();
889 	    *allocated = TRUE;
890 	    if (*argp == NULL && errmsg)
891 		emsg(_(e_no_inserted_text_yet));
892 	    return TRUE;
893 
894 #ifdef FEAT_SEARCHPATH
895 	case Ctrl_F:		// Filename under cursor
896 	case Ctrl_P:		// Path under cursor, expand via "path"
897 	    if (!errmsg)
898 		return FALSE;
899 	    *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP
900 			    | (regname == Ctrl_P ? FNAME_EXP : 0), 1L, NULL);
901 	    *allocated = TRUE;
902 	    return TRUE;
903 #endif
904 
905 	case Ctrl_W:		// word under cursor
906 	case Ctrl_A:		// WORD (mnemonic All) under cursor
907 	    if (!errmsg)
908 		return FALSE;
909 	    cnt = find_ident_under_cursor(argp, regname == Ctrl_W
910 				   ?  (FIND_IDENT|FIND_STRING) : FIND_STRING);
911 	    *argp = cnt ? vim_strnsave(*argp, cnt) : NULL;
912 	    *allocated = TRUE;
913 	    return TRUE;
914 
915 	case Ctrl_L:		// Line under cursor
916 	    if (!errmsg)
917 		return FALSE;
918 
919 	    *argp = ml_get_buf(curwin->w_buffer,
920 			curwin->w_cursor.lnum, FALSE);
921 	    return TRUE;
922 
923 	case '_':		// black hole: always empty
924 	    *argp = (char_u *)"";
925 	    return TRUE;
926     }
927 
928     return FALSE;
929 }
930 
931 /*
932  * Paste a yank register into the command line.
933  * Only for non-special registers.
934  * Used by CTRL-R command in command-line mode
935  * insert_reg() can't be used here, because special characters from the
936  * register contents will be interpreted as commands.
937  *
938  * return FAIL for failure, OK otherwise
939  */
940     int
cmdline_paste_reg(int regname,int literally_arg,int remcr)941 cmdline_paste_reg(
942     int regname,
943     int literally_arg,	// Insert text literally instead of "as typed"
944     int remcr)		// don't add CR characters
945 {
946     long	i;
947     int		literally = literally_arg;
948 
949     if (get_yank_register(regname, FALSE))
950 	literally = TRUE;
951     if (y_current->y_array == NULL)
952 	return FAIL;
953 
954     for (i = 0; i < y_current->y_size; ++i)
955     {
956 	cmdline_paste_str(y_current->y_array[i], literally);
957 
958 	// Insert ^M between lines and after last line if type is MLINE.
959 	// Don't do this when "remcr" is TRUE.
960 	if ((y_current->y_type == MLINE || i < y_current->y_size - 1) && !remcr)
961 	    cmdline_paste_str((char_u *)"\r", literally);
962 
963 	// Check for CTRL-C, in case someone tries to paste a few thousand
964 	// lines and gets bored.
965 	ui_breakcheck();
966 	if (got_int)
967 	    return FAIL;
968     }
969     return OK;
970 }
971 
972 /*
973  * Shift the delete registers: "9 is cleared, "8 becomes "9, etc.
974  */
975     void
shift_delete_registers()976 shift_delete_registers()
977 {
978     int		n;
979 
980     y_current = &y_regs[9];
981     free_yank_all();			// free register nine
982     for (n = 9; n > 1; --n)
983 	y_regs[n] = y_regs[n - 1];
984     y_current = &y_regs[1];
985     if (!y_append)
986 	y_previous = y_current;
987     y_regs[1].y_array = NULL;		// set register one to empty
988 }
989 
990 #if defined(FEAT_EVAL)
991     void
yank_do_autocmd(oparg_T * oap,yankreg_T * reg)992 yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
993 {
994     static int	    recursive = FALSE;
995     dict_T	    *v_event;
996     list_T	    *list;
997     int		    n;
998     char_u	    buf[NUMBUFLEN + 2];
999     long	    reglen = 0;
1000     save_v_event_T  save_v_event;
1001 
1002     if (recursive)
1003 	return;
1004 
1005     v_event = get_v_event(&save_v_event);
1006 
1007     list = list_alloc();
1008     if (list == NULL)
1009 	return;
1010     for (n = 0; n < reg->y_size; n++)
1011 	list_append_string(list, reg->y_array[n], -1);
1012     list->lv_lock = VAR_FIXED;
1013     (void)dict_add_list(v_event, "regcontents", list);
1014 
1015     buf[0] = (char_u)oap->regname;
1016     buf[1] = NUL;
1017     (void)dict_add_string(v_event, "regname", buf);
1018 
1019     buf[0] = get_op_char(oap->op_type);
1020     buf[1] = get_extra_op_char(oap->op_type);
1021     buf[2] = NUL;
1022     (void)dict_add_string(v_event, "operator", buf);
1023 
1024     buf[0] = NUL;
1025     buf[1] = NUL;
1026     switch (get_reg_type(oap->regname, &reglen))
1027     {
1028 	case MLINE: buf[0] = 'V'; break;
1029 	case MCHAR: buf[0] = 'v'; break;
1030 	case MBLOCK:
1031 		vim_snprintf((char *)buf, sizeof(buf), "%c%ld", Ctrl_V,
1032 			     reglen + 1);
1033 		break;
1034     }
1035     (void)dict_add_string(v_event, "regtype", buf);
1036 
1037     (void)dict_add_bool(v_event, "visual", oap->is_VIsual);
1038 
1039     // Lock the dictionary and its keys
1040     dict_set_items_ro(v_event);
1041 
1042     recursive = TRUE;
1043     textwinlock++;
1044     apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, FALSE, curbuf);
1045     textwinlock--;
1046     recursive = FALSE;
1047 
1048     // Empty the dictionary, v:event is still valid
1049     restore_v_event(v_event, &save_v_event);
1050 }
1051 #endif
1052 
1053 /*
1054  * set all the yank registers to empty (called from main())
1055  */
1056     void
init_yank(void)1057 init_yank(void)
1058 {
1059     int		i;
1060 
1061     for (i = 0; i < NUM_REGISTERS; ++i)
1062 	y_regs[i].y_array = NULL;
1063 }
1064 
1065 #if defined(EXITFREE) || defined(PROTO)
1066     void
clear_registers(void)1067 clear_registers(void)
1068 {
1069     int		i;
1070 
1071     for (i = 0; i < NUM_REGISTERS; ++i)
1072     {
1073 	y_current = &y_regs[i];
1074 	if (y_current->y_array != NULL)
1075 	    free_yank_all();
1076     }
1077 }
1078 #endif
1079 
1080 /*
1081  * Free "n" lines from the current yank register.
1082  * Called for normal freeing and in case of error.
1083  */
1084     static void
free_yank(long n)1085 free_yank(long n)
1086 {
1087     if (y_current->y_array != NULL)
1088     {
1089 	long	    i;
1090 
1091 	for (i = n; --i >= 0; )
1092 	{
1093 #ifdef AMIGA	    // only for very slow machines
1094 	    if ((i & 1023) == 1023)  // this may take a while
1095 	    {
1096 		// This message should never cause a hit-return message.
1097 		// Overwrite this message with any next message.
1098 		++no_wait_return;
1099 		smsg(_("freeing %ld lines"), i + 1);
1100 		--no_wait_return;
1101 		msg_didout = FALSE;
1102 		msg_col = 0;
1103 	    }
1104 #endif
1105 	    vim_free(y_current->y_array[i]);
1106 	}
1107 	VIM_CLEAR(y_current->y_array);
1108 #ifdef AMIGA
1109 	if (n >= 1000)
1110 	    msg("");
1111 #endif
1112     }
1113 }
1114 
1115     void
free_yank_all(void)1116 free_yank_all(void)
1117 {
1118     free_yank(y_current->y_size);
1119 }
1120 
1121 /*
1122  * Yank the text between "oap->start" and "oap->end" into a yank register.
1123  * If we are to append (uppercase register), we first yank into a new yank
1124  * register and then concatenate the old and the new one (so we keep the old
1125  * one in case of out-of-memory).
1126  *
1127  * Return FAIL for failure, OK otherwise.
1128  */
1129     int
op_yank(oparg_T * oap,int deleting,int mess)1130 op_yank(oparg_T *oap, int deleting, int mess)
1131 {
1132     long		y_idx;		// index in y_array[]
1133     yankreg_T		*curr;		// copy of y_current
1134     yankreg_T		newreg;		// new yank register when appending
1135     char_u		**new_ptr;
1136     linenr_T		lnum;		// current line number
1137     long		j;
1138     int			yanktype = oap->motion_type;
1139     long		yanklines = oap->line_count;
1140     linenr_T		yankendlnum = oap->end.lnum;
1141     char_u		*p;
1142     char_u		*pnew;
1143     struct block_def	bd;
1144 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
1145     int			did_star = FALSE;
1146 #endif
1147 
1148 				    // check for read-only register
1149     if (oap->regname != 0 && !valid_yank_reg(oap->regname, TRUE))
1150     {
1151 	beep_flush();
1152 	return FAIL;
1153     }
1154     if (oap->regname == '_')	    // black hole: nothing to do
1155 	return OK;
1156 
1157 #ifdef FEAT_CLIPBOARD
1158     if (!clip_star.available && oap->regname == '*')
1159 	oap->regname = 0;
1160     else if (!clip_plus.available && oap->regname == '+')
1161 	oap->regname = 0;
1162 #endif
1163 
1164     if (!deleting)		    // op_delete() already set y_current
1165 	get_yank_register(oap->regname, TRUE);
1166 
1167     curr = y_current;
1168 				    // append to existing contents
1169     if (y_append && y_current->y_array != NULL)
1170 	y_current = &newreg;
1171     else
1172 	free_yank_all();	    // free previously yanked lines
1173 
1174     // If the cursor was in column 1 before and after the movement, and the
1175     // operator is not inclusive, the yank is always linewise.
1176     if (       oap->motion_type == MCHAR
1177 	    && oap->start.col == 0
1178 	    && !oap->inclusive
1179 	    && (!oap->is_VIsual || *p_sel == 'o')
1180 	    && !oap->block_mode
1181 	    && oap->end.col == 0
1182 	    && yanklines > 1)
1183     {
1184 	yanktype = MLINE;
1185 	--yankendlnum;
1186 	--yanklines;
1187     }
1188 
1189     y_current->y_size = yanklines;
1190     y_current->y_type = yanktype;   // set the yank register type
1191     y_current->y_width = 0;
1192     y_current->y_array = lalloc_clear(sizeof(char_u *) * yanklines, TRUE);
1193     if (y_current->y_array == NULL)
1194     {
1195 	y_current = curr;
1196 	return FAIL;
1197     }
1198 #ifdef FEAT_VIMINFO
1199     y_current->y_time_set = vim_time();
1200 #endif
1201 
1202     y_idx = 0;
1203     lnum = oap->start.lnum;
1204 
1205     if (oap->block_mode)
1206     {
1207 	// Visual block mode
1208 	y_current->y_type = MBLOCK;	    // set the yank register type
1209 	y_current->y_width = oap->end_vcol - oap->start_vcol;
1210 
1211 	if (curwin->w_curswant == MAXCOL && y_current->y_width > 0)
1212 	    y_current->y_width--;
1213     }
1214 
1215     for ( ; lnum <= yankendlnum; lnum++, y_idx++)
1216     {
1217 	switch (y_current->y_type)
1218 	{
1219 	    case MBLOCK:
1220 		block_prep(oap, &bd, lnum, FALSE);
1221 		if (yank_copy_line(&bd, y_idx, oap->excl_tr_ws) == FAIL)
1222 		    goto fail;
1223 		break;
1224 
1225 	    case MLINE:
1226 		if ((y_current->y_array[y_idx] =
1227 					    vim_strsave(ml_get(lnum))) == NULL)
1228 		    goto fail;
1229 		break;
1230 
1231 	    case MCHAR:
1232 		{
1233 		    colnr_T startcol = 0, endcol = MAXCOL;
1234 		    int	    is_oneChar = FALSE;
1235 		    colnr_T cs, ce;
1236 
1237 		    p = ml_get(lnum);
1238 		    bd.startspaces = 0;
1239 		    bd.endspaces = 0;
1240 
1241 		    if (lnum == oap->start.lnum)
1242 		    {
1243 			startcol = oap->start.col;
1244 			if (virtual_op)
1245 			{
1246 			    getvcol(curwin, &oap->start, &cs, NULL, &ce);
1247 			    if (ce != cs && oap->start.coladd > 0)
1248 			    {
1249 				// Part of a tab selected -- but don't
1250 				// double-count it.
1251 				bd.startspaces = (ce - cs + 1)
1252 							  - oap->start.coladd;
1253 				startcol++;
1254 			    }
1255 			}
1256 		    }
1257 
1258 		    if (lnum == oap->end.lnum)
1259 		    {
1260 			endcol = oap->end.col;
1261 			if (virtual_op)
1262 			{
1263 			    getvcol(curwin, &oap->end, &cs, NULL, &ce);
1264 			    if (p[endcol] == NUL || (cs + oap->end.coladd < ce
1265 					// Don't add space for double-wide
1266 					// char; endcol will be on last byte
1267 					// of multi-byte char.
1268 					&& (*mb_head_off)(p, p + endcol) == 0))
1269 			    {
1270 				if (oap->start.lnum == oap->end.lnum
1271 					    && oap->start.col == oap->end.col)
1272 				{
1273 				    // Special case: inside a single char
1274 				    is_oneChar = TRUE;
1275 				    bd.startspaces = oap->end.coladd
1276 					 - oap->start.coladd + oap->inclusive;
1277 				    endcol = startcol;
1278 				}
1279 				else
1280 				{
1281 				    bd.endspaces = oap->end.coladd
1282 							     + oap->inclusive;
1283 				    endcol -= oap->inclusive;
1284 				}
1285 			    }
1286 			}
1287 		    }
1288 		    if (endcol == MAXCOL)
1289 			endcol = (colnr_T)STRLEN(p);
1290 		    if (startcol > endcol || is_oneChar)
1291 			bd.textlen = 0;
1292 		    else
1293 			bd.textlen = endcol - startcol + oap->inclusive;
1294 		    bd.textstart = p + startcol;
1295 		    if (yank_copy_line(&bd, y_idx, FALSE) == FAIL)
1296 			goto fail;
1297 		    break;
1298 		}
1299 		// NOTREACHED
1300 	}
1301     }
1302 
1303     if (curr != y_current)	// append the new block to the old block
1304     {
1305 	new_ptr = ALLOC_MULT(char_u *, curr->y_size + y_current->y_size);
1306 	if (new_ptr == NULL)
1307 	    goto fail;
1308 	for (j = 0; j < curr->y_size; ++j)
1309 	    new_ptr[j] = curr->y_array[j];
1310 	vim_free(curr->y_array);
1311 	curr->y_array = new_ptr;
1312 #ifdef FEAT_VIMINFO
1313 	curr->y_time_set = vim_time();
1314 #endif
1315 
1316 	if (yanktype == MLINE)	// MLINE overrides MCHAR and MBLOCK
1317 	    curr->y_type = MLINE;
1318 
1319 	// Concatenate the last line of the old block with the first line of
1320 	// the new block, unless being Vi compatible.
1321 	if (curr->y_type == MCHAR && vim_strchr(p_cpo, CPO_REGAPPEND) == NULL)
1322 	{
1323 	    pnew = alloc(STRLEN(curr->y_array[curr->y_size - 1])
1324 					  + STRLEN(y_current->y_array[0]) + 1);
1325 	    if (pnew == NULL)
1326 	    {
1327 		y_idx = y_current->y_size - 1;
1328 		goto fail;
1329 	    }
1330 	    STRCPY(pnew, curr->y_array[--j]);
1331 	    STRCAT(pnew, y_current->y_array[0]);
1332 	    vim_free(curr->y_array[j]);
1333 	    vim_free(y_current->y_array[0]);
1334 	    curr->y_array[j++] = pnew;
1335 	    y_idx = 1;
1336 	}
1337 	else
1338 	    y_idx = 0;
1339 	while (y_idx < y_current->y_size)
1340 	    curr->y_array[j++] = y_current->y_array[y_idx++];
1341 	curr->y_size = j;
1342 	vim_free(y_current->y_array);
1343 	y_current = curr;
1344     }
1345     if (curwin->w_p_rnu)
1346 	redraw_later(SOME_VALID);	// cursor moved to start
1347     if (mess)			// Display message about yank?
1348     {
1349 	if (yanktype == MCHAR
1350 		&& !oap->block_mode
1351 		&& yanklines == 1)
1352 	    yanklines = 0;
1353 	// Some versions of Vi use ">=" here, some don't...
1354 	if (yanklines > p_report)
1355 	{
1356 	    char namebuf[100];
1357 
1358 	    if (oap->regname == NUL)
1359 		*namebuf = NUL;
1360 	    else
1361 		vim_snprintf(namebuf, sizeof(namebuf),
1362 						_(" into \"%c"), oap->regname);
1363 
1364 	    // redisplay now, so message is not deleted
1365 	    update_topline_redraw();
1366 	    if (oap->block_mode)
1367 	    {
1368 		smsg(NGETTEXT("block of %ld line yanked%s",
1369 				     "block of %ld lines yanked%s", yanklines),
1370 			yanklines, namebuf);
1371 	    }
1372 	    else
1373 	    {
1374 		smsg(NGETTEXT("%ld line yanked%s",
1375 					      "%ld lines yanked%s", yanklines),
1376 			yanklines, namebuf);
1377 	    }
1378 	}
1379     }
1380 
1381     if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0)
1382     {
1383 	// Set "'[" and "']" marks.
1384 	curbuf->b_op_start = oap->start;
1385 	curbuf->b_op_end = oap->end;
1386 	if (yanktype == MLINE && !oap->block_mode)
1387 	{
1388 	    curbuf->b_op_start.col = 0;
1389 	    curbuf->b_op_end.col = MAXCOL;
1390 	}
1391     }
1392 
1393 #ifdef FEAT_CLIPBOARD
1394     // If we were yanking to the '*' register, send result to clipboard.
1395     // If no register was specified, and "unnamed" in 'clipboard', make a copy
1396     // to the '*' register.
1397     if (clip_star.available
1398 	    && (curr == &(y_regs[STAR_REGISTER])
1399 		|| (!deleting && oap->regname == 0
1400 		   && ((clip_unnamed | clip_unnamed_saved) & CLIP_UNNAMED))))
1401     {
1402 	if (curr != &(y_regs[STAR_REGISTER]))
1403 	    // Copy the text from register 0 to the clipboard register.
1404 	    copy_yank_reg(&(y_regs[STAR_REGISTER]));
1405 
1406 	clip_own_selection(&clip_star);
1407 	clip_gen_set_selection(&clip_star);
1408 # ifdef FEAT_X11
1409 	did_star = TRUE;
1410 # endif
1411     }
1412 
1413 # ifdef FEAT_X11
1414     // If we were yanking to the '+' register, send result to selection.
1415     // Also copy to the '*' register, in case auto-select is off.  But not when
1416     // 'clipboard' has "unnamedplus" and not "unnamed".
1417     if (clip_plus.available
1418 	    && (curr == &(y_regs[PLUS_REGISTER])
1419 		|| (!deleting && oap->regname == 0
1420 		  && ((clip_unnamed | clip_unnamed_saved) &
1421 							  CLIP_UNNAMED_PLUS))))
1422     {
1423 	if (curr != &(y_regs[PLUS_REGISTER]))
1424 	    // Copy the text from register 0 to the clipboard register.
1425 	    copy_yank_reg(&(y_regs[PLUS_REGISTER]));
1426 
1427 	clip_own_selection(&clip_plus);
1428 	clip_gen_set_selection(&clip_plus);
1429 	if (!clip_isautosel_star()
1430 		&& !clip_isautosel_plus()
1431 		&& !((clip_unnamed | clip_unnamed_saved) == CLIP_UNNAMED_PLUS)
1432 		&& !did_star
1433 		&& curr == &(y_regs[PLUS_REGISTER]))
1434 	{
1435 	    copy_yank_reg(&(y_regs[STAR_REGISTER]));
1436 	    clip_own_selection(&clip_star);
1437 	    clip_gen_set_selection(&clip_star);
1438 	}
1439     }
1440 # endif
1441 #endif
1442 
1443 #if defined(FEAT_EVAL)
1444     if (!deleting && has_textyankpost())
1445 	yank_do_autocmd(oap, y_current);
1446 #endif
1447 
1448     return OK;
1449 
1450 fail:		// free the allocated lines
1451     free_yank(y_idx + 1);
1452     y_current = curr;
1453     return FAIL;
1454 }
1455 
1456 /*
1457  * Copy a block range into a register.
1458  * If "exclude_trailing_space" is set, do not copy trailing whitespaces.
1459  */
1460     static int
yank_copy_line(struct block_def * bd,long y_idx,int exclude_trailing_space)1461 yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space)
1462 {
1463     char_u	*pnew;
1464 
1465     if (exclude_trailing_space)
1466 	bd->endspaces = 0;
1467     if ((pnew = alloc(bd->startspaces + bd->endspaces + bd->textlen + 1))
1468 								      == NULL)
1469 	return FAIL;
1470     y_current->y_array[y_idx] = pnew;
1471     vim_memset(pnew, ' ', (size_t)bd->startspaces);
1472     pnew += bd->startspaces;
1473     mch_memmove(pnew, bd->textstart, (size_t)bd->textlen);
1474     pnew += bd->textlen;
1475     vim_memset(pnew, ' ', (size_t)bd->endspaces);
1476     pnew += bd->endspaces;
1477     if (exclude_trailing_space)
1478     {
1479 	int s = bd->textlen + bd->endspaces;
1480 
1481 	while (VIM_ISWHITE(*(bd->textstart + s - 1)) && s > 0)
1482 	{
1483 	    s = s - (*mb_head_off)(bd->textstart, bd->textstart + s - 1) - 1;
1484 	    pnew--;
1485 	}
1486     }
1487     *pnew = NUL;
1488     return OK;
1489 }
1490 
1491 #ifdef FEAT_CLIPBOARD
1492 /*
1493  * Make a copy of the y_current register to register "reg".
1494  */
1495     static void
copy_yank_reg(yankreg_T * reg)1496 copy_yank_reg(yankreg_T *reg)
1497 {
1498     yankreg_T	*curr = y_current;
1499     long	j;
1500 
1501     y_current = reg;
1502     free_yank_all();
1503     *y_current = *curr;
1504     y_current->y_array = lalloc_clear(
1505 				    sizeof(char_u *) * y_current->y_size, TRUE);
1506     if (y_current->y_array == NULL)
1507 	y_current->y_size = 0;
1508     else
1509 	for (j = 0; j < y_current->y_size; ++j)
1510 	    if ((y_current->y_array[j] = vim_strsave(curr->y_array[j])) == NULL)
1511 	    {
1512 		free_yank(j);
1513 		y_current->y_size = 0;
1514 		break;
1515 	    }
1516     y_current = curr;
1517 }
1518 #endif
1519 
1520 /*
1521  * Put contents of register "regname" into the text.
1522  * Caller must check "regname" to be valid!
1523  * "flags": PUT_FIXINDENT	make indent look nice
1524  *	    PUT_CURSEND		leave cursor after end of new text
1525  *	    PUT_LINE		force linewise put (":put")
1526  *	    PUT_BLOCK_INNER     in block mode, do not add trailing spaces
1527  */
1528     void
do_put(int regname,char_u * expr_result,int dir,long count,int flags)1529 do_put(
1530     int		regname,
1531     char_u	*expr_result,	// result for regname "=" when compiled
1532     int		dir,		// BACKWARD for 'P', FORWARD for 'p'
1533     long	count,
1534     int		flags)
1535 {
1536     char_u	*ptr;
1537     char_u	*newp, *oldp;
1538     int		yanklen;
1539     int		totlen = 0;		// init for gcc
1540     linenr_T	lnum;
1541     colnr_T	col;
1542     long	i;			// index in y_array[]
1543     int		y_type;
1544     long	y_size;
1545     int		oldlen;
1546     long	y_width = 0;
1547     colnr_T	vcol;
1548     int		delcount;
1549     int		incr = 0;
1550     long	j;
1551     struct block_def bd;
1552     char_u	**y_array = NULL;
1553     long	nr_lines = 0;
1554     pos_T	new_cursor;
1555     int		indent;
1556     int		orig_indent = 0;	// init for gcc
1557     int		indent_diff = 0;	// init for gcc
1558     int		first_indent = TRUE;
1559     int		lendiff = 0;
1560     pos_T	old_pos;
1561     char_u	*insert_string = NULL;
1562     int		allocated = FALSE;
1563     long	cnt;
1564     pos_T	orig_start = curbuf->b_op_start;
1565     pos_T	orig_end = curbuf->b_op_end;
1566     unsigned int cur_ve_flags = get_ve_flags();
1567 
1568 #ifdef FEAT_CLIPBOARD
1569     // Adjust register name for "unnamed" in 'clipboard'.
1570     adjust_clip_reg(&regname);
1571     (void)may_get_selection(regname);
1572 #endif
1573 
1574     if (flags & PUT_FIXINDENT)
1575 	orig_indent = get_indent();
1576 
1577     curbuf->b_op_start = curwin->w_cursor;	// default for '[ mark
1578     curbuf->b_op_end = curwin->w_cursor;	// default for '] mark
1579 
1580     // Using inserted text works differently, because the register includes
1581     // special characters (newlines, etc.).
1582     if (regname == '.')
1583     {
1584 	if (VIsual_active)
1585 	    stuffcharReadbuff(VIsual_mode);
1586 	(void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') :
1587 				    (count == -1 ? 'O' : 'i')), count, FALSE);
1588 	// Putting the text is done later, so can't really move the cursor to
1589 	// the next character.  Use "l" to simulate it.
1590 	if ((flags & PUT_CURSEND) && gchar_cursor() != NUL)
1591 	    stuffcharReadbuff('l');
1592 	return;
1593     }
1594 
1595     // For special registers '%' (file name), '#' (alternate file name) and
1596     // ':' (last command line), etc. we have to create a fake yank register.
1597     // For compiled code "expr_result" holds the expression result.
1598     if (regname == '=' && expr_result != NULL)
1599 	insert_string = expr_result;
1600     else if (get_spec_reg(regname, &insert_string, &allocated, TRUE)
1601 		&& insert_string == NULL)
1602 	return;
1603 
1604     // Autocommands may be executed when saving lines for undo.  This might
1605     // make "y_array" invalid, so we start undo now to avoid that.
1606     if (u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1) == FAIL)
1607 	goto end;
1608 
1609     if (insert_string != NULL)
1610     {
1611 	y_type = MCHAR;
1612 #ifdef FEAT_EVAL
1613 	if (regname == '=')
1614 	{
1615 	    // For the = register we need to split the string at NL
1616 	    // characters.
1617 	    // Loop twice: count the number of lines and save them.
1618 	    for (;;)
1619 	    {
1620 		y_size = 0;
1621 		ptr = insert_string;
1622 		while (ptr != NULL)
1623 		{
1624 		    if (y_array != NULL)
1625 			y_array[y_size] = ptr;
1626 		    ++y_size;
1627 		    ptr = vim_strchr(ptr, '\n');
1628 		    if (ptr != NULL)
1629 		    {
1630 			if (y_array != NULL)
1631 			    *ptr = NUL;
1632 			++ptr;
1633 			// A trailing '\n' makes the register linewise.
1634 			if (*ptr == NUL)
1635 			{
1636 			    y_type = MLINE;
1637 			    break;
1638 			}
1639 		    }
1640 		}
1641 		if (y_array != NULL)
1642 		    break;
1643 		y_array = ALLOC_MULT(char_u *, y_size);
1644 		if (y_array == NULL)
1645 		    goto end;
1646 	    }
1647 	}
1648 	else
1649 #endif
1650 	{
1651 	    y_size = 1;		// use fake one-line yank register
1652 	    y_array = &insert_string;
1653 	}
1654     }
1655     else
1656     {
1657 	get_yank_register(regname, FALSE);
1658 
1659 	y_type = y_current->y_type;
1660 	y_width = y_current->y_width;
1661 	y_size = y_current->y_size;
1662 	y_array = y_current->y_array;
1663     }
1664 
1665     if (y_type == MLINE)
1666     {
1667 	if (flags & PUT_LINE_SPLIT)
1668 	{
1669 	    char_u *p;
1670 
1671 	    // "p" or "P" in Visual mode: split the lines to put the text in
1672 	    // between.
1673 	    if (u_save_cursor() == FAIL)
1674 		goto end;
1675 	    p = ml_get_cursor();
1676 	    if (dir == FORWARD && *p != NUL)
1677 		MB_PTR_ADV(p);
1678 	    ptr = vim_strsave(p);
1679 	    if (ptr == NULL)
1680 		goto end;
1681 	    ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, FALSE);
1682 	    vim_free(ptr);
1683 
1684 	    oldp = ml_get_curline();
1685 	    p = oldp + curwin->w_cursor.col;
1686 	    if (dir == FORWARD && *p != NUL)
1687 		MB_PTR_ADV(p);
1688 	    ptr = vim_strnsave(oldp, p - oldp);
1689 	    if (ptr == NULL)
1690 		goto end;
1691 	    ml_replace(curwin->w_cursor.lnum, ptr, FALSE);
1692 	    ++nr_lines;
1693 	    dir = FORWARD;
1694 	}
1695 	if (flags & PUT_LINE_FORWARD)
1696 	{
1697 	    // Must be "p" for a Visual block, put lines below the block.
1698 	    curwin->w_cursor = curbuf->b_visual.vi_end;
1699 	    dir = FORWARD;
1700 	}
1701 	curbuf->b_op_start = curwin->w_cursor;	// default for '[ mark
1702 	curbuf->b_op_end = curwin->w_cursor;	// default for '] mark
1703     }
1704 
1705     if (flags & PUT_LINE)	// :put command or "p" in Visual line mode.
1706 	y_type = MLINE;
1707 
1708     if (y_size == 0 || y_array == NULL)
1709     {
1710 	semsg(_("E353: Nothing in register %s"),
1711 		  regname == 0 ? (char_u *)"\"" : transchar(regname));
1712 	goto end;
1713     }
1714 
1715     if (y_type == MBLOCK)
1716     {
1717 	lnum = curwin->w_cursor.lnum + y_size + 1;
1718 	if (lnum > curbuf->b_ml.ml_line_count)
1719 	    lnum = curbuf->b_ml.ml_line_count + 1;
1720 	if (u_save(curwin->w_cursor.lnum - 1, lnum) == FAIL)
1721 	    goto end;
1722     }
1723     else if (y_type == MLINE)
1724     {
1725 	lnum = curwin->w_cursor.lnum;
1726 #ifdef FEAT_FOLDING
1727 	// Correct line number for closed fold.  Don't move the cursor yet,
1728 	// u_save() uses it.
1729 	if (dir == BACKWARD)
1730 	    (void)hasFolding(lnum, &lnum, NULL);
1731 	else
1732 	    (void)hasFolding(lnum, NULL, &lnum);
1733 #endif
1734 	if (dir == FORWARD)
1735 	    ++lnum;
1736 	// In an empty buffer the empty line is going to be replaced, include
1737 	// it in the saved lines.
1738 	if ((BUFEMPTY() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL)
1739 	    goto end;
1740 #ifdef FEAT_FOLDING
1741 	if (dir == FORWARD)
1742 	    curwin->w_cursor.lnum = lnum - 1;
1743 	else
1744 	    curwin->w_cursor.lnum = lnum;
1745 	curbuf->b_op_start = curwin->w_cursor;	// for mark_adjust()
1746 #endif
1747     }
1748     else if (u_save_cursor() == FAIL)
1749 	goto end;
1750 
1751     yanklen = (int)STRLEN(y_array[0]);
1752 
1753     if (cur_ve_flags == VE_ALL && y_type == MCHAR)
1754     {
1755 	if (gchar_cursor() == TAB)
1756 	{
1757 	    int viscol = getviscol();
1758 	    int ts = curbuf->b_p_ts;
1759 
1760 	    // Don't need to insert spaces when "p" on the last position of a
1761 	    // tab or "P" on the first position.
1762 	    if (dir == FORWARD ?
1763 #ifdef FEAT_VARTABS
1764 		    tabstop_padding(viscol, ts, curbuf->b_p_vts_array) != 1
1765 #else
1766 		    ts - (viscol % ts) != 1
1767 #endif
1768 		    : curwin->w_cursor.coladd > 0)
1769 		coladvance_force(viscol);
1770 	    else
1771 		curwin->w_cursor.coladd = 0;
1772 	}
1773 	else if (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL)
1774 	    coladvance_force(getviscol() + (dir == FORWARD));
1775     }
1776 
1777     lnum = curwin->w_cursor.lnum;
1778     col = curwin->w_cursor.col;
1779 
1780     // Block mode
1781     if (y_type == MBLOCK)
1782     {
1783 	int	c = gchar_cursor();
1784 	colnr_T	endcol2 = 0;
1785 
1786 	if (dir == FORWARD && c != NUL)
1787 	{
1788 	    if (cur_ve_flags == VE_ALL)
1789 		getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
1790 	    else
1791 		getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
1792 
1793 	    if (has_mbyte)
1794 		// move to start of next multi-byte character
1795 		curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
1796 	    else
1797 	    if (c != TAB || cur_ve_flags != VE_ALL)
1798 		++curwin->w_cursor.col;
1799 	    ++col;
1800 	}
1801 	else
1802 	    getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
1803 
1804 	col += curwin->w_cursor.coladd;
1805 	if (cur_ve_flags == VE_ALL
1806 		&& (curwin->w_cursor.coladd > 0
1807 		    || endcol2 == curwin->w_cursor.col))
1808 	{
1809 	    if (dir == FORWARD && c == NUL)
1810 		++col;
1811 	    if (dir != FORWARD && c != NUL && curwin->w_cursor.coladd > 0)
1812 		++curwin->w_cursor.col;
1813 	    if (c == TAB)
1814 	    {
1815 		if (dir == BACKWARD && curwin->w_cursor.col)
1816 		    curwin->w_cursor.col--;
1817 		if (dir == FORWARD && col - 1 == endcol2)
1818 		    curwin->w_cursor.col++;
1819 	    }
1820 	}
1821 	curwin->w_cursor.coladd = 0;
1822 	bd.textcol = 0;
1823 	for (i = 0; i < y_size; ++i)
1824 	{
1825 	    int spaces = 0;
1826 	    char shortline;
1827 
1828 	    bd.startspaces = 0;
1829 	    bd.endspaces = 0;
1830 	    vcol = 0;
1831 	    delcount = 0;
1832 
1833 	    // add a new line
1834 	    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
1835 	    {
1836 		if (ml_append(curbuf->b_ml.ml_line_count, (char_u *)"",
1837 						   (colnr_T)1, FALSE) == FAIL)
1838 		    break;
1839 		++nr_lines;
1840 	    }
1841 	    // get the old line and advance to the position to insert at
1842 	    oldp = ml_get_curline();
1843 	    oldlen = (int)STRLEN(oldp);
1844 	    for (ptr = oldp; vcol < col && *ptr; )
1845 	    {
1846 		// Count a tab for what it's worth (if list mode not on)
1847 		incr = lbr_chartabsize_adv(oldp, &ptr, (colnr_T)vcol);
1848 		vcol += incr;
1849 	    }
1850 	    bd.textcol = (colnr_T)(ptr - oldp);
1851 
1852 	    shortline = (vcol < col) || (vcol == col && !*ptr) ;
1853 
1854 	    if (vcol < col) // line too short, padd with spaces
1855 		bd.startspaces = col - vcol;
1856 	    else if (vcol > col)
1857 	    {
1858 		bd.endspaces = vcol - col;
1859 		bd.startspaces = incr - bd.endspaces;
1860 		--bd.textcol;
1861 		delcount = 1;
1862 		if (has_mbyte)
1863 		    bd.textcol -= (*mb_head_off)(oldp, oldp + bd.textcol);
1864 		if (oldp[bd.textcol] != TAB)
1865 		{
1866 		    // Only a Tab can be split into spaces.  Other
1867 		    // characters will have to be moved to after the
1868 		    // block, causing misalignment.
1869 		    delcount = 0;
1870 		    bd.endspaces = 0;
1871 		}
1872 	    }
1873 
1874 	    yanklen = (int)STRLEN(y_array[i]);
1875 
1876 	    if ((flags & PUT_BLOCK_INNER) == 0)
1877 	    {
1878 		// calculate number of spaces required to fill right side of
1879 		// block
1880 		spaces = y_width + 1;
1881 		for (j = 0; j < yanklen; j++)
1882 		    spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
1883 		if (spaces < 0)
1884 		    spaces = 0;
1885 	    }
1886 
1887 	    // Insert the new text.
1888 	    // First check for multiplication overflow.
1889 	    if (yanklen + spaces != 0
1890 		     && count > ((INT_MAX - (bd.startspaces + bd.endspaces))
1891 							/ (yanklen + spaces)))
1892 	    {
1893 		emsg(_(e_resulting_text_too_long));
1894 		break;
1895 	    }
1896 
1897 	    totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
1898 	    newp = alloc(totlen + oldlen + 1);
1899 	    if (newp == NULL)
1900 		break;
1901 
1902 	    // copy part up to cursor to new line
1903 	    ptr = newp;
1904 	    mch_memmove(ptr, oldp, (size_t)bd.textcol);
1905 	    ptr += bd.textcol;
1906 
1907 	    // may insert some spaces before the new text
1908 	    vim_memset(ptr, ' ', (size_t)bd.startspaces);
1909 	    ptr += bd.startspaces;
1910 
1911 	    // insert the new text
1912 	    for (j = 0; j < count; ++j)
1913 	    {
1914 		mch_memmove(ptr, y_array[i], (size_t)yanklen);
1915 		ptr += yanklen;
1916 
1917 		// insert block's trailing spaces only if there's text behind
1918 		if ((j < count - 1 || !shortline) && spaces)
1919 		{
1920 		    vim_memset(ptr, ' ', (size_t)spaces);
1921 		    ptr += spaces;
1922 		}
1923 	    }
1924 
1925 	    // may insert some spaces after the new text
1926 	    vim_memset(ptr, ' ', (size_t)bd.endspaces);
1927 	    ptr += bd.endspaces;
1928 
1929 	    // move the text after the cursor to the end of the line.
1930 	    mch_memmove(ptr, oldp + bd.textcol + delcount,
1931 				(size_t)(oldlen - bd.textcol - delcount + 1));
1932 	    ml_replace(curwin->w_cursor.lnum, newp, FALSE);
1933 
1934 	    ++curwin->w_cursor.lnum;
1935 	    if (i == 0)
1936 		curwin->w_cursor.col += bd.startspaces;
1937 	}
1938 
1939 	changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines);
1940 
1941 	// Set '[ mark.
1942 	curbuf->b_op_start = curwin->w_cursor;
1943 	curbuf->b_op_start.lnum = lnum;
1944 
1945 	// adjust '] mark
1946 	curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1;
1947 	curbuf->b_op_end.col = bd.textcol + totlen - 1;
1948 	curbuf->b_op_end.coladd = 0;
1949 	if (flags & PUT_CURSEND)
1950 	{
1951 	    colnr_T len;
1952 
1953 	    curwin->w_cursor = curbuf->b_op_end;
1954 	    curwin->w_cursor.col++;
1955 
1956 	    // in Insert mode we might be after the NUL, correct for that
1957 	    len = (colnr_T)STRLEN(ml_get_curline());
1958 	    if (curwin->w_cursor.col > len)
1959 		curwin->w_cursor.col = len;
1960 	}
1961 	else
1962 	    curwin->w_cursor.lnum = lnum;
1963     }
1964     else
1965     {
1966 	// Character or Line mode
1967 	if (y_type == MCHAR)
1968 	{
1969 	    // if type is MCHAR, FORWARD is the same as BACKWARD on the next
1970 	    // char
1971 	    if (dir == FORWARD && gchar_cursor() != NUL)
1972 	    {
1973 		if (has_mbyte)
1974 		{
1975 		    int bytelen = (*mb_ptr2len)(ml_get_cursor());
1976 
1977 		    // put it on the next of the multi-byte character.
1978 		    col += bytelen;
1979 		    if (yanklen)
1980 		    {
1981 			curwin->w_cursor.col += bytelen;
1982 			curbuf->b_op_end.col += bytelen;
1983 		    }
1984 		}
1985 		else
1986 		{
1987 		    ++col;
1988 		    if (yanklen)
1989 		    {
1990 			++curwin->w_cursor.col;
1991 			++curbuf->b_op_end.col;
1992 		    }
1993 		}
1994 	    }
1995 	    curbuf->b_op_start = curwin->w_cursor;
1996 	}
1997 	// Line mode: BACKWARD is the same as FORWARD on the previous line
1998 	else if (dir == BACKWARD)
1999 	    --lnum;
2000 	new_cursor = curwin->w_cursor;
2001 
2002 	// simple case: insert into one line at a time
2003 	if (y_type == MCHAR && y_size == 1)
2004 	{
2005 	    linenr_T	end_lnum = 0; // init for gcc
2006 	    linenr_T	start_lnum = lnum;
2007 
2008 	    if (VIsual_active)
2009 	    {
2010 		end_lnum = curbuf->b_visual.vi_end.lnum;
2011 		if (end_lnum < curbuf->b_visual.vi_start.lnum)
2012 		    end_lnum = curbuf->b_visual.vi_start.lnum;
2013 		if (end_lnum > start_lnum)
2014 		{
2015 		    pos_T   pos;
2016 
2017 		    // "col" is valid for the first line, in following lines
2018 		    // the virtual column needs to be used.  Matters for
2019 		    // multi-byte characters.
2020 		    pos.lnum = lnum;
2021 		    pos.col = col;
2022 		    pos.coladd = 0;
2023 		    getvcol(curwin, &pos, NULL, &vcol, NULL);
2024 		}
2025 	    }
2026 
2027 	    if (count == 0 || yanklen == 0)
2028 	    {
2029 		if (VIsual_active)
2030 		    lnum = end_lnum;
2031 	    }
2032 	    else if (count > INT_MAX / yanklen)
2033 		// multiplication overflow
2034 		emsg(_(e_resulting_text_too_long));
2035 	    else
2036 	    {
2037 		totlen = count * yanklen;
2038 		do {
2039 		    oldp = ml_get(lnum);
2040 		    oldlen = (int)STRLEN(oldp);
2041 		    if (lnum > start_lnum)
2042 		    {
2043 			pos_T   pos;
2044 
2045 			pos.lnum = lnum;
2046 			if (getvpos(&pos, vcol) == OK)
2047 			    col = pos.col;
2048 			else
2049 			    col = MAXCOL;
2050 		    }
2051 		    if (VIsual_active && col > oldlen)
2052 		    {
2053 			lnum++;
2054 			continue;
2055 		    }
2056 		    newp = alloc(totlen + oldlen + 1);
2057 		    if (newp == NULL)
2058 			goto end;	// alloc() gave an error message
2059 		    mch_memmove(newp, oldp, (size_t)col);
2060 		    ptr = newp + col;
2061 		    for (i = 0; i < count; ++i)
2062 		    {
2063 			mch_memmove(ptr, y_array[0], (size_t)yanklen);
2064 			ptr += yanklen;
2065 		    }
2066 		    STRMOVE(ptr, oldp + col);
2067 		    ml_replace(lnum, newp, FALSE);
2068 		    // Place cursor on last putted char.
2069 		    if (lnum == curwin->w_cursor.lnum)
2070 		    {
2071 			// make sure curwin->w_virtcol is updated
2072 			changed_cline_bef_curs();
2073 			curwin->w_cursor.col += (colnr_T)(totlen - 1);
2074 		    }
2075 		    if (VIsual_active)
2076 			lnum++;
2077 		} while (VIsual_active && lnum <= end_lnum);
2078 
2079 		if (VIsual_active) // reset lnum to the last visual line
2080 		    lnum--;
2081 	    }
2082 
2083 	    curbuf->b_op_end = curwin->w_cursor;
2084 	    // For "CTRL-O p" in Insert mode, put cursor after last char
2085 	    if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND)))
2086 		++curwin->w_cursor.col;
2087 	    changed_bytes(lnum, col);
2088 	}
2089 	else
2090 	{
2091 	    linenr_T	new_lnum = new_cursor.lnum;
2092 
2093 	    // Insert at least one line.  When y_type is MCHAR, break the first
2094 	    // line in two.
2095 	    for (cnt = 1; cnt <= count; ++cnt)
2096 	    {
2097 		i = 0;
2098 		if (y_type == MCHAR)
2099 		{
2100 		    // Split the current line in two at the insert position.
2101 		    // First insert y_array[size - 1] in front of second line.
2102 		    // Then append y_array[0] to first line.
2103 		    lnum = new_cursor.lnum;
2104 		    ptr = ml_get(lnum) + col;
2105 		    totlen = (int)STRLEN(y_array[y_size - 1]);
2106 		    newp = alloc(STRLEN(ptr) + totlen + 1);
2107 		    if (newp == NULL)
2108 			goto error;
2109 		    STRCPY(newp, y_array[y_size - 1]);
2110 		    STRCAT(newp, ptr);
2111 		    // insert second line
2112 		    ml_append(lnum, newp, (colnr_T)0, FALSE);
2113 		    ++new_lnum;
2114 		    vim_free(newp);
2115 
2116 		    oldp = ml_get(lnum);
2117 		    newp = alloc(col + yanklen + 1);
2118 		    if (newp == NULL)
2119 			goto error;
2120 					    // copy first part of line
2121 		    mch_memmove(newp, oldp, (size_t)col);
2122 					    // append to first line
2123 		    mch_memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
2124 		    ml_replace(lnum, newp, FALSE);
2125 
2126 		    curwin->w_cursor.lnum = lnum;
2127 		    i = 1;
2128 		}
2129 
2130 		for (; i < y_size; ++i)
2131 		{
2132 		    if (y_type != MCHAR || i < y_size - 1)
2133 		    {
2134 			if (ml_append(lnum, y_array[i], (colnr_T)0, FALSE)
2135 								      == FAIL)
2136 			    goto error;
2137 			new_lnum++;
2138 		    }
2139 		    lnum++;
2140 		    ++nr_lines;
2141 		    if (flags & PUT_FIXINDENT)
2142 		    {
2143 			old_pos = curwin->w_cursor;
2144 			curwin->w_cursor.lnum = lnum;
2145 			ptr = ml_get(lnum);
2146 			if (cnt == count && i == y_size - 1)
2147 			    lendiff = (int)STRLEN(ptr);
2148 #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
2149 			if (*ptr == '#' && preprocs_left())
2150 			    indent = 0;     // Leave # lines at start
2151 			else
2152 #endif
2153 			     if (*ptr == NUL)
2154 			    indent = 0;     // Ignore empty lines
2155 			else if (first_indent)
2156 			{
2157 			    indent_diff = orig_indent - get_indent();
2158 			    indent = orig_indent;
2159 			    first_indent = FALSE;
2160 			}
2161 			else if ((indent = get_indent() + indent_diff) < 0)
2162 			    indent = 0;
2163 			(void)set_indent(indent, 0);
2164 			curwin->w_cursor = old_pos;
2165 			// remember how many chars were removed
2166 			if (cnt == count && i == y_size - 1)
2167 			    lendiff -= (int)STRLEN(ml_get(lnum));
2168 		    }
2169 		}
2170 		if (cnt == 1)
2171 		    new_lnum = lnum;
2172 	    }
2173 
2174 error:
2175 	    // Adjust marks.
2176 	    if (y_type == MLINE)
2177 	    {
2178 		curbuf->b_op_start.col = 0;
2179 		if (dir == FORWARD)
2180 		    curbuf->b_op_start.lnum++;
2181 	    }
2182 	    // Skip mark_adjust when adding lines after the last one, there
2183 	    // can't be marks there. But still needed in diff mode.
2184 	    if (curbuf->b_op_start.lnum + (y_type == MCHAR) - 1 + nr_lines
2185 						 < curbuf->b_ml.ml_line_count
2186 #ifdef FEAT_DIFF
2187 						 || curwin->w_p_diff
2188 #endif
2189 						 )
2190 		mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR),
2191 					     (linenr_T)MAXLNUM, nr_lines, 0L);
2192 
2193 	    // note changed text for displaying and folding
2194 	    if (y_type == MCHAR)
2195 		changed_lines(curwin->w_cursor.lnum, col,
2196 					 curwin->w_cursor.lnum + 1, nr_lines);
2197 	    else
2198 		changed_lines(curbuf->b_op_start.lnum, 0,
2199 					   curbuf->b_op_start.lnum, nr_lines);
2200 
2201 	    // put '] mark at last inserted character
2202 	    curbuf->b_op_end.lnum = new_lnum;
2203 	    // correct length for change in indent
2204 	    col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
2205 	    if (col > 1)
2206 		curbuf->b_op_end.col = col - 1;
2207 	    else
2208 		curbuf->b_op_end.col = 0;
2209 
2210 	    if (flags & PUT_CURSLINE)
2211 	    {
2212 		// ":put": put cursor on last inserted line
2213 		curwin->w_cursor.lnum = lnum;
2214 		beginline(BL_WHITE | BL_FIX);
2215 	    }
2216 	    else if (flags & PUT_CURSEND)
2217 	    {
2218 		// put cursor after inserted text
2219 		if (y_type == MLINE)
2220 		{
2221 		    if (lnum >= curbuf->b_ml.ml_line_count)
2222 			curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
2223 		    else
2224 			curwin->w_cursor.lnum = lnum + 1;
2225 		    curwin->w_cursor.col = 0;
2226 		}
2227 		else
2228 		{
2229 		    curwin->w_cursor.lnum = new_lnum;
2230 		    curwin->w_cursor.col = col;
2231 		    curbuf->b_op_end = curwin->w_cursor;
2232 		    if (col > 1)
2233 			curbuf->b_op_end.col = col - 1;
2234 		}
2235 	    }
2236 	    else if (y_type == MLINE)
2237 	    {
2238 		// put cursor on first non-blank in first inserted line
2239 		curwin->w_cursor.col = 0;
2240 		if (dir == FORWARD)
2241 		    ++curwin->w_cursor.lnum;
2242 		beginline(BL_WHITE | BL_FIX);
2243 	    }
2244 	    else	// put cursor on first inserted character
2245 		curwin->w_cursor = new_cursor;
2246 	}
2247     }
2248 
2249     msgmore(nr_lines);
2250     curwin->w_set_curswant = TRUE;
2251 
2252 end:
2253     if (cmdmod.cmod_flags & CMOD_LOCKMARKS)
2254     {
2255 	curbuf->b_op_start = orig_start;
2256 	curbuf->b_op_end = orig_end;
2257     }
2258     if (allocated)
2259 	vim_free(insert_string);
2260     if (regname == '=')
2261 	vim_free(y_array);
2262 
2263     VIsual_active = FALSE;
2264 
2265     // If the cursor is past the end of the line put it at the end.
2266     adjust_cursor_eol();
2267 }
2268 
2269 /*
2270  * Return the character name of the register with the given number.
2271  */
2272     int
get_register_name(int num)2273 get_register_name(int num)
2274 {
2275     if (num == -1)
2276 	return '"';
2277     else if (num < 10)
2278 	return num + '0';
2279     else if (num == DELETION_REGISTER)
2280 	return '-';
2281 #ifdef FEAT_CLIPBOARD
2282     else if (num == STAR_REGISTER)
2283 	return '*';
2284     else if (num == PLUS_REGISTER)
2285 	return '+';
2286 #endif
2287     else
2288     {
2289 #ifdef EBCDIC
2290 	int i;
2291 
2292 	// EBCDIC is really braindead ...
2293 	i = 'a' + (num - 10);
2294 	if (i > 'i')
2295 	    i += 7;
2296 	if (i > 'r')
2297 	    i += 8;
2298 	return i;
2299 #else
2300 	return num + 'a' - 10;
2301 #endif
2302     }
2303 }
2304 
2305 /*
2306  * Return the index of the register "" points to.
2307  */
2308     int
get_unname_register()2309 get_unname_register()
2310 {
2311     return y_previous == NULL ? -1 : y_previous - &y_regs[0];
2312 }
2313 
2314 /*
2315  * ":dis" and ":registers": Display the contents of the yank registers.
2316  */
2317     void
ex_display(exarg_T * eap)2318 ex_display(exarg_T *eap)
2319 {
2320     int		i, n;
2321     long	j;
2322     char_u	*p;
2323     yankreg_T	*yb;
2324     int		name;
2325     int		attr;
2326     char_u	*arg = eap->arg;
2327     int		clen;
2328     int		type;
2329 
2330     if (arg != NULL && *arg == NUL)
2331 	arg = NULL;
2332     attr = HL_ATTR(HLF_8);
2333 
2334     // Highlight title
2335     msg_puts_title(_("\nType Name Content"));
2336     for (i = -1; i < NUM_REGISTERS && !got_int; ++i)
2337     {
2338 	name = get_register_name(i);
2339 	switch (get_reg_type(name, NULL))
2340 	{
2341 	    case MLINE: type = 'l'; break;
2342 	    case MCHAR: type = 'c'; break;
2343 	    default:	type = 'b'; break;
2344 	}
2345 	if (arg != NULL && vim_strchr(arg, name) == NULL
2346 #ifdef ONE_CLIPBOARD
2347 	    // Star register and plus register contain the same thing.
2348 		&& (name != '*' || vim_strchr(arg, '+') == NULL)
2349 #endif
2350 		)
2351 	    continue;	    // did not ask for this register
2352 
2353 #ifdef FEAT_CLIPBOARD
2354 	// Adjust register name for "unnamed" in 'clipboard'.
2355 	// When it's a clipboard register, fill it with the current contents
2356 	// of the clipboard.
2357 	adjust_clip_reg(&name);
2358 	(void)may_get_selection(name);
2359 #endif
2360 
2361 	if (i == -1)
2362 	{
2363 	    if (y_previous != NULL)
2364 		yb = y_previous;
2365 	    else
2366 		yb = &(y_regs[0]);
2367 	}
2368 	else
2369 	    yb = &(y_regs[i]);
2370 
2371 #ifdef FEAT_EVAL
2372 	if (name == MB_TOLOWER(redir_reg)
2373 		|| (redir_reg == '"' && yb == y_previous))
2374 	    continue;	    // do not list register being written to, the
2375 			    // pointer can be freed
2376 #endif
2377 
2378 	if (yb->y_array != NULL)
2379 	{
2380 	    int do_show = FALSE;
2381 
2382 	    for (j = 0; !do_show && j < yb->y_size; ++j)
2383 		do_show = !message_filtered(yb->y_array[j]);
2384 
2385 	    if (do_show || yb->y_size == 0)
2386 	    {
2387 		msg_putchar('\n');
2388 		msg_puts("  ");
2389 		msg_putchar(type);
2390 		msg_puts("  ");
2391 		msg_putchar('"');
2392 		msg_putchar(name);
2393 		msg_puts("   ");
2394 
2395 		n = (int)Columns - 11;
2396 		for (j = 0; j < yb->y_size && n > 1; ++j)
2397 		{
2398 		    if (j)
2399 		    {
2400 			msg_puts_attr("^J", attr);
2401 			n -= 2;
2402 		    }
2403 		    for (p = yb->y_array[j]; *p && (n -= ptr2cells(p)) >= 0;
2404 									   ++p)
2405 		    {
2406 			clen = (*mb_ptr2len)(p);
2407 			msg_outtrans_len(p, clen);
2408 			p += clen - 1;
2409 		    }
2410 		}
2411 		if (n > 1 && yb->y_type == MLINE)
2412 		    msg_puts_attr("^J", attr);
2413 		out_flush();		    // show one line at a time
2414 	    }
2415 	    ui_breakcheck();
2416 	}
2417     }
2418 
2419     // display last inserted text
2420     if ((p = get_last_insert()) != NULL
2421 		  && (arg == NULL || vim_strchr(arg, '.') != NULL) && !got_int
2422 						      && !message_filtered(p))
2423     {
2424 	msg_puts("\n  c  \".   ");
2425 	dis_msg(p, TRUE);
2426     }
2427 
2428     // display last command line
2429     if (last_cmdline != NULL && (arg == NULL || vim_strchr(arg, ':') != NULL)
2430 			       && !got_int && !message_filtered(last_cmdline))
2431     {
2432 	msg_puts("\n  c  \":   ");
2433 	dis_msg(last_cmdline, FALSE);
2434     }
2435 
2436     // display current file name
2437     if (curbuf->b_fname != NULL
2438 	    && (arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int
2439 					&& !message_filtered(curbuf->b_fname))
2440     {
2441 	msg_puts("\n  c  \"%   ");
2442 	dis_msg(curbuf->b_fname, FALSE);
2443     }
2444 
2445     // display alternate file name
2446     if ((arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int)
2447     {
2448 	char_u	    *fname;
2449 	linenr_T    dummy;
2450 
2451 	if (buflist_name_nr(0, &fname, &dummy) != FAIL
2452 						  && !message_filtered(fname))
2453 	{
2454 	    msg_puts("\n  c  \"#   ");
2455 	    dis_msg(fname, FALSE);
2456 	}
2457     }
2458 
2459     // display last search pattern
2460     if (last_search_pat() != NULL
2461 		 && (arg == NULL || vim_strchr(arg, '/') != NULL) && !got_int
2462 				      && !message_filtered(last_search_pat()))
2463     {
2464 	msg_puts("\n  c  \"/   ");
2465 	dis_msg(last_search_pat(), FALSE);
2466     }
2467 
2468 #ifdef FEAT_EVAL
2469     // display last used expression
2470     if (expr_line != NULL && (arg == NULL || vim_strchr(arg, '=') != NULL)
2471 				  && !got_int && !message_filtered(expr_line))
2472     {
2473 	msg_puts("\n  c  \"=   ");
2474 	dis_msg(expr_line, FALSE);
2475     }
2476 #endif
2477 }
2478 
2479 /*
2480  * display a string for do_dis()
2481  * truncate at end of screen line
2482  */
2483     static void
dis_msg(char_u * p,int skip_esc)2484 dis_msg(
2485     char_u	*p,
2486     int		skip_esc)	    // if TRUE, ignore trailing ESC
2487 {
2488     int		n;
2489     int		l;
2490 
2491     n = (int)Columns - 6;
2492     while (*p != NUL
2493 	    && !(*p == ESC && skip_esc && *(p + 1) == NUL)
2494 	    && (n -= ptr2cells(p)) >= 0)
2495     {
2496 	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
2497 	{
2498 	    msg_outtrans_len(p, l);
2499 	    p += l;
2500 	}
2501 	else
2502 	    msg_outtrans_len(p++, 1);
2503     }
2504     ui_breakcheck();
2505 }
2506 
2507 #if defined(FEAT_DND) || defined(PROTO)
2508 /*
2509  * Replace the contents of the '~' register with str.
2510  */
2511     void
dnd_yank_drag_data(char_u * str,long len)2512 dnd_yank_drag_data(char_u *str, long len)
2513 {
2514     yankreg_T *curr;
2515 
2516     curr = y_current;
2517     y_current = &y_regs[TILDE_REGISTER];
2518     free_yank_all();
2519     str_to_reg(y_current, MCHAR, str, len, 0L, FALSE);
2520     y_current = curr;
2521 }
2522 #endif
2523 
2524 
2525 /*
2526  * Return the type of a register.
2527  * Used for getregtype()
2528  * Returns MAUTO for error.
2529  */
2530     char_u
get_reg_type(int regname,long * reglen)2531 get_reg_type(int regname, long *reglen)
2532 {
2533     switch (regname)
2534     {
2535 	case '%':		// file name
2536 	case '#':		// alternate file name
2537 	case '=':		// expression
2538 	case ':':		// last command line
2539 	case '/':		// last search-pattern
2540 	case '.':		// last inserted text
2541 # ifdef FEAT_SEARCHPATH
2542 	case Ctrl_F:		// Filename under cursor
2543 	case Ctrl_P:		// Path under cursor, expand via "path"
2544 # endif
2545 	case Ctrl_W:		// word under cursor
2546 	case Ctrl_A:		// WORD (mnemonic All) under cursor
2547 	case '_':		// black hole: always empty
2548 	    return MCHAR;
2549     }
2550 
2551 # ifdef FEAT_CLIPBOARD
2552     regname = may_get_selection(regname);
2553 # endif
2554 
2555     if (regname != NUL && !valid_yank_reg(regname, FALSE))
2556 	return MAUTO;
2557 
2558     get_yank_register(regname, FALSE);
2559 
2560     if (y_current->y_array != NULL)
2561     {
2562 	if (reglen != NULL && y_current->y_type == MBLOCK)
2563 	    *reglen = y_current->y_width;
2564 	return y_current->y_type;
2565     }
2566     return MAUTO;
2567 }
2568 
2569 #if defined(FEAT_EVAL) || defined(PROTO)
2570 /*
2571  * When "flags" has GREG_LIST return a list with text "s".
2572  * Otherwise just return "s".
2573  */
2574     static char_u *
getreg_wrap_one_line(char_u * s,int flags)2575 getreg_wrap_one_line(char_u *s, int flags)
2576 {
2577     if (flags & GREG_LIST)
2578     {
2579 	list_T *list = list_alloc();
2580 
2581 	if (list != NULL)
2582 	{
2583 	    if (list_append_string(list, NULL, -1) == FAIL)
2584 	    {
2585 		list_free(list);
2586 		return NULL;
2587 	    }
2588 	    list->lv_first->li_tv.vval.v_string = s;
2589 	}
2590 	return (char_u *)list;
2591     }
2592     return s;
2593 }
2594 
2595 /*
2596  * Return the contents of a register as a single allocated string or as a list.
2597  * Used for "@r" in expressions and for getreg().
2598  * Returns NULL for error.
2599  * Flags:
2600  *	GREG_NO_EXPR	Do not allow expression register
2601  *	GREG_EXPR_SRC	For the expression register: return expression itself,
2602  *			not the result of its evaluation.
2603  *	GREG_LIST	Return a list of lines instead of a single string.
2604  */
2605     char_u *
get_reg_contents(int regname,int flags)2606 get_reg_contents(int regname, int flags)
2607 {
2608     long	i;
2609     char_u	*retval;
2610     int		allocated;
2611     long	len;
2612 
2613     // Don't allow using an expression register inside an expression
2614     if (regname == '=')
2615     {
2616 	if (flags & GREG_NO_EXPR)
2617 	    return NULL;
2618 	if (flags & GREG_EXPR_SRC)
2619 	    return getreg_wrap_one_line(get_expr_line_src(), flags);
2620 	return getreg_wrap_one_line(get_expr_line(), flags);
2621     }
2622 
2623     if (regname == '@')	    // "@@" is used for unnamed register
2624 	regname = '"';
2625 
2626     // check for valid regname
2627     if (regname != NUL && !valid_yank_reg(regname, FALSE))
2628 	return NULL;
2629 
2630 # ifdef FEAT_CLIPBOARD
2631     regname = may_get_selection(regname);
2632 # endif
2633 
2634     if (get_spec_reg(regname, &retval, &allocated, FALSE))
2635     {
2636 	if (retval == NULL)
2637 	    return NULL;
2638 	if (allocated)
2639 	    return getreg_wrap_one_line(retval, flags);
2640 	return getreg_wrap_one_line(vim_strsave(retval), flags);
2641     }
2642 
2643     get_yank_register(regname, FALSE);
2644     if (y_current->y_array == NULL)
2645 	return NULL;
2646 
2647     if (flags & GREG_LIST)
2648     {
2649 	list_T	*list = list_alloc();
2650 	int	error = FALSE;
2651 
2652 	if (list == NULL)
2653 	    return NULL;
2654 	for (i = 0; i < y_current->y_size; ++i)
2655 	    if (list_append_string(list, y_current->y_array[i], -1) == FAIL)
2656 		error = TRUE;
2657 	if (error)
2658 	{
2659 	    list_free(list);
2660 	    return NULL;
2661 	}
2662 	return (char_u *)list;
2663     }
2664 
2665     // Compute length of resulting string.
2666     len = 0;
2667     for (i = 0; i < y_current->y_size; ++i)
2668     {
2669 	len += (long)STRLEN(y_current->y_array[i]);
2670 	// Insert a newline between lines and after last line if
2671 	// y_type is MLINE.
2672 	if (y_current->y_type == MLINE || i < y_current->y_size - 1)
2673 	    ++len;
2674     }
2675 
2676     retval = alloc(len + 1);
2677 
2678     // Copy the lines of the yank register into the string.
2679     if (retval != NULL)
2680     {
2681 	len = 0;
2682 	for (i = 0; i < y_current->y_size; ++i)
2683 	{
2684 	    STRCPY(retval + len, y_current->y_array[i]);
2685 	    len += (long)STRLEN(retval + len);
2686 
2687 	    // Insert a NL between lines and after the last line if y_type is
2688 	    // MLINE.
2689 	    if (y_current->y_type == MLINE || i < y_current->y_size - 1)
2690 		retval[len++] = '\n';
2691 	}
2692 	retval[len] = NUL;
2693     }
2694 
2695     return retval;
2696 }
2697 
2698     static int
init_write_reg(int name,yankreg_T ** old_y_previous,yankreg_T ** old_y_current,int must_append,int * yank_type UNUSED)2699 init_write_reg(
2700     int		name,
2701     yankreg_T	**old_y_previous,
2702     yankreg_T	**old_y_current,
2703     int		must_append,
2704     int		*yank_type UNUSED)
2705 {
2706     if (!valid_yank_reg(name, TRUE))	    // check for valid reg name
2707     {
2708 	emsg_invreg(name);
2709 	return FAIL;
2710     }
2711 
2712     // Don't want to change the current (unnamed) register
2713     *old_y_previous = y_previous;
2714     *old_y_current = y_current;
2715 
2716     get_yank_register(name, TRUE);
2717     if (!y_append && !must_append)
2718 	free_yank_all();
2719     return OK;
2720 }
2721 
2722     static void
finish_write_reg(int name,yankreg_T * old_y_previous,yankreg_T * old_y_current)2723 finish_write_reg(
2724     int		name,
2725     yankreg_T	*old_y_previous,
2726     yankreg_T	*old_y_current)
2727 {
2728 # ifdef FEAT_CLIPBOARD
2729     // Send text of clipboard register to the clipboard.
2730     may_set_selection();
2731 # endif
2732 
2733     // ':let @" = "val"' should change the meaning of the "" register
2734     if (name != '"')
2735 	y_previous = old_y_previous;
2736     y_current = old_y_current;
2737 }
2738 
2739 /*
2740  * Store string "str" in register "name".
2741  * "maxlen" is the maximum number of bytes to use, -1 for all bytes.
2742  * If "must_append" is TRUE, always append to the register.  Otherwise append
2743  * if "name" is an uppercase letter.
2744  * Note: "maxlen" and "must_append" don't work for the "/" register.
2745  * Careful: 'str' is modified, you may have to use a copy!
2746  * If "str" ends in '\n' or '\r', use linewise, otherwise use characterwise.
2747  */
2748     void
write_reg_contents(int name,char_u * str,int maxlen,int must_append)2749 write_reg_contents(
2750     int		name,
2751     char_u	*str,
2752     int		maxlen,
2753     int		must_append)
2754 {
2755     write_reg_contents_ex(name, str, maxlen, must_append, MAUTO, 0L);
2756 }
2757 
2758     void
write_reg_contents_lst(int name,char_u ** strings,int maxlen UNUSED,int must_append,int yank_type,long block_len)2759 write_reg_contents_lst(
2760     int		name,
2761     char_u	**strings,
2762     int		maxlen UNUSED,
2763     int		must_append,
2764     int		yank_type,
2765     long	block_len)
2766 {
2767     yankreg_T  *old_y_previous, *old_y_current;
2768 
2769     if (name == '/' || name == '=')
2770     {
2771 	char_u	*s;
2772 
2773 	if (strings[0] == NULL)
2774 	    s = (char_u *)"";
2775 	else if (strings[1] != NULL)
2776 	{
2777 	    emsg(_("E883: search pattern and expression register may not "
2778 			"contain two or more lines"));
2779 	    return;
2780 	}
2781 	else
2782 	    s = strings[0];
2783 	write_reg_contents_ex(name, s, -1, must_append, yank_type, block_len);
2784 	return;
2785     }
2786 
2787     if (name == '_')	    // black hole: nothing to do
2788 	return;
2789 
2790     if (init_write_reg(name, &old_y_previous, &old_y_current, must_append,
2791 		&yank_type) == FAIL)
2792 	return;
2793 
2794     str_to_reg(y_current, yank_type, (char_u *)strings, -1, block_len, TRUE);
2795 
2796     finish_write_reg(name, old_y_previous, old_y_current);
2797 }
2798 
2799     void
write_reg_contents_ex(int name,char_u * str,int maxlen,int must_append,int yank_type,long block_len)2800 write_reg_contents_ex(
2801     int		name,
2802     char_u	*str,
2803     int		maxlen,
2804     int		must_append,
2805     int		yank_type,
2806     long	block_len)
2807 {
2808     yankreg_T	*old_y_previous, *old_y_current;
2809     long	len;
2810 
2811     if (maxlen >= 0)
2812 	len = maxlen;
2813     else
2814 	len = (long)STRLEN(str);
2815 
2816     // Special case: '/' search pattern
2817     if (name == '/')
2818     {
2819 	set_last_search_pat(str, RE_SEARCH, TRUE, TRUE);
2820 	return;
2821     }
2822 
2823     if (name == '#')
2824     {
2825 	buf_T	*buf;
2826 
2827 	if (VIM_ISDIGIT(*str))
2828 	{
2829 	    int	num = atoi((char *)str);
2830 
2831 	    buf = buflist_findnr(num);
2832 	    if (buf == NULL)
2833 		semsg(_(e_nobufnr), (long)num);
2834 	}
2835 	else
2836 	    buf = buflist_findnr(buflist_findpat(str, str + STRLEN(str),
2837 							 TRUE, FALSE, FALSE));
2838 	if (buf == NULL)
2839 	    return;
2840 	curwin->w_alt_fnum = buf->b_fnum;
2841 	return;
2842     }
2843 
2844     if (name == '=')
2845     {
2846 	char_u	    *p, *s;
2847 
2848 	p = vim_strnsave(str, len);
2849 	if (p == NULL)
2850 	    return;
2851 	if (must_append && expr_line != NULL)
2852 	{
2853 	    s = concat_str(expr_line, p);
2854 	    vim_free(p);
2855 	    p = s;
2856 	}
2857 	set_expr_line(p, NULL);
2858 	return;
2859     }
2860 
2861     if (name == '_')	    // black hole: nothing to do
2862 	return;
2863 
2864     if (init_write_reg(name, &old_y_previous, &old_y_current, must_append,
2865 		&yank_type) == FAIL)
2866 	return;
2867 
2868     str_to_reg(y_current, yank_type, str, len, block_len, FALSE);
2869 
2870     finish_write_reg(name, old_y_previous, old_y_current);
2871 }
2872 #endif	// FEAT_EVAL
2873 
2874 #if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
2875 /*
2876  * Put a string into a register.  When the register is not empty, the string
2877  * is appended.
2878  */
2879     void
str_to_reg(yankreg_T * y_ptr,int yank_type,char_u * str,long len,long blocklen,int str_list)2880 str_to_reg(
2881     yankreg_T	*y_ptr,		// pointer to yank register
2882     int		yank_type,	// MCHAR, MLINE, MBLOCK, MAUTO
2883     char_u	*str,		// string to put in register
2884     long	len,		// length of string
2885     long	blocklen,	// width of Visual block
2886     int		str_list)	// TRUE if str is char_u **
2887 {
2888     int		type;			// MCHAR, MLINE or MBLOCK
2889     int		lnum;
2890     long	start;
2891     long	i;
2892     int		extra;
2893     int		newlines;		// number of lines added
2894     int		extraline = 0;		// extra line at the end
2895     int		append = FALSE;		// append to last line in register
2896     char_u	*s;
2897     char_u	**ss;
2898     char_u	**pp;
2899     long	maxlen;
2900 
2901     if (y_ptr->y_array == NULL)		// NULL means empty register
2902 	y_ptr->y_size = 0;
2903 
2904     if (yank_type == MAUTO)
2905 	type = ((str_list || (len > 0 && (str[len - 1] == NL
2906 					    || str[len - 1] == CAR)))
2907 							     ? MLINE : MCHAR);
2908     else
2909 	type = yank_type;
2910 
2911     // Count the number of lines within the string
2912     newlines = 0;
2913     if (str_list)
2914     {
2915 	for (ss = (char_u **) str; *ss != NULL; ++ss)
2916 	    ++newlines;
2917     }
2918     else
2919     {
2920 	for (i = 0; i < len; i++)
2921 	    if (str[i] == '\n')
2922 		++newlines;
2923 	if (type == MCHAR || len == 0 || str[len - 1] != '\n')
2924 	{
2925 	    extraline = 1;
2926 	    ++newlines;	// count extra newline at the end
2927 	}
2928 	if (y_ptr->y_size > 0 && y_ptr->y_type == MCHAR)
2929 	{
2930 	    append = TRUE;
2931 	    --newlines;	// uncount newline when appending first line
2932 	}
2933     }
2934 
2935     // Without any lines make the register empty.
2936     if (y_ptr->y_size + newlines == 0)
2937     {
2938 	VIM_CLEAR(y_ptr->y_array);
2939 	return;
2940     }
2941 
2942     // Allocate an array to hold the pointers to the new register lines.
2943     // If the register was not empty, move the existing lines to the new array.
2944     pp = lalloc_clear((y_ptr->y_size + newlines) * sizeof(char_u *), TRUE);
2945     if (pp == NULL)	// out of memory
2946 	return;
2947     for (lnum = 0; lnum < y_ptr->y_size; ++lnum)
2948 	pp[lnum] = y_ptr->y_array[lnum];
2949     vim_free(y_ptr->y_array);
2950     y_ptr->y_array = pp;
2951     maxlen = 0;
2952 
2953     // Find the end of each line and save it into the array.
2954     if (str_list)
2955     {
2956 	for (ss = (char_u **) str; *ss != NULL; ++ss, ++lnum)
2957 	{
2958 	    pp[lnum] = vim_strsave(*ss);
2959 	    if (type == MBLOCK)
2960 	    {
2961 		int charlen = mb_string2cells(*ss, -1);
2962 
2963 		if (charlen > maxlen)
2964 		    maxlen = charlen;
2965 	    }
2966 	}
2967     }
2968     else
2969     {
2970 	for (start = 0; start < len + extraline; start += i + 1)
2971 	{
2972 	    int charlen = 0;
2973 
2974 	    for (i = start; i < len; ++i)	// find the end of the line
2975 	    {
2976 		if (str[i] == '\n')
2977 		    break;
2978 		if (type == MBLOCK)
2979 		    charlen += mb_ptr2cells_len(str + i, len - i);
2980 	    }
2981 	    i -= start;			// i is now length of line
2982 	    if (charlen > maxlen)
2983 		maxlen = charlen;
2984 	    if (append)
2985 	    {
2986 		--lnum;
2987 		extra = (int)STRLEN(y_ptr->y_array[lnum]);
2988 	    }
2989 	    else
2990 		extra = 0;
2991 	    s = alloc(i + extra + 1);
2992 	    if (s == NULL)
2993 		break;
2994 	    if (extra)
2995 		mch_memmove(s, y_ptr->y_array[lnum], (size_t)extra);
2996 	    if (append)
2997 		vim_free(y_ptr->y_array[lnum]);
2998 	    if (i > 0)
2999 		mch_memmove(s + extra, str + start, (size_t)i);
3000 	    extra += i;
3001 	    s[extra] = NUL;
3002 	    y_ptr->y_array[lnum++] = s;
3003 	    while (--extra >= 0)
3004 	    {
3005 		if (*s == NUL)
3006 		    *s = '\n';	    // replace NUL with newline
3007 		++s;
3008 	    }
3009 	    append = FALSE;		    // only first line is appended
3010 	}
3011     }
3012     y_ptr->y_type = type;
3013     y_ptr->y_size = lnum;
3014     if (type == MBLOCK)
3015 	y_ptr->y_width = (blocklen < 0 ? maxlen - 1 : blocklen);
3016     else
3017 	y_ptr->y_width = 0;
3018 # ifdef FEAT_VIMINFO
3019     y_ptr->y_time_set = vim_time();
3020 # endif
3021 }
3022 #endif // FEAT_CLIPBOARD || FEAT_EVAL || PROTO
3023