Mercurial > vim
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) |