comparison src/register.c @ 20891:4bdc07beeadb v8.2.0997

patch 8.2.0997: cannot execute a register containing line continuation Commit: https://github.com/vim/vim/commit/856c1110c1cf0d6e44e387b70732ca4b4c8ef0f2 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jun 17 21:47:23 2020 +0200 patch 8.2.0997: cannot execute a register containing line continuation Problem: Cannot execute a register containing line continuation. Solution: Concatenate lines where needed. (Yegappan Lakshmanan, closes #6272)
author Bram Moolenaar <Bram@vim.org>
date Wed, 17 Jun 2020 22:00:05 +0200
parents 9064044fd4f6
children 3af71cbcfdbe
comparison
equal deleted inserted replaced
20890:2ac788c89015 20891:4bdc07beeadb
472 { 472 {
473 execreg_lastc = lastc; 473 execreg_lastc = lastc;
474 } 474 }
475 475
476 /* 476 /*
477 * When executing a register as a series of ex-commands, if the
478 * line-continuation character is used for a line, then join it with one or
479 * more previous lines. Note that lines are processed backwards starting from
480 * the last line in the register.
481 *
482 * Arguments:
483 * lines - list of lines in the register
484 * idx - index of the line starting with \ or "\. Join this line with all the
485 * immediate predecessor lines that start with a \ and the first line
486 * that doesn't start with a \. Lines that start with a comment "\
487 * character are ignored.
488 *
489 * Returns the concatenated line. The index of the line that should be
490 * processed next is returned in idx.
491 */
492 static char_u *
493 execreg_line_continuation(char_u **lines, long *idx)
494 {
495 garray_T ga;
496 long i = *idx;
497 char_u *p;
498 int cmd_start;
499 int cmd_end = i;
500 int j;
501 char_u *str;
502
503 ga_init2(&ga, (int)sizeof(char_u), 400);
504
505 // search backwards to find the first line of this command.
506 // Any line not starting with \ or "\ is the start of the
507 // command.
508 while (--i > 0)
509 {
510 p = skipwhite(lines[i]);
511 if (*p != '\\' && (p[0] != '"' || p[1] != '\\' || p[2] != ' '))
512 break;
513 }
514 cmd_start = i;
515
516 // join all the lines
517 ga_concat(&ga, lines[cmd_start]);
518 for (j = cmd_start + 1; j <= cmd_end; j++)
519 {
520 p = skipwhite(lines[j]);
521 if (*p == '\\')
522 {
523 // Adjust the growsize to the current length to
524 // speed up concatenating many lines.
525 if (ga.ga_len > 400)
526 {
527 if (ga.ga_len > 8000)
528 ga.ga_growsize = 8000;
529 else
530 ga.ga_growsize = ga.ga_len;
531 }
532 ga_concat(&ga, p + 1);
533 }
534 }
535 ga_append(&ga, NUL);
536 str = vim_strsave(ga.ga_data);
537 ga_clear(&ga);
538
539 *idx = i;
540 return str;
541 }
542
543 /*
477 * Execute a yank register: copy it into the stuff buffer. 544 * Execute a yank register: copy it into the stuff buffer.
478 * 545 *
479 * Return FAIL for failure, OK otherwise. 546 * Return FAIL for failure, OK otherwise.
480 */ 547 */
481 int 548 int
577 // Insert lines into typeahead buffer, from last one to first one. 644 // Insert lines into typeahead buffer, from last one to first one.
578 put_reedit_in_typebuf(silent); 645 put_reedit_in_typebuf(silent);
579 for (i = y_current->y_size; --i >= 0; ) 646 for (i = y_current->y_size; --i >= 0; )
580 { 647 {
581 char_u *escaped; 648 char_u *escaped;
649 char_u *str;
650 int free_str = FALSE;
582 651
583 // insert NL between lines and after last line if type is MLINE 652 // 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 653 if (y_current->y_type == MLINE || i < y_current->y_size - 1
585 || addcr) 654 || addcr)
586 { 655 {
587 if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL) 656 if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL)
588 return FAIL; 657 return FAIL;
589 } 658 }
590 escaped = vim_strsave_escape_csi(y_current->y_array[i]); 659
660 // Handle line-continuation for :@<register>
661 str = y_current->y_array[i];
662 if (colon && i > 0)
663 {
664 p = skipwhite(str);
665 if (*p == '\\' || (p[0] == '"' && p[1] == '\\' && p[2] == ' '))
666 {
667 str = execreg_line_continuation(y_current->y_array, &i);
668 if (str == NULL)
669 return FAIL;
670 free_str = TRUE;
671 }
672 }
673 escaped = vim_strsave_escape_csi(str);
674 if (free_str)
675 vim_free(str);
591 if (escaped == NULL) 676 if (escaped == NULL)
592 return FAIL; 677 return FAIL;
593 retval = ins_typebuf(escaped, remap, 0, TRUE, silent); 678 retval = ins_typebuf(escaped, remap, 0, TRUE, silent);
594 vim_free(escaped); 679 vim_free(escaped);
595 if (retval == FAIL) 680 if (retval == FAIL)