mirror of
https://github.com/vim/vim.git
synced 2025-09-05 21:43:39 -04:00
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>
This commit is contained in:
parent
34e1e8de91
commit
f50d5364d7
41
src/syntax.c
41
src/syntax.c
@ -299,7 +299,7 @@ static void update_si_attr(int idx);
|
|||||||
static void check_keepend(void);
|
static void check_keepend(void);
|
||||||
static void update_si_end(stateitem_T *sip, int startcol, int force);
|
static void update_si_end(stateitem_T *sip, int startcol, int force);
|
||||||
static short *copy_id_list(short *list);
|
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 int push_current_state(int idx);
|
||||||
static void pop_current_state(void);
|
static void pop_current_state(void);
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
@ -1943,7 +1943,7 @@ syn_current_attr(
|
|||||||
? !(spp->sp_flags & HL_CONTAINED)
|
? !(spp->sp_flags & HL_CONTAINED)
|
||||||
: in_id_list(cur_si,
|
: in_id_list(cur_si,
|
||||||
cur_si->si_cont_list, &spp->sp_syn,
|
cur_si->si_cont_list, &spp->sp_syn,
|
||||||
spp->sp_flags & HL_CONTAINED))))
|
spp->sp_flags))))
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -3269,7 +3269,7 @@ check_keyword_id(
|
|||||||
: (cur_si == NULL
|
: (cur_si == NULL
|
||||||
? !(kp->flags & HL_CONTAINED)
|
? !(kp->flags & HL_CONTAINED)
|
||||||
: in_id_list(cur_si, cur_si->si_cont_list,
|
: 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;
|
*endcolp = startcol + kwlen;
|
||||||
*flagsp = kp->flags;
|
*flagsp = kp->flags;
|
||||||
@ -4681,7 +4681,7 @@ syn_incl_toplevel(int id, int *flagsp)
|
|||||||
{
|
{
|
||||||
if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
|
if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
|
||||||
return;
|
return;
|
||||||
*flagsp |= HL_CONTAINED;
|
*flagsp |= HL_CONTAINED | HL_INCLUDED_TOPLEVEL;
|
||||||
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER)
|
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER)
|
||||||
{
|
{
|
||||||
// We have to alloc this, because syn_combine_list() will free it.
|
// We have to alloc this, because syn_combine_list() will free it.
|
||||||
@ -5969,17 +5969,12 @@ get_id_list(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (name[1] == 'A')
|
if (name[1] == 'A')
|
||||||
id = SYNID_ALLBUT + current_syn_inc_tag;
|
id = SYNID_ALLBUT;
|
||||||
else if (name[1] == 'T')
|
else if (name[1] == 'T')
|
||||||
{
|
id = SYNID_TOP;
|
||||||
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER)
|
|
||||||
id = curwin->w_s->b_syn_topgrp;
|
|
||||||
else
|
else
|
||||||
id = SYNID_TOP + current_syn_inc_tag;
|
id = SYNID_CONTAINED;
|
||||||
}
|
id += current_syn_inc_tag;
|
||||||
else
|
|
||||||
id = SYNID_CONTAINED + current_syn_inc_tag;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (name[1] == '@')
|
else if (name[1] == '@')
|
||||||
{
|
{
|
||||||
@ -6127,7 +6122,7 @@ in_id_list(
|
|||||||
stateitem_T *cur_si, // current item or NULL
|
stateitem_T *cur_si, // current item or NULL
|
||||||
short *list, // id list
|
short *list, // id list
|
||||||
struct sp_syn *ssp, // group id and ":syn include" tag of group
|
struct sp_syn *ssp, // group id and ":syn include" tag of group
|
||||||
int contained) // group id is contained
|
int flags) // group flags
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
short *scl_list;
|
short *scl_list;
|
||||||
@ -6135,6 +6130,7 @@ in_id_list(
|
|||||||
short id = ssp->id;
|
short id = ssp->id;
|
||||||
static int depth = 0;
|
static int depth = 0;
|
||||||
int r;
|
int r;
|
||||||
|
int toplevel;
|
||||||
|
|
||||||
// If ssp has a "containedin" list and "cur_si" is in it, return TRUE.
|
// If ssp has a "containedin" list and "cur_si" is in it, return TRUE.
|
||||||
if (cur_si != NULL && ssp->cont_in_list != NULL
|
if (cur_si != NULL && ssp->cont_in_list != NULL
|
||||||
@ -6148,7 +6144,7 @@ in_id_list(
|
|||||||
// cur_si->si_idx is -1 for keywords, these never contain anything.
|
// 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,
|
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_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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6160,7 +6156,14 @@ in_id_list(
|
|||||||
* inside anything. Only allow not-contained groups.
|
* inside anything. Only allow not-contained groups.
|
||||||
*/
|
*/
|
||||||
if (list == ID_LIST_ALL)
|
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
|
* If the first item is "ALLBUT", return TRUE if "id" is NOT in the
|
||||||
@ -6179,13 +6182,13 @@ in_id_list(
|
|||||||
else if (item < SYNID_CONTAINED)
|
else if (item < SYNID_CONTAINED)
|
||||||
{
|
{
|
||||||
// TOP: accept all not-contained groups in the same file
|
// 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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// CONTAINED: accept all contained groups in the same file
|
// 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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
item = *++list;
|
item = *++list;
|
||||||
@ -6209,7 +6212,7 @@ in_id_list(
|
|||||||
if (scl_list != NULL && depth < 30)
|
if (scl_list != NULL && depth < 30)
|
||||||
{
|
{
|
||||||
++depth;
|
++depth;
|
||||||
r = in_id_list(NULL, scl_list, ssp, contained);
|
r = in_id_list(NULL, scl_list, ssp, flags);
|
||||||
--depth;
|
--depth;
|
||||||
if (r)
|
if (r)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -949,7 +949,7 @@ func Test_syn_contained_transparent()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_syn_include_contains_TOP()
|
func Test_syn_include_contains_TOP()
|
||||||
let l:case = "TOP in included syntax means its group list name"
|
let l:case = "TOP in included syntax refers to top level of that included syntax"
|
||||||
new
|
new
|
||||||
syntax include @INCLUDED syntax/c.vim
|
syntax include @INCLUDED syntax/c.vim
|
||||||
syntax region FencedCodeBlockC start=/```c/ end=/```/ contains=@INCLUDED
|
syntax region FencedCodeBlockC start=/```c/ end=/```/ contains=@INCLUDED
|
||||||
@ -964,6 +964,18 @@ func Test_syn_include_contains_TOP()
|
|||||||
bw!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_syn_include_contains_TOP_excluding()
|
||||||
|
new
|
||||||
|
syntax include @INCLUDED syntax/c.vim
|
||||||
|
syntax region FencedCodeBlockC start=/```c/ end=/```/ contains=@INCLUDED
|
||||||
|
|
||||||
|
call setline(1, ['```c', '#if 0', 'int', '#else', 'int', '#if', '#endif', '```' ])
|
||||||
|
let l:expected = ["cCppOutElse", "cConditional"]
|
||||||
|
eval AssertHighlightGroups(6, 1, l:expected, 1)
|
||||||
|
syntax clear
|
||||||
|
bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" This was using freed memory
|
" This was using freed memory
|
||||||
func Test_WinEnter_synstack_synID()
|
func Test_WinEnter_synstack_synID()
|
||||||
autocmd WinEnter * call synstack(line("."), col("."))
|
autocmd WinEnter * call synstack(line("."), col("."))
|
||||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1077,
|
||||||
/**/
|
/**/
|
||||||
1076,
|
1076,
|
||||||
/**/
|
/**/
|
||||||
|
@ -953,6 +953,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
|||||||
# define HL_TRANS_CONT 0x10000 // transparent item without contains arg
|
# define HL_TRANS_CONT 0x10000 // transparent item without contains arg
|
||||||
# define HL_CONCEAL 0x20000 // can be concealed
|
# define HL_CONCEAL 0x20000 // can be concealed
|
||||||
# define HL_CONCEALENDS 0x40000 // can be concealed
|
# define HL_CONCEALENDS 0x40000 // can be concealed
|
||||||
|
# define HL_INCLUDED_TOPLEVEL 0x80000 // toplevel item in included syntax, allowed by contains=TOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Values for 'options' argument in do_search() and searchit()
|
// Values for 'options' argument in do_search() and searchit()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user