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