changeset 10618:4ee16e5e2e26 v8.0.0198

patch 8.0.0198: some syntax arguments take effect even after "if 0" commit https://github.com/vim/vim/commit/de318c5c35ed0d65fd2a07196cb8acd5ee6d9bf8 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jan 17 16:27:10 2017 +0100 patch 8.0.0198: some syntax arguments take effect even after "if 0" Problem: Some syntax arguments take effect even after "if 0". (Taylor Venable) Solution: Properly skip the syntax statements. Make "syn case" and "syn conceal" report the current state. Fix that "syn clear" didn't reset the conceal flag. Add tests for :syntax skipping properly.
author Christian Brabandt <cb@256bit.org>
date Tue, 17 Jan 2017 16:30:05 +0100
parents 9a75c8a1b8b1
children 3cc3825f1f53
files src/syntax.c src/testdir/test_syntax.vim src/version.c
diffstat 3 files changed, 185 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -462,7 +462,7 @@ static void syn_clear_keyword(int id, ha
 static void clear_keywtab(hashtab_T *ht);
 static void add_keyword(char_u *name, int id, int flags, short *cont_in_list, short *next_list, int conceal_char);
 static char_u *get_group_name(char_u *arg, char_u **name_end);
-static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char);
+static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char, int skip);
 static void syn_cmd_include(exarg_T *eap, int syncing);
 static void syn_cmd_iskeyword(exarg_T *eap, int syncing);
 static void syn_cmd_keyword(exarg_T *eap, int syncing);
@@ -481,7 +481,7 @@ static int syn_add_cluster(char_u *name)
 static void init_syn_patterns(void);
 static char_u *get_syn_pattern(char_u *arg, synpat_T *ci);
 static void syn_cmd_sync(exarg_T *eap, int syncing);
-static int get_id_list(char_u **arg, int keylen, short **list);
+static int get_id_list(char_u **arg, int keylen, short **list, int skip);
 static void syn_combine_list(short **clstr1, short **clstr2, int list_op);
 static void syn_incl_toplevel(int id, int *flagsp);
 
@@ -3434,7 +3434,14 @@ syn_cmd_conceal(exarg_T *eap UNUSED, int
 	return;
 
     next = skiptowhite(arg);
-    if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
+    if (*arg == NUL)
+    {
+	if (curwin->w_s->b_syn_conceal)
+	    MSG(_("syn conceal on"));
+	else
+	    MSG(_("syn conceal off"));
+    }
+    else if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
 	curwin->w_s->b_syn_conceal = TRUE;
     else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3)
 	curwin->w_s->b_syn_conceal = FALSE;
@@ -3457,7 +3464,14 @@ syn_cmd_case(exarg_T *eap, int syncing U
 	return;
 
     next = skiptowhite(arg);
-    if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
+    if (*arg == NUL)
+    {
+	if (curwin->w_s->b_syn_ic)
+	    MSG(_("syntax case ignore"));
+	else
+	    MSG(_("syntax case match"));
+    }
+    else if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
 	curwin->w_s->b_syn_ic = FALSE;
     else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
 	curwin->w_s->b_syn_ic = TRUE;
@@ -3479,7 +3493,16 @@ syn_cmd_spell(exarg_T *eap, int syncing 
 	return;
 
     next = skiptowhite(arg);
-    if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
+    if (*arg == NUL)
+    {
+	if (curwin->w_s->b_syn_spell == SYNSPL_TOP)
+	    MSG(_("syntax spell toplevel"));
+	else if (curwin->w_s->b_syn_spell == SYNSPL_NOTOP)
+	    MSG(_("syntax spell notoplevel"));
+	else
+	    MSG(_("syntax spell default"));
+    }
+    else if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
 	curwin->w_s->b_syn_spell = SYNSPL_TOP;
     else if (STRNICMP(arg, "notoplevel", 10) == 0 && next - arg == 10)
 	curwin->w_s->b_syn_spell = SYNSPL_NOTOP;
@@ -3556,6 +3579,9 @@ syntax_clear(synblock_T *block)
     block->b_syn_ic = FALSE;	    /* Use case, by default */
     block->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
     block->b_syn_containedin = FALSE;
+#ifdef FEAT_CONCEAL
+    block->b_syn_conceal = FALSE;
+#endif
 
     /* free the keywords */
     clear_keywtab(&block->b_keywtab);
@@ -4543,7 +4569,8 @@ get_group_name(
 get_syn_options(
     char_u	    *arg,		/* next argument to be checked */
     syn_opt_arg_T   *opt,		/* various things */
-    int		    *conceal_char UNUSED)
+    int		    *conceal_char UNUSED,
+    int		    skip)		/* TRUE if skipping over command */
 {
     char_u	*gname_start, *gname;
     int		syn_id;
@@ -4626,17 +4653,17 @@ get_syn_options(
 		EMSG(_("E395: contains argument not accepted here"));
 		return NULL;
 	    }
-	    if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
+	    if (get_id_list(&arg, 8, &opt->cont_list, skip) == FAIL)
 		return NULL;
 	}
 	else if (flagtab[fidx].argtype == 2)
 	{
-	    if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
+	    if (get_id_list(&arg, 11, &opt->cont_in_list, skip) == FAIL)
 		return NULL;
 	}
 	else if (flagtab[fidx].argtype == 3)
 	{
-	    if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
+	    if (get_id_list(&arg, 9, &opt->next_list, skip) == FAIL)
 		return NULL;
 	}
 	else if (flagtab[fidx].argtype == 11 && arg[5] == '=')
@@ -4846,7 +4873,10 @@ syn_cmd_keyword(exarg_T *eap, int syncin
 
     if (rest != NULL)
     {
-	syn_id = syn_check_group(arg, (int)(group_name_end - arg));
+	if (eap->skip)
+	    syn_id = -1;
+	else
+	    syn_id = syn_check_group(arg, (int)(group_name_end - arg));
 	if (syn_id != 0)
 	    /* allocate a buffer, for removing backslashes in the keyword */
 	    keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
@@ -4868,7 +4898,8 @@ syn_cmd_keyword(exarg_T *eap, int syncin
 	    p = keyword_copy;
 	    for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest))
 	    {
-		rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+		rest = get_syn_options(rest, &syn_opt_arg, &conceal_char,
+								    eap->skip);
 		if (rest == NULL || ends_excmd(*rest))
 		    break;
 		/* Copy the keyword, removing backslashes, and add a NUL. */
@@ -4981,7 +5012,7 @@ syn_cmd_match(
     syn_opt_arg.cont_list = NULL;
     syn_opt_arg.cont_in_list = NULL;
     syn_opt_arg.next_list = NULL;
-    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
 
     /* get the pattern. */
     init_syn_patterns();
@@ -4991,7 +5022,7 @@ syn_cmd_match(
 	syn_opt_arg.flags |= HL_HAS_EOL;
 
     /* Get options after the pattern */
-    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+    rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
 
     if (rest != NULL)		/* all arguments are valid */
     {
@@ -5117,7 +5148,7 @@ syn_cmd_region(
     while (rest != NULL && !ends_excmd(*rest))
     {
 	/* Check for option arguments */
-	rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+	rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
 	if (rest == NULL || ends_excmd(*rest))
 	    break;
 
@@ -5628,12 +5659,13 @@ syn_cmd_cluster(exarg_T *eap, int syncin
 		break;
 
 	    clstr_list = NULL;
-	    if (get_id_list(&rest, opt_len, &clstr_list) == FAIL)
+	    if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL)
 	    {
 		EMSG2(_(e_invarg2), rest);
 		break;
 	    }
-	    syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
+	    if (scl_id >= 0)
+		syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
 			     &clstr_list, list_op);
 	    got_clstr = TRUE;
 	}
@@ -5931,8 +5963,9 @@ syn_cmd_sync(exarg_T *eap, int syncing U
 get_id_list(
     char_u	**arg,
     int		keylen,		/* length of keyword */
-    short	**list)		/* where to store the resulting list, if not
+    short	**list,		/* where to store the resulting list, if not
 				   NULL, the list is silently skipped! */
+    int		skip)
 {
     char_u	*p = NULL;
     char_u	*end;
@@ -6015,7 +6048,8 @@ get_id_list(
 	    }
 	    else if (name[1] == '@')
 	    {
-		id = syn_check_cluster(name + 2, (int)(end - p - 1));
+		if (!skip)
+		    id = syn_check_cluster(name + 2, (int)(end - p - 1));
 	    }
 	    else
 	    {
--- a/src/testdir/test_syntax.vim
+++ b/src/testdir/test_syntax.vim
@@ -162,3 +162,134 @@ func Test_syntax_completion()
   call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx')
   call assert_match('^"syn match Boolean Character ', @:)
 endfunc
+
+func Test_syntax_arg_skipped()
+  syn clear
+  syntax case ignore
+  if 0
+    syntax case match
+  endif
+  call assert_match('case ignore', execute('syntax case'))
+
+  syn keyword Foo foo
+  call assert_match('Foo', execute('syntax'))
+  syn clear
+  call assert_match('case match', execute('syntax case'))
+  call assert_notmatch('Foo', execute('syntax'))
+
+  if has('conceal')
+    syn clear
+    syntax conceal on
+    if 0
+      syntax conceal off
+    endif
+    call assert_match('conceal on', execute('syntax conceal'))
+    syn clear
+    call assert_match('conceal off', execute('syntax conceal'))
+  endif
+
+  syntax region Tar start=/</ end=/>/
+  if 0
+    syntax region NotTest start=/</ end=/>/ contains=@Spell
+  endif
+  call assert_match('Tar', execute('syntax'))
+  call assert_notmatch('NotTest', execute('syntax'))
+  call assert_notmatch('Spell', execute('syntax'))
+
+  hi Foo ctermfg=blue
+  let a = execute('hi Foo')
+  if 0
+    syntax rest
+  endif
+  call assert_equal(a, execute('hi Foo'))
+
+  set ft=tags
+  syn off
+  if 0
+    syntax enable
+  endif
+  call assert_match('No Syntax items defined', execute('syntax'))
+  syntax enable
+  call assert_match('tagComment', execute('syntax'))
+  set ft=
+
+  syn clear
+  if 0
+    syntax include @Spell nothing
+  endif
+  call assert_notmatch('Spell', execute('syntax'))
+
+  syn clear
+  syn iskeyword 48-57,$,_
+  call assert_match('48-57,$,_', execute('syntax iskeyword'))
+  if 0
+    syn clear
+    syn iskeyword clear
+  endif
+  call assert_match('48-57,$,_', execute('syntax iskeyword'))
+  syn iskeyword clear
+  call assert_match('not set', execute('syntax iskeyword'))
+  syn iskeyword 48-57,$,_
+  syn clear
+  call assert_match('not set', execute('syntax iskeyword'))
+
+  syn clear
+  syn keyword Foo foo
+  if 0
+    syn keyword NotAdded bar
+  endif
+  call assert_match('Foo', execute('syntax'))
+  call assert_notmatch('NotAdded', execute('highlight'))
+
+  syn clear
+  syn keyword Foo foo
+  call assert_match('Foo', execute('syntax'))
+  call assert_match('Foo', execute('syntax list'))
+  call assert_notmatch('Foo', execute('if 0 | syntax | endif'))
+  call assert_notmatch('Foo', execute('if 0 | syntax list | endif'))
+
+  syn clear
+  syn match Fopi /asdf/
+  if 0
+    syn match Fopx /asdf/
+  endif
+  call assert_match('Fopi', execute('syntax'))
+  call assert_notmatch('Fopx', execute('syntax'))
+
+  syn clear
+  syn spell toplevel
+  call assert_match('spell toplevel', execute('syntax spell'))
+  if 0
+    syn spell notoplevel
+  endif
+  call assert_match('spell toplevel', execute('syntax spell'))
+  syn spell notoplevel
+  call assert_match('spell notoplevel', execute('syntax spell'))
+  syn spell default
+  call assert_match('spell default', execute('syntax spell'))
+
+  syn clear
+  if 0
+    syntax cluster Spell
+  endif
+  call assert_notmatch('Spell', execute('syntax'))
+
+  syn clear
+  syn keyword Foo foo
+  syn sync ccomment
+  syn sync maxlines=5
+  if 0
+    syn sync maxlines=11
+  endif
+  call assert_match('on C-style comments', execute('syntax sync'))
+  call assert_match('maximal 5 lines', execute('syntax sync'))
+  syn clear
+  syn keyword Foo foo
+  if 0
+    syn sync ccomment
+  endif
+  call assert_notmatch('on C-style comments', execute('syntax sync'))
+
+  syn clear
+endfunc
+
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    198,
+/**/
     197,
 /**/
     196,