Skip to content

Commit de318c5

Browse files
committed
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.
1 parent 369b6f5 commit de318c5

3 files changed

Lines changed: 185 additions & 18 deletions

File tree

src/syntax.c

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ static void syn_clear_keyword(int id, hashtab_T *ht);
462462
static void clear_keywtab(hashtab_T *ht);
463463
static void add_keyword(char_u *name, int id, int flags, short *cont_in_list, short *next_list, int conceal_char);
464464
static char_u *get_group_name(char_u *arg, char_u **name_end);
465-
static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char);
465+
static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char, int skip);
466466
static void syn_cmd_include(exarg_T *eap, int syncing);
467467
static void syn_cmd_iskeyword(exarg_T *eap, int syncing);
468468
static void syn_cmd_keyword(exarg_T *eap, int syncing);
@@ -481,7 +481,7 @@ static int syn_add_cluster(char_u *name);
481481
static void init_syn_patterns(void);
482482
static char_u *get_syn_pattern(char_u *arg, synpat_T *ci);
483483
static void syn_cmd_sync(exarg_T *eap, int syncing);
484-
static int get_id_list(char_u **arg, int keylen, short **list);
484+
static int get_id_list(char_u **arg, int keylen, short **list, int skip);
485485
static void syn_combine_list(short **clstr1, short **clstr2, int list_op);
486486
static void syn_incl_toplevel(int id, int *flagsp);
487487

@@ -3434,7 +3434,14 @@ syn_cmd_conceal(exarg_T *eap UNUSED, int syncing UNUSED)
34343434
return;
34353435

34363436
next = skiptowhite(arg);
3437-
if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
3437+
if (*arg == NUL)
3438+
{
3439+
if (curwin->w_s->b_syn_conceal)
3440+
MSG(_("syn conceal on"));
3441+
else
3442+
MSG(_("syn conceal off"));
3443+
}
3444+
else if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
34383445
curwin->w_s->b_syn_conceal = TRUE;
34393446
else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3)
34403447
curwin->w_s->b_syn_conceal = FALSE;
@@ -3457,7 +3464,14 @@ syn_cmd_case(exarg_T *eap, int syncing UNUSED)
34573464
return;
34583465

34593466
next = skiptowhite(arg);
3460-
if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
3467+
if (*arg == NUL)
3468+
{
3469+
if (curwin->w_s->b_syn_ic)
3470+
MSG(_("syntax case ignore"));
3471+
else
3472+
MSG(_("syntax case match"));
3473+
}
3474+
else if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
34613475
curwin->w_s->b_syn_ic = FALSE;
34623476
else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
34633477
curwin->w_s->b_syn_ic = TRUE;
@@ -3479,7 +3493,16 @@ syn_cmd_spell(exarg_T *eap, int syncing UNUSED)
34793493
return;
34803494

34813495
next = skiptowhite(arg);
3482-
if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
3496+
if (*arg == NUL)
3497+
{
3498+
if (curwin->w_s->b_syn_spell == SYNSPL_TOP)
3499+
MSG(_("syntax spell toplevel"));
3500+
else if (curwin->w_s->b_syn_spell == SYNSPL_NOTOP)
3501+
MSG(_("syntax spell notoplevel"));
3502+
else
3503+
MSG(_("syntax spell default"));
3504+
}
3505+
else if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
34833506
curwin->w_s->b_syn_spell = SYNSPL_TOP;
34843507
else if (STRNICMP(arg, "notoplevel", 10) == 0 && next - arg == 10)
34853508
curwin->w_s->b_syn_spell = SYNSPL_NOTOP;
@@ -3556,6 +3579,9 @@ syntax_clear(synblock_T *block)
35563579
block->b_syn_ic = FALSE; /* Use case, by default */
35573580
block->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
35583581
block->b_syn_containedin = FALSE;
3582+
#ifdef FEAT_CONCEAL
3583+
block->b_syn_conceal = FALSE;
3584+
#endif
35593585

35603586
/* free the keywords */
35613587
clear_keywtab(&block->b_keywtab);
@@ -4543,7 +4569,8 @@ get_group_name(
45434569
get_syn_options(
45444570
char_u *arg, /* next argument to be checked */
45454571
syn_opt_arg_T *opt, /* various things */
4546-
int *conceal_char UNUSED)
4572+
int *conceal_char UNUSED,
4573+
int skip) /* TRUE if skipping over command */
45474574
{
45484575
char_u *gname_start, *gname;
45494576
int syn_id;
@@ -4626,17 +4653,17 @@ get_syn_options(
46264653
EMSG(_("E395: contains argument not accepted here"));
46274654
return NULL;
46284655
}
4629-
if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
4656+
if (get_id_list(&arg, 8, &opt->cont_list, skip) == FAIL)
46304657
return NULL;
46314658
}
46324659
else if (flagtab[fidx].argtype == 2)
46334660
{
4634-
if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
4661+
if (get_id_list(&arg, 11, &opt->cont_in_list, skip) == FAIL)
46354662
return NULL;
46364663
}
46374664
else if (flagtab[fidx].argtype == 3)
46384665
{
4639-
if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
4666+
if (get_id_list(&arg, 9, &opt->next_list, skip) == FAIL)
46404667
return NULL;
46414668
}
46424669
else if (flagtab[fidx].argtype == 11 && arg[5] == '=')
@@ -4846,7 +4873,10 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED)
48464873

48474874
if (rest != NULL)
48484875
{
4849-
syn_id = syn_check_group(arg, (int)(group_name_end - arg));
4876+
if (eap->skip)
4877+
syn_id = -1;
4878+
else
4879+
syn_id = syn_check_group(arg, (int)(group_name_end - arg));
48504880
if (syn_id != 0)
48514881
/* allocate a buffer, for removing backslashes in the keyword */
48524882
keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
@@ -4868,7 +4898,8 @@ syn_cmd_keyword(exarg_T *eap, int syncing UNUSED)
48684898
p = keyword_copy;
48694899
for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest))
48704900
{
4871-
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
4901+
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char,
4902+
eap->skip);
48724903
if (rest == NULL || ends_excmd(*rest))
48734904
break;
48744905
/* Copy the keyword, removing backslashes, and add a NUL. */
@@ -4981,7 +5012,7 @@ syn_cmd_match(
49815012
syn_opt_arg.cont_list = NULL;
49825013
syn_opt_arg.cont_in_list = NULL;
49835014
syn_opt_arg.next_list = NULL;
4984-
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
5015+
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
49855016

49865017
/* get the pattern. */
49875018
init_syn_patterns();
@@ -4991,7 +5022,7 @@ syn_cmd_match(
49915022
syn_opt_arg.flags |= HL_HAS_EOL;
49925023

49935024
/* Get options after the pattern */
4994-
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
5025+
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
49955026

49965027
if (rest != NULL) /* all arguments are valid */
49975028
{
@@ -5117,7 +5148,7 @@ syn_cmd_region(
51175148
while (rest != NULL && !ends_excmd(*rest))
51185149
{
51195150
/* Check for option arguments */
5120-
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
5151+
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
51215152
if (rest == NULL || ends_excmd(*rest))
51225153
break;
51235154

@@ -5628,12 +5659,13 @@ syn_cmd_cluster(exarg_T *eap, int syncing UNUSED)
56285659
break;
56295660

56305661
clstr_list = NULL;
5631-
if (get_id_list(&rest, opt_len, &clstr_list) == FAIL)
5662+
if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL)
56325663
{
56335664
EMSG2(_(e_invarg2), rest);
56345665
break;
56355666
}
5636-
syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
5667+
if (scl_id >= 0)
5668+
syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
56375669
&clstr_list, list_op);
56385670
got_clstr = TRUE;
56395671
}
@@ -5931,8 +5963,9 @@ syn_cmd_sync(exarg_T *eap, int syncing UNUSED)
59315963
get_id_list(
59325964
char_u **arg,
59335965
int keylen, /* length of keyword */
5934-
short **list) /* where to store the resulting list, if not
5966+
short **list, /* where to store the resulting list, if not
59355967
NULL, the list is silently skipped! */
5968+
int skip)
59365969
{
59375970
char_u *p = NULL;
59385971
char_u *end;
@@ -6015,7 +6048,8 @@ get_id_list(
60156048
}
60166049
else if (name[1] == '@')
60176050
{
6018-
id = syn_check_cluster(name + 2, (int)(end - p - 1));
6051+
if (!skip)
6052+
id = syn_check_cluster(name + 2, (int)(end - p - 1));
60196053
}
60206054
else
60216055
{

src/testdir/test_syntax.vim

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,134 @@ func Test_syntax_completion()
162162
call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx')
163163
call assert_match('^"syn match Boolean Character ', @:)
164164
endfunc
165+
166+
func Test_syntax_arg_skipped()
167+
syn clear
168+
syntax case ignore
169+
if 0
170+
syntax case match
171+
endif
172+
call assert_match('case ignore', execute('syntax case'))
173+
174+
syn keyword Foo foo
175+
call assert_match('Foo', execute('syntax'))
176+
syn clear
177+
call assert_match('case match', execute('syntax case'))
178+
call assert_notmatch('Foo', execute('syntax'))
179+
180+
if has('conceal')
181+
syn clear
182+
syntax conceal on
183+
if 0
184+
syntax conceal off
185+
endif
186+
call assert_match('conceal on', execute('syntax conceal'))
187+
syn clear
188+
call assert_match('conceal off', execute('syntax conceal'))
189+
endif
190+
191+
syntax region Tar start=/</ end=/>/
192+
if 0
193+
syntax region NotTest start=/</ end=/>/ contains=@Spell
194+
endif
195+
call assert_match('Tar', execute('syntax'))
196+
call assert_notmatch('NotTest', execute('syntax'))
197+
call assert_notmatch('Spell', execute('syntax'))
198+
199+
hi Foo ctermfg=blue
200+
let a = execute('hi Foo')
201+
if 0
202+
syntax rest
203+
endif
204+
call assert_equal(a, execute('hi Foo'))
205+
206+
set ft=tags
207+
syn off
208+
if 0
209+
syntax enable
210+
endif
211+
call assert_match('No Syntax items defined', execute('syntax'))
212+
syntax enable
213+
call assert_match('tagComment', execute('syntax'))
214+
set ft=
215+
216+
syn clear
217+
if 0
218+
syntax include @Spell nothing
219+
endif
220+
call assert_notmatch('Spell', execute('syntax'))
221+
222+
syn clear
223+
syn iskeyword 48-57,$,_
224+
call assert_match('48-57,$,_', execute('syntax iskeyword'))
225+
if 0
226+
syn clear
227+
syn iskeyword clear
228+
endif
229+
call assert_match('48-57,$,_', execute('syntax iskeyword'))
230+
syn iskeyword clear
231+
call assert_match('not set', execute('syntax iskeyword'))
232+
syn iskeyword 48-57,$,_
233+
syn clear
234+
call assert_match('not set', execute('syntax iskeyword'))
235+
236+
syn clear
237+
syn keyword Foo foo
238+
if 0
239+
syn keyword NotAdded bar
240+
endif
241+
call assert_match('Foo', execute('syntax'))
242+
call assert_notmatch('NotAdded', execute('highlight'))
243+
244+
syn clear
245+
syn keyword Foo foo
246+
call assert_match('Foo', execute('syntax'))
247+
call assert_match('Foo', execute('syntax list'))
248+
call assert_notmatch('Foo', execute('if 0 | syntax | endif'))
249+
call assert_notmatch('Foo', execute('if 0 | syntax list | endif'))
250+
251+
syn clear
252+
syn match Fopi /asdf/
253+
if 0
254+
syn match Fopx /asdf/
255+
endif
256+
call assert_match('Fopi', execute('syntax'))
257+
call assert_notmatch('Fopx', execute('syntax'))
258+
259+
syn clear
260+
syn spell toplevel
261+
call assert_match('spell toplevel', execute('syntax spell'))
262+
if 0
263+
syn spell notoplevel
264+
endif
265+
call assert_match('spell toplevel', execute('syntax spell'))
266+
syn spell notoplevel
267+
call assert_match('spell notoplevel', execute('syntax spell'))
268+
syn spell default
269+
call assert_match('spell default', execute('syntax spell'))
270+
271+
syn clear
272+
if 0
273+
syntax cluster Spell
274+
endif
275+
call assert_notmatch('Spell', execute('syntax'))
276+
277+
syn clear
278+
syn keyword Foo foo
279+
syn sync ccomment
280+
syn sync maxlines=5
281+
if 0
282+
syn sync maxlines=11
283+
endif
284+
call assert_match('on C-style comments', execute('syntax sync'))
285+
call assert_match('maximal 5 lines', execute('syntax sync'))
286+
syn clear
287+
syn keyword Foo foo
288+
if 0
289+
syn sync ccomment
290+
endif
291+
call assert_notmatch('on C-style comments', execute('syntax sync'))
292+
293+
syn clear
294+
endfunc
295+

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
198,
767769
/**/
768770
197,
769771
/**/

0 commit comments

Comments
 (0)