patch 9.1.1077: included syntax items do not understand contains=TOP
Problem: Syntax engine interpreted contains=TOP as matching nothing
inside included files, since :syn-include forces HL_CONTAINED
on for every included item. After 8.2.2761, interprets
contains=TOP as contains=@INCLUDED, which is also not correct
since it doesn't respect exclusions, and doesn't work if there
is no @INCLUDED cluster.
Solution: revert patch 8.2.2761, instead track groups that have had
HL_CONTAINED forced, and interpret contains=TOP and
contains=CONTAINED using this. (Theodore Dubois)
fixes: #11277
closes: #16571
Signed-off-by: Theodore Dubois <tblodt@icloud.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/syntax.c b/src/syntax.c
index 6940aa1..34563aa 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -299,7 +299,7 @@
static void check_keepend(void);
static void update_si_end(stateitem_T *sip, int startcol, int force);
static short *copy_id_list(short *list);
-static int in_id_list(stateitem_T *item, short *cont_list, struct sp_syn *ssp, int contained);
+static int in_id_list(stateitem_T *item, short *cont_list, struct sp_syn *ssp, int flags);
static int push_current_state(int idx);
static void pop_current_state(void);
#ifdef FEAT_PROFILE
@@ -1943,7 +1943,7 @@
? !(spp->sp_flags & HL_CONTAINED)
: in_id_list(cur_si,
cur_si->si_cont_list, &spp->sp_syn,
- spp->sp_flags & HL_CONTAINED))))
+ spp->sp_flags))))
{
int r;
@@ -3269,7 +3269,7 @@
: (cur_si == NULL
? !(kp->flags & HL_CONTAINED)
: in_id_list(cur_si, cur_si->si_cont_list,
- &kp->k_syn, kp->flags & HL_CONTAINED)))
+ &kp->k_syn, kp->flags)))
{
*endcolp = startcol + kwlen;
*flagsp = kp->flags;
@@ -4681,7 +4681,7 @@
{
if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
return;
- *flagsp |= HL_CONTAINED;
+ *flagsp |= HL_CONTAINED | HL_INCLUDED_TOPLEVEL;
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER)
{
// We have to alloc this, because syn_combine_list() will free it.
@@ -5969,17 +5969,12 @@
break;
}
if (name[1] == 'A')
- id = SYNID_ALLBUT + current_syn_inc_tag;
+ id = SYNID_ALLBUT;
else if (name[1] == 'T')
- {
- if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER)
- id = curwin->w_s->b_syn_topgrp;
- else
- id = SYNID_TOP + current_syn_inc_tag;
- }
+ id = SYNID_TOP;
else
- id = SYNID_CONTAINED + current_syn_inc_tag;
-
+ id = SYNID_CONTAINED;
+ id += current_syn_inc_tag;
}
else if (name[1] == '@')
{
@@ -6127,7 +6122,7 @@
stateitem_T *cur_si, // current item or NULL
short *list, // id list
struct sp_syn *ssp, // group id and ":syn include" tag of group
- int contained) // group id is contained
+ int flags) // group flags
{
int retval;
short *scl_list;
@@ -6135,6 +6130,7 @@
short id = ssp->id;
static int depth = 0;
int r;
+ int toplevel;
// If ssp has a "containedin" list and "cur_si" is in it, return TRUE.
if (cur_si != NULL && ssp->cont_in_list != NULL
@@ -6148,7 +6144,7 @@
// cur_si->si_idx is -1 for keywords, these never contain anything.
if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list,
&(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn),
- SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED))
+ SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags))
return TRUE;
}
@@ -6160,7 +6156,14 @@
* inside anything. Only allow not-contained groups.
*/
if (list == ID_LIST_ALL)
- return !contained;
+ return !(flags & HL_CONTAINED);
+
+ /*
+ * Is this top-level (i.e. not 'contained') in the file it was declared in?
+ * For included files, this is different from HL_CONTAINED, which is set
+ * unconditionally.
+ */
+ toplevel = !(flags & HL_CONTAINED) || (flags & HL_INCLUDED_TOPLEVEL);
/*
* If the first item is "ALLBUT", return TRUE if "id" is NOT in the
@@ -6179,13 +6182,13 @@
else if (item < SYNID_CONTAINED)
{
// TOP: accept all not-contained groups in the same file
- if (item - SYNID_TOP != ssp->inc_tag || contained)
+ if (item - SYNID_TOP != ssp->inc_tag || !toplevel)
return FALSE;
}
else
{
// CONTAINED: accept all contained groups in the same file
- if (item - SYNID_CONTAINED != ssp->inc_tag || !contained)
+ if (item - SYNID_CONTAINED != ssp->inc_tag || toplevel)
return FALSE;
}
item = *++list;
@@ -6209,7 +6212,7 @@
if (scl_list != NULL && depth < 30)
{
++depth;
- r = in_id_list(NULL, scl_list, ssp, contained);
+ r = in_id_list(NULL, scl_list, ssp, flags);
--depth;
if (r)
return retval;