use syntect::parsing::{Scope, ScopeStack, SyntaxSetBuilder};
fn tag_left_open_after(source: &str, apply_end_pattern_last: bool) -> bool {
let grammar = format!(
r#"{{
"scopeName": "source.test",
"patterns": [
{{
"begin": "<",
"end": ">",
"name": "meta.tag.test",
"applyEndPatternLast": {apply_end_pattern_last},
"patterns": [
{{ "match": ".", "name": "text.body.test" }}
]
}}
]
}}"#
);
let definition = syntect_tmlanguage::load(&grammar).expect("translation failed");
let mut builder = SyntaxSetBuilder::new();
builder.add(definition);
let syntax_set = builder.build();
let syntax = syntax_set
.find_syntax_by_scope(Scope::new("source.test").unwrap())
.unwrap();
let mut parse_state = syntect::parsing::ParseState::new(syntax);
let mut scope_stack = ScopeStack::new();
for line in source.lines() {
let ops = parse_state.parse_line(line, &syntax_set).unwrap();
for (_, op) in ops {
scope_stack.apply(&op).unwrap();
}
}
scope_stack
.as_slice()
.iter()
.any(|s| s.build_string() == "meta.tag.test")
}
#[test]
fn default_end_pattern_is_tried_before_body_patterns() {
assert!(
!tag_left_open_after("<a>b", false),
"tag should have closed on '>' with the default ordering"
);
}
#[test]
fn apply_end_pattern_last_tries_body_patterns_before_end() {
assert!(
tag_left_open_after("<a>b", true),
"tag should still be open — its own body pattern should have consumed '>' before `end` got a chance"
);
}