Mercurial > vim
comparison src/ex_docmd.c @ 14538:213f1a519378 v8.1.0282
patch 8.1.0282: 'incsearch' does not work with command modifiers
commit https://github.com/vim/vim/commit/33c4dbb74bdf41aadd193a704f597d4df20f0e47
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Aug 14 16:06:16 2018 +0200
patch 8.1.0282: 'incsearch' does not work with command modifiers
Problem: 'incsearch' does not work with command modifiers.
Solution: Skip command modifiers.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 14 Aug 2018 16:15:04 +0200 |
parents | 4caa51067cb8 |
children | 60b9b6196644 |
comparison
equal
deleted
inserted
replaced
14537:2e7cca4372f3 | 14538:213f1a519378 |
---|---|
66 static char_u *do_one_cmd(char_u **, int, struct condstack *, char_u *(*fgetline)(int, void *, int), void *cookie); | 66 static char_u *do_one_cmd(char_u **, int, struct condstack *, char_u *(*fgetline)(int, void *, int), void *cookie); |
67 #else | 67 #else |
68 static char_u *do_one_cmd(char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie); | 68 static char_u *do_one_cmd(char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie); |
69 static int if_level = 0; /* depth in :if */ | 69 static int if_level = 0; /* depth in :if */ |
70 #endif | 70 #endif |
71 static void free_cmdmod(void); | |
71 static void append_command(char_u *cmd); | 72 static void append_command(char_u *cmd); |
72 static char_u *find_command(exarg_T *eap, int *full); | 73 static char_u *find_command(exarg_T *eap, int *full); |
73 | 74 |
74 static void ex_abbreviate(exarg_T *eap); | 75 static void ex_abbreviate(exarg_T *eap); |
75 static void ex_map(exarg_T *eap); | 76 static void ex_map(exarg_T *eap); |
1739 | 1740 |
1740 /* "#!anything" is handled like a comment. */ | 1741 /* "#!anything" is handled like a comment. */ |
1741 if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!') | 1742 if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!') |
1742 goto doend; | 1743 goto doend; |
1743 | 1744 |
1744 /* | 1745 /* |
1745 * Repeat until no more command modifiers are found. | 1746 * 1. Skip comment lines and leading white space and colons. |
1746 * The "ea" structure holds the arguments that can be used. | 1747 * 2. Handle command modifiers. |
1747 */ | 1748 */ |
1749 // The "ea" structure holds the arguments that can be used. | |
1748 ea.cmd = *cmdlinep; | 1750 ea.cmd = *cmdlinep; |
1749 ea.cmdlinep = cmdlinep; | 1751 ea.cmdlinep = cmdlinep; |
1750 ea.getline = fgetline; | 1752 ea.getline = fgetline; |
1751 ea.cookie = cookie; | 1753 ea.cookie = cookie; |
1752 #ifdef FEAT_EVAL | 1754 #ifdef FEAT_EVAL |
1753 ea.cstack = cstack; | 1755 ea.cstack = cstack; |
1754 #endif | 1756 #endif |
1755 if (parse_command_modifiers(&ea, &errormsg) == FAIL) | 1757 if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL) |
1756 goto doend; | 1758 goto doend; |
1757 | 1759 |
1758 after_modifier = ea.cmd; | 1760 after_modifier = ea.cmd; |
1759 | 1761 |
1760 #ifdef FEAT_EVAL | 1762 #ifdef FEAT_EVAL |
2551 #endif | 2553 #endif |
2552 | 2554 |
2553 if (ea.verbose_save >= 0) | 2555 if (ea.verbose_save >= 0) |
2554 p_verbose = ea.verbose_save; | 2556 p_verbose = ea.verbose_save; |
2555 | 2557 |
2556 if (cmdmod.save_ei != NULL) | 2558 free_cmdmod(); |
2557 { | |
2558 /* Restore 'eventignore' to the value before ":noautocmd". */ | |
2559 set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei, | |
2560 OPT_FREE, SID_NONE); | |
2561 free_string_option(cmdmod.save_ei); | |
2562 } | |
2563 | |
2564 if (cmdmod.filter_regmatch.regprog != NULL) | |
2565 vim_regfree(cmdmod.filter_regmatch.regprog); | |
2566 | |
2567 cmdmod = save_cmdmod; | 2559 cmdmod = save_cmdmod; |
2568 | 2560 |
2569 if (ea.save_msg_silent != -1) | 2561 if (ea.save_msg_silent != -1) |
2570 { | 2562 { |
2571 /* messages could be enabled for a serious error, need to check if the | 2563 /* messages could be enabled for a serious error, need to check if the |
2607 * Parse and skip over command modifiers: | 2599 * Parse and skip over command modifiers: |
2608 * - update eap->cmd | 2600 * - update eap->cmd |
2609 * - store flags in "cmdmod". | 2601 * - store flags in "cmdmod". |
2610 * - Set ex_pressedreturn for an empty command line. | 2602 * - Set ex_pressedreturn for an empty command line. |
2611 * - set msg_silent for ":silent" | 2603 * - set msg_silent for ":silent" |
2604 * - set 'eventignore' to "all" for ":noautocmd" | |
2612 * - set p_verbose for ":verbose" | 2605 * - set p_verbose for ":verbose" |
2613 * - Increment "sandbox" for ":sandbox" | 2606 * - Increment "sandbox" for ":sandbox" |
2607 * When "skip_only" is TRUE the global variables are not changed, except for | |
2608 * "cmdmod". | |
2614 * Return FAIL when the command is not to be executed. | 2609 * Return FAIL when the command is not to be executed. |
2615 * May set "errormsg" to an error message. | 2610 * May set "errormsg" to an error message. |
2616 */ | 2611 */ |
2617 int | 2612 int |
2618 parse_command_modifiers(exarg_T *eap, char_u **errormsg) | 2613 parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only) |
2619 { | 2614 { |
2620 char_u *p; | 2615 char_u *p; |
2621 | 2616 |
2622 vim_memset(&cmdmod, 0, sizeof(cmdmod)); | 2617 vim_memset(&cmdmod, 0, sizeof(cmdmod)); |
2623 eap->verbose_save = -1; | 2618 eap->verbose_save = -1; |
2624 eap->save_msg_silent = -1; | 2619 eap->save_msg_silent = -1; |
2625 | 2620 |
2621 // Repeat until no more command modifiers are found. | |
2626 for (;;) | 2622 for (;;) |
2627 { | 2623 { |
2628 /* | |
2629 * 1. Skip comment lines and leading white space and colons. | |
2630 */ | |
2631 while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':') | 2624 while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':') |
2632 ++eap->cmd; | 2625 ++eap->cmd; |
2633 | 2626 |
2634 /* in ex mode, an empty line works like :+ */ | 2627 /* in ex mode, an empty line works like :+ */ |
2635 if (*eap->cmd == NUL && exmode_active | 2628 if (*eap->cmd == NUL && exmode_active |
2636 && (getline_equal(eap->getline, eap->cookie, getexmodeline) | 2629 && (getline_equal(eap->getline, eap->cookie, getexmodeline) |
2637 || getline_equal(eap->getline, eap->cookie, getexline)) | 2630 || getline_equal(eap->getline, eap->cookie, getexline)) |
2638 && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) | 2631 && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) |
2639 { | 2632 { |
2640 eap->cmd = (char_u *)"+"; | 2633 eap->cmd = (char_u *)"+"; |
2641 ex_pressedreturn = TRUE; | 2634 if (!skip_only) |
2635 ex_pressedreturn = TRUE; | |
2642 } | 2636 } |
2643 | 2637 |
2644 /* ignore comment and empty lines */ | 2638 /* ignore comment and empty lines */ |
2645 if (*eap->cmd == '"') | 2639 if (*eap->cmd == '"') |
2646 return FAIL; | 2640 return FAIL; |
2647 if (*eap->cmd == NUL) | 2641 if (*eap->cmd == NUL) |
2648 { | 2642 { |
2649 ex_pressedreturn = TRUE; | 2643 if (!skip_only) |
2644 ex_pressedreturn = TRUE; | |
2650 return FAIL; | 2645 return FAIL; |
2651 } | 2646 } |
2652 | 2647 |
2653 /* | |
2654 * 2. Handle command modifiers. | |
2655 */ | |
2656 p = skip_range(eap->cmd, NULL); | 2648 p = skip_range(eap->cmd, NULL); |
2657 switch (*p) | 2649 switch (*p) |
2658 { | 2650 { |
2659 /* When adding an entry, also modify cmd_exists(). */ | 2651 /* When adding an entry, also modify cmd_exists(). */ |
2660 case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3)) | 2652 case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3)) |
2718 cmdmod.filter_force = TRUE; | 2710 cmdmod.filter_force = TRUE; |
2719 p = skipwhite(p + 1); | 2711 p = skipwhite(p + 1); |
2720 if (*p == NUL || ends_excmd(*p)) | 2712 if (*p == NUL || ends_excmd(*p)) |
2721 break; | 2713 break; |
2722 } | 2714 } |
2723 p = skip_vimgrep_pat(p, ®_pat, NULL); | 2715 if (skip_only) |
2716 p = skip_vimgrep_pat(p, NULL, NULL); | |
2717 else | |
2718 // NOTE: This puts a NUL after the pattern. | |
2719 p = skip_vimgrep_pat(p, ®_pat, NULL); | |
2724 if (p == NULL || *p == NUL) | 2720 if (p == NULL || *p == NUL) |
2725 break; | 2721 break; |
2726 cmdmod.filter_regmatch.regprog = | 2722 if (!skip_only) |
2723 { | |
2724 cmdmod.filter_regmatch.regprog = | |
2727 vim_regcomp(reg_pat, RE_MAGIC); | 2725 vim_regcomp(reg_pat, RE_MAGIC); |
2728 if (cmdmod.filter_regmatch.regprog == NULL) | 2726 if (cmdmod.filter_regmatch.regprog == NULL) |
2729 break; | 2727 break; |
2728 } | |
2730 eap->cmd = p; | 2729 eap->cmd = p; |
2731 continue; | 2730 continue; |
2732 } | 2731 } |
2733 | 2732 |
2734 /* ":hide" and ":hide | cmd" are not modifiers */ | 2733 /* ":hide" and ":hide | cmd" are not modifiers */ |
2750 cmdmod.split |= WSP_ABOVE; | 2749 cmdmod.split |= WSP_ABOVE; |
2751 continue; | 2750 continue; |
2752 | 2751 |
2753 case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3)) | 2752 case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3)) |
2754 { | 2753 { |
2755 if (cmdmod.save_ei == NULL) | 2754 if (cmdmod.save_ei == NULL && !skip_only) |
2756 { | 2755 { |
2757 /* Set 'eventignore' to "all". Restore the | 2756 /* Set 'eventignore' to "all". Restore the |
2758 * existing option value later. */ | 2757 * existing option value later. */ |
2759 cmdmod.save_ei = vim_strsave(p_ei); | 2758 cmdmod.save_ei = vim_strsave(p_ei); |
2760 set_string_option_direct((char_u *)"ei", -1, | 2759 set_string_option_direct((char_u *)"ei", -1, |
2773 continue; | 2772 continue; |
2774 | 2773 |
2775 case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) | 2774 case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) |
2776 { | 2775 { |
2777 #ifdef HAVE_SANDBOX | 2776 #ifdef HAVE_SANDBOX |
2778 if (!eap->did_sandbox) | 2777 if (!skip_only) |
2779 ++sandbox; | 2778 { |
2780 eap->did_sandbox = TRUE; | 2779 if (!eap->did_sandbox) |
2780 ++sandbox; | |
2781 eap->did_sandbox = TRUE; | |
2782 } | |
2781 #endif | 2783 #endif |
2782 continue; | 2784 continue; |
2783 } | 2785 } |
2784 if (!checkforcmd(&eap->cmd, "silent", 3)) | 2786 if (!checkforcmd(&eap->cmd, "silent", 3)) |
2785 break; | 2787 break; |
2786 if (eap->save_msg_silent == -1) | 2788 if (!skip_only) |
2787 eap->save_msg_silent = msg_silent; | 2789 { |
2788 ++msg_silent; | 2790 if (eap->save_msg_silent == -1) |
2791 eap->save_msg_silent = msg_silent; | |
2792 ++msg_silent; | |
2793 } | |
2789 if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1])) | 2794 if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1])) |
2790 { | 2795 { |
2791 /* ":silent!", but not "silent !cmd" */ | 2796 /* ":silent!", but not "silent !cmd" */ |
2792 eap->cmd = skipwhite(eap->cmd + 1); | 2797 eap->cmd = skipwhite(eap->cmd + 1); |
2793 ++emsg_silent; | 2798 if (!skip_only) |
2794 ++eap->did_esilent; | 2799 { |
2800 ++emsg_silent; | |
2801 ++eap->did_esilent; | |
2802 } | |
2795 } | 2803 } |
2796 continue; | 2804 continue; |
2797 | 2805 |
2798 case 't': if (checkforcmd(&p, "tab", 3)) | 2806 case 't': if (checkforcmd(&p, "tab", 3)) |
2799 { | 2807 { |
2818 cmdmod.split |= WSP_TOP; | 2826 cmdmod.split |= WSP_TOP; |
2819 continue; | 2827 continue; |
2820 | 2828 |
2821 case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3)) | 2829 case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3)) |
2822 break; | 2830 break; |
2823 if (eap->save_msg_silent == -1) | 2831 if (!skip_only) |
2824 eap->save_msg_silent = msg_silent; | 2832 { |
2825 msg_silent = 0; | 2833 if (eap->save_msg_silent == -1) |
2834 eap->save_msg_silent = msg_silent; | |
2835 msg_silent = 0; | |
2836 } | |
2826 continue; | 2837 continue; |
2827 | 2838 |
2828 case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) | 2839 case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) |
2829 { | 2840 { |
2830 cmdmod.split |= WSP_VERT; | 2841 cmdmod.split |= WSP_VERT; |
2831 continue; | 2842 continue; |
2832 } | 2843 } |
2833 if (!checkforcmd(&p, "verbose", 4)) | 2844 if (!checkforcmd(&p, "verbose", 4)) |
2834 break; | 2845 break; |
2835 if (eap->verbose_save < 0) | 2846 if (!skip_only) |
2836 eap->verbose_save = p_verbose; | 2847 { |
2837 if (vim_isdigit(*eap->cmd)) | 2848 if (eap->verbose_save < 0) |
2838 p_verbose = atoi((char *)eap->cmd); | 2849 eap->verbose_save = p_verbose; |
2839 else | 2850 if (vim_isdigit(*eap->cmd)) |
2840 p_verbose = 1; | 2851 p_verbose = atoi((char *)eap->cmd); |
2852 else | |
2853 p_verbose = 1; | |
2854 } | |
2841 eap->cmd = p; | 2855 eap->cmd = p; |
2842 continue; | 2856 continue; |
2843 } | 2857 } |
2844 break; | 2858 break; |
2845 } | 2859 } |
2846 | 2860 |
2847 return OK; | 2861 return OK; |
2862 } | |
2863 | |
2864 /* | |
2865 * Free contents of "cmdmod". | |
2866 */ | |
2867 static void | |
2868 free_cmdmod(void) | |
2869 { | |
2870 if (cmdmod.save_ei != NULL) | |
2871 { | |
2872 /* Restore 'eventignore' to the value before ":noautocmd". */ | |
2873 set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei, | |
2874 OPT_FREE, SID_NONE); | |
2875 free_string_option(cmdmod.save_ei); | |
2876 } | |
2877 | |
2878 if (cmdmod.filter_regmatch.regprog != NULL) | |
2879 vim_regfree(cmdmod.filter_regmatch.regprog); | |
2848 } | 2880 } |
2849 | 2881 |
2850 /* | 2882 /* |
2851 * Parse the address range, if any, in "eap". | 2883 * Parse the address range, if any, in "eap". |
2852 * Return FAIL and set "errormsg" or return OK. | 2884 * Return FAIL and set "errormsg" or return OK. |