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