Mercurial > vim
comparison src/ex_cmds.c @ 9272:f5d9eb512f8b v7.4.1919
commit https://github.com/vim/vim/commit/46bbb0c4ba27395859dfeaa26938483946bb4ec2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 11 21:04:39 2016 +0200
patch 7.4.1919
Problem: Register contents is not merged when writing viminfo.
Solution: Use timestamps for register contents.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 11 Jun 2016 21:15:05 +0200 |
parents | 79cb08f0d812 |
children | fd81f36cd5b6 |
comparison
equal
deleted
inserted
replaced
9271:d10d373d488e | 9272:f5d9eb512f8b |
---|---|
1748 } | 1748 } |
1749 | 1749 |
1750 #if defined(FEAT_VIMINFO) || defined(PROTO) | 1750 #if defined(FEAT_VIMINFO) || defined(PROTO) |
1751 | 1751 |
1752 static int no_viminfo(void); | 1752 static int no_viminfo(void); |
1753 static int read_viminfo_barline(vir_T *virp, int got_encoding, int writing); | 1753 static int read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing); |
1754 static void write_viminfo_version(FILE *fp_out); | 1754 static void write_viminfo_version(FILE *fp_out); |
1755 static void write_viminfo_barlines(vir_T *virp, FILE *fp_out); | 1755 static void write_viminfo_barlines(vir_T *virp, FILE *fp_out); |
1756 static int viminfo_errcnt; | 1756 static int viminfo_errcnt; |
1757 | 1757 |
1758 static int | 1758 static int |
2162 | 2162 |
2163 if (fp_in != NULL) | 2163 if (fp_in != NULL) |
2164 { | 2164 { |
2165 if (flags & VIF_WANT_INFO) | 2165 if (flags & VIF_WANT_INFO) |
2166 { | 2166 { |
2167 /* Registers are read and newer ones are used when writing. */ | |
2168 if (fp_out != NULL) | |
2169 prepare_viminfo_registers(); | |
2170 | |
2167 eof = read_viminfo_up_to_marks(&vir, | 2171 eof = read_viminfo_up_to_marks(&vir, |
2168 flags & VIF_FORCEIT, fp_out != NULL); | 2172 flags & VIF_FORCEIT, fp_out != NULL); |
2169 merge = TRUE; | 2173 merge = TRUE; |
2170 } | 2174 } |
2171 else if (flags != 0) | 2175 else if (flags != 0) |
2189 write_viminfo_sub_string(fp_out); | 2193 write_viminfo_sub_string(fp_out); |
2190 #ifdef FEAT_CMDHIST | 2194 #ifdef FEAT_CMDHIST |
2191 write_viminfo_history(fp_out, merge); | 2195 write_viminfo_history(fp_out, merge); |
2192 #endif | 2196 #endif |
2193 write_viminfo_registers(fp_out); | 2197 write_viminfo_registers(fp_out); |
2198 finish_viminfo_registers(); | |
2194 #ifdef FEAT_EVAL | 2199 #ifdef FEAT_EVAL |
2195 write_viminfo_varlist(fp_out); | 2200 write_viminfo_varlist(fp_out); |
2196 #endif | 2201 #endif |
2197 write_viminfo_filemarks(fp_out); | 2202 write_viminfo_filemarks(fp_out); |
2198 write_viminfo_bufferlist(fp_out); | 2203 write_viminfo_bufferlist(fp_out); |
2227 int got_encoding = FALSE; | 2232 int got_encoding = FALSE; |
2228 | 2233 |
2229 #ifdef FEAT_CMDHIST | 2234 #ifdef FEAT_CMDHIST |
2230 prepare_viminfo_history(forceit ? 9999 : 0, writing); | 2235 prepare_viminfo_history(forceit ? 9999 : 0, writing); |
2231 #endif | 2236 #endif |
2237 | |
2232 eof = viminfo_readline(virp); | 2238 eof = viminfo_readline(virp); |
2233 while (!eof && virp->vir_line[0] != '>') | 2239 while (!eof && virp->vir_line[0] != '>') |
2234 { | 2240 { |
2235 switch (virp->vir_line[0]) | 2241 switch (virp->vir_line[0]) |
2236 { | 2242 { |
2244 case '\n': | 2250 case '\n': |
2245 case '#': | 2251 case '#': |
2246 eof = viminfo_readline(virp); | 2252 eof = viminfo_readline(virp); |
2247 break; | 2253 break; |
2248 case '|': | 2254 case '|': |
2249 eof = read_viminfo_barline(virp, got_encoding, writing); | 2255 eof = read_viminfo_barline(virp, got_encoding, |
2256 forceit, writing); | |
2250 break; | 2257 break; |
2251 case '*': /* "*encoding=value" */ | 2258 case '*': /* "*encoding=value" */ |
2252 got_encoding = TRUE; | 2259 got_encoding = TRUE; |
2253 eof = viminfo_encoding(virp); | 2260 eof = viminfo_encoding(virp); |
2254 break; | 2261 break; |
2261 break; | 2268 break; |
2262 case '%': /* entry for buffer list */ | 2269 case '%': /* entry for buffer list */ |
2263 eof = read_viminfo_bufferlist(virp, writing); | 2270 eof = read_viminfo_bufferlist(virp, writing); |
2264 break; | 2271 break; |
2265 case '"': | 2272 case '"': |
2266 eof = read_viminfo_register(virp, forceit); | 2273 /* When registers are in bar lines skip the old style register |
2274 * lines. */ | |
2275 if (virp->vir_version < VIMINFO_VERSION_WITH_REGISTERS) | |
2276 eof = read_viminfo_register(virp, forceit); | |
2277 else | |
2278 do { | |
2279 eof = viminfo_readline(virp); | |
2280 } while (!eof && (virp->vir_line[0] == TAB | |
2281 || virp->vir_line[0] == '<')); | |
2267 break; | 2282 break; |
2268 case '/': /* Search string */ | 2283 case '/': /* Search string */ |
2269 case '&': /* Substitute search string */ | 2284 case '&': /* Substitute search string */ |
2270 case '~': /* Last search string, followed by '/' or '&' */ | 2285 case '~': /* Last search string, followed by '/' or '&' */ |
2271 eof = read_viminfo_search_pattern(virp, forceit); | 2286 eof = read_viminfo_search_pattern(virp, forceit); |
2525 /* Leave enough space for another continuation. */ | 2540 /* Leave enough space for another continuation. */ |
2526 remaining = LSIZE - 20; | 2541 remaining = LSIZE - 20; |
2527 } | 2542 } |
2528 } | 2543 } |
2529 putc('"', fd); | 2544 putc('"', fd); |
2530 return remaining; | 2545 return remaining - 2; |
2531 } | 2546 } |
2532 | 2547 |
2533 /* | 2548 /* |
2534 * Parse a viminfo line starting with '|'. | 2549 * Parse a viminfo line starting with '|'. |
2535 * Put each decoded value in "values" and return the number of values found. | 2550 * Add each decoded value to "values". |
2536 */ | 2551 */ |
2537 static int | 2552 static void |
2538 barline_parse(vir_T *virp, char_u *text, bval_T *values) | 2553 barline_parse(vir_T *virp, char_u *text, garray_T *values) |
2539 { | 2554 { |
2540 char_u *p = text; | 2555 char_u *p = text; |
2541 char_u *nextp = NULL; | 2556 char_u *nextp = NULL; |
2542 char_u *buf = NULL; | 2557 char_u *buf = NULL; |
2543 int count = 0; | 2558 bval_T *value; |
2544 int i; | 2559 int i; |
2545 int allocated = FALSE; | 2560 int allocated = FALSE; |
2546 #ifdef FEAT_MBYTE | 2561 #ifdef FEAT_MBYTE |
2547 char_u *sconv; | 2562 char_u *sconv; |
2548 int converted; | 2563 int converted; |
2549 #endif | 2564 #endif |
2550 | 2565 |
2551 while (*p == ',') | 2566 while (*p == ',') |
2552 { | 2567 { |
2553 if (count == BVAL_MAX) | 2568 ++p; |
2554 { | 2569 if (ga_grow(values, 1) == FAIL) |
2555 EMSG2(e_intern2, "barline_parse()"); | |
2556 break; | 2570 break; |
2557 } | 2571 value = (bval_T *)(values->ga_data) + values->ga_len; |
2558 ++p; | |
2559 | 2572 |
2560 if (*p == '>') | 2573 if (*p == '>') |
2561 { | 2574 { |
2562 /* Need to read a continuation line. Need to put strings in | 2575 /* Need to read a continuation line. Put strings in allocated |
2563 * allocated memory, because virp->vir_line is overwritten. */ | 2576 * memory, because virp->vir_line is overwritten. */ |
2564 if (!allocated) | 2577 if (!allocated) |
2565 { | 2578 { |
2566 for (i = 0; i < count; ++i) | 2579 for (i = 0; i < values->ga_len; ++i) |
2567 if (values[i].bv_type == BVAL_STRING | 2580 { |
2568 && !values[i].bv_allocated) | 2581 bval_T *vp = (bval_T *)(values->ga_data) + i; |
2582 | |
2583 if (vp->bv_type == BVAL_STRING && !vp->bv_allocated) | |
2569 { | 2584 { |
2570 values[i].bv_string = vim_strnsave( | 2585 vp->bv_string = vim_strnsave(vp->bv_string, vp->bv_len); |
2571 values[i].bv_string, values[i].bv_len); | 2586 vp->bv_allocated = TRUE; |
2572 values[i].bv_allocated = TRUE; | |
2573 } | 2587 } |
2588 } | |
2574 allocated = TRUE; | 2589 allocated = TRUE; |
2575 } | 2590 } |
2576 | 2591 |
2577 if (vim_isdigit(p[1])) | 2592 if (vim_isdigit(p[1])) |
2578 { | 2593 { |
2588 */ | 2603 */ |
2589 ++p; | 2604 ++p; |
2590 len = getdigits(&p); | 2605 len = getdigits(&p); |
2591 buf = alloc((int)(len + 1)); | 2606 buf = alloc((int)(len + 1)); |
2592 if (buf == NULL) | 2607 if (buf == NULL) |
2593 return count; | 2608 return; |
2594 p = buf; | 2609 p = buf; |
2595 for (todo = len; todo > 0; todo -= n) | 2610 for (todo = len; todo > 0; todo -= n) |
2596 { | 2611 { |
2597 if (viminfo_readline(virp) || virp->vir_line[0] != '|' | 2612 if (viminfo_readline(virp) || virp->vir_line[0] != '|' |
2598 || virp->vir_line[1] != '<') | 2613 || virp->vir_line[1] != '<') |
2599 { | 2614 { |
2600 /* file was truncated or garbled */ | 2615 /* file was truncated or garbled */ |
2601 vim_free(buf); | 2616 vim_free(buf); |
2602 return count; | 2617 return; |
2603 } | 2618 } |
2604 /* Get length of text, excluding |< and NL chars. */ | 2619 /* Get length of text, excluding |< and NL chars. */ |
2605 n = STRLEN(virp->vir_line); | 2620 n = STRLEN(virp->vir_line); |
2606 while (n > 0 && (virp->vir_line[n - 1] == NL | 2621 while (n > 0 && (virp->vir_line[n - 1] == NL |
2607 || virp->vir_line[n - 1] == CAR)) | 2622 || virp->vir_line[n - 1] == CAR)) |
2626 * |<{value},{value} | 2641 * |<{value},{value} |
2627 */ | 2642 */ |
2628 if (viminfo_readline(virp) || virp->vir_line[0] != '|' | 2643 if (viminfo_readline(virp) || virp->vir_line[0] != '|' |
2629 || virp->vir_line[1] != '<') | 2644 || virp->vir_line[1] != '<') |
2630 /* file was truncated or garbled */ | 2645 /* file was truncated or garbled */ |
2631 return count; | 2646 return; |
2632 p = virp->vir_line + 2; | 2647 p = virp->vir_line + 2; |
2633 } | 2648 } |
2634 } | 2649 } |
2635 | 2650 |
2636 if (isdigit(*p)) | 2651 if (isdigit(*p)) |
2637 { | 2652 { |
2638 values[count].bv_type = BVAL_NR; | 2653 value->bv_type = BVAL_NR; |
2639 values[count].bv_nr = getdigits(&p); | 2654 value->bv_nr = getdigits(&p); |
2640 ++count; | 2655 ++values->ga_len; |
2641 } | 2656 } |
2642 else if (*p == '"') | 2657 else if (*p == '"') |
2643 { | 2658 { |
2644 int len = 0; | 2659 int len = 0; |
2645 char_u *s = p; | 2660 char_u *s = p; |
2647 /* Unescape special characters in-place. */ | 2662 /* Unescape special characters in-place. */ |
2648 ++p; | 2663 ++p; |
2649 while (*p != '"') | 2664 while (*p != '"') |
2650 { | 2665 { |
2651 if (*p == NL || *p == NUL) | 2666 if (*p == NL || *p == NUL) |
2652 return count; /* syntax error, drop the value */ | 2667 return; /* syntax error, drop the value */ |
2653 if (*p == '\\') | 2668 if (*p == '\\') |
2654 { | 2669 { |
2655 ++p; | 2670 ++p; |
2656 if (*p == 'n') | 2671 if (*p == 'n') |
2657 s[len++] = '\n'; | 2672 s[len++] = '\n'; |
2660 ++p; | 2675 ++p; |
2661 } | 2676 } |
2662 else | 2677 else |
2663 s[len++] = *p++; | 2678 s[len++] = *p++; |
2664 } | 2679 } |
2680 ++p; | |
2665 s[len] = NUL; | 2681 s[len] = NUL; |
2666 | 2682 |
2667 #ifdef FEAT_MBYTE | 2683 #ifdef FEAT_MBYTE |
2668 converted = FALSE; | 2684 converted = FALSE; |
2669 if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL) | 2685 if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL) |
2681 #endif | 2697 #endif |
2682 /* Need to copy in allocated memory if the string wasn't allocated | 2698 /* Need to copy in allocated memory if the string wasn't allocated |
2683 * above and we did allocate before, thus vir_line may change. */ | 2699 * above and we did allocate before, thus vir_line may change. */ |
2684 if (s != buf && allocated) | 2700 if (s != buf && allocated) |
2685 s = vim_strsave(s); | 2701 s = vim_strsave(s); |
2686 values[count].bv_string = s; | 2702 value->bv_string = s; |
2687 values[count].bv_type = BVAL_STRING; | 2703 value->bv_type = BVAL_STRING; |
2688 values[count].bv_len = len; | 2704 value->bv_len = len; |
2689 values[count].bv_allocated = allocated | 2705 value->bv_allocated = allocated |
2690 #ifdef FEAT_MBYTE | 2706 #ifdef FEAT_MBYTE |
2691 || converted | 2707 || converted |
2692 #endif | 2708 #endif |
2693 ; | 2709 ; |
2694 ++count; | 2710 ++values->ga_len; |
2695 if (nextp != NULL) | 2711 if (nextp != NULL) |
2696 { | 2712 { |
2697 /* values following a long string */ | 2713 /* values following a long string */ |
2698 p = nextp; | 2714 p = nextp; |
2699 nextp = NULL; | 2715 nextp = NULL; |
2700 } | 2716 } |
2701 } | 2717 } |
2702 else if (*p == ',') | 2718 else if (*p == ',') |
2703 { | 2719 { |
2704 values[count].bv_type = BVAL_EMPTY; | 2720 value->bv_type = BVAL_EMPTY; |
2705 ++count; | 2721 ++values->ga_len; |
2706 } | 2722 } |
2707 else | 2723 else |
2708 break; | 2724 break; |
2709 } | 2725 } |
2710 | |
2711 return count; | |
2712 } | 2726 } |
2713 | 2727 |
2714 static int | 2728 static int |
2715 read_viminfo_barline(vir_T *virp, int got_encoding, int writing) | 2729 read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing) |
2716 { | 2730 { |
2717 char_u *p = virp->vir_line + 1; | 2731 char_u *p = virp->vir_line + 1; |
2718 int bartype; | 2732 int bartype; |
2719 bval_T values[BVAL_MAX]; | 2733 garray_T values; |
2720 int count = 0; | 2734 bval_T *vp; |
2721 int i; | 2735 int i; |
2722 | 2736 |
2723 /* The format is: |{bartype},{value},... | 2737 /* The format is: |{bartype},{value},... |
2724 * For a very long string: | 2738 * For a very long string: |
2725 * |{bartype},>{length of "{text}{text2}"} | 2739 * |{bartype},>{length of "{text}{text2}"} |
2735 if (writing) | 2749 if (writing) |
2736 ga_add_string(&virp->vir_barlines, virp->vir_line); | 2750 ga_add_string(&virp->vir_barlines, virp->vir_line); |
2737 } | 2751 } |
2738 else | 2752 else |
2739 { | 2753 { |
2754 ga_init2(&values, sizeof(bval_T), 20); | |
2740 bartype = getdigits(&p); | 2755 bartype = getdigits(&p); |
2741 switch (bartype) | 2756 switch (bartype) |
2742 { | 2757 { |
2743 case BARTYPE_VERSION: | 2758 case BARTYPE_VERSION: |
2744 /* Only use the version when it comes before the encoding. | 2759 /* Only use the version when it comes before the encoding. |
2745 * If it comes later it was copied by a Vim version that | 2760 * If it comes later it was copied by a Vim version that |
2746 * doesn't understand the version. */ | 2761 * doesn't understand the version. */ |
2747 if (!got_encoding) | 2762 if (!got_encoding) |
2748 { | 2763 { |
2749 count = barline_parse(virp, p, values); | 2764 barline_parse(virp, p, &values); |
2750 if (count > 0 && values[0].bv_type == BVAL_NR) | 2765 vp = (bval_T *)values.ga_data; |
2751 virp->vir_version = values[0].bv_nr; | 2766 if (values.ga_len > 0 && vp->bv_type == BVAL_NR) |
2767 virp->vir_version = vp->bv_nr; | |
2752 } | 2768 } |
2753 break; | 2769 break; |
2754 | 2770 |
2755 case BARTYPE_HISTORY: | 2771 case BARTYPE_HISTORY: |
2756 count = barline_parse(virp, p, values); | 2772 barline_parse(virp, p, &values); |
2757 handle_viminfo_history(values, count, writing); | 2773 handle_viminfo_history(&values, writing); |
2774 break; | |
2775 | |
2776 case BARTYPE_REGISTER: | |
2777 barline_parse(virp, p, &values); | |
2778 handle_viminfo_register(&values, force); | |
2758 break; | 2779 break; |
2759 | 2780 |
2760 default: | 2781 default: |
2761 /* copy unrecognized line (for future use) */ | 2782 /* copy unrecognized line (for future use) */ |
2762 if (writing) | 2783 if (writing) |
2763 ga_add_string(&virp->vir_barlines, virp->vir_line); | 2784 ga_add_string(&virp->vir_barlines, virp->vir_line); |
2764 } | 2785 } |
2765 } | 2786 for (i = 0; i < values.ga_len; ++i) |
2766 | 2787 { |
2767 for (i = 0; i < count; ++i) | 2788 vp = (bval_T *)values.ga_data + i; |
2768 if (values[i].bv_type == BVAL_STRING && values[i].bv_allocated) | 2789 if (vp->bv_type == BVAL_STRING && vp->bv_allocated) |
2769 vim_free(values[i].bv_string); | 2790 vim_free(vp->bv_string); |
2791 } | |
2792 ga_clear(&values); | |
2793 } | |
2770 | 2794 |
2771 return viminfo_readline(virp); | 2795 return viminfo_readline(virp); |
2772 } | 2796 } |
2773 | 2797 |
2774 static void | 2798 static void |
2791 for (i = 0; i < gap->ga_len; ++i) | 2815 for (i = 0; i < gap->ga_len; ++i) |
2792 fputs(((char **)(gap->ga_data))[i], fp_out); | 2816 fputs(((char **)(gap->ga_data))[i], fp_out); |
2793 } | 2817 } |
2794 } | 2818 } |
2795 #endif /* FEAT_VIMINFO */ | 2819 #endif /* FEAT_VIMINFO */ |
2820 | |
2821 #if defined(FEAT_VIMINFO) || defined(PROTO) | |
2822 /* | |
2823 * Return the current time in seconds. Calls time(), unless test_settime() | |
2824 * was used. | |
2825 */ | |
2826 time_t | |
2827 vim_time(void) | |
2828 { | |
2829 # ifdef FEAT_EVAL | |
2830 return time_for_testing == 0 ? time(NULL) : time_for_testing; | |
2831 # else | |
2832 return time(NULL); | |
2833 # endif | |
2834 } | |
2835 #endif | |
2796 | 2836 |
2797 /* | 2837 /* |
2798 * Implementation of ":fixdel", also used by get_stty(). | 2838 * Implementation of ":fixdel", also used by get_stty(). |
2799 * <BS> resulting <Del> | 2839 * <BS> resulting <Del> |
2800 * ^? ^H | 2840 * ^? ^H |