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