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, &reg_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, &reg_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.