-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect push/pop order when combining meta scopes, content scopes and pushing multiple things #51
Comments
I've done some work in the fix-test-bugs branch that makes things better. It cherry-picks fixes from @keith-hall's It doesn't fix this issue but it includes the fix to |
Nice one for investigating this - I'm glad my branch was helpful. I also prefer the first approach because I like the idea of the parser outputting operations :) And it would sure be a shame to have to rewrite everything just for one edge case. |
^ I pushed a commit that I think fixes this bug to my branch, but I don't know what the performance impact is, and it didn't fix as many tests as I thought. It fixed one ASP test, and possibly some tests in other languages but there's still lots of other failures. One thing I'm investigating now is that my model of how the syntax-level scopes are applied is borked. The ones that are done with things like |
From my testing, I think the top level scope behaviour is:
|
@keith-hall ok cool that matches my previous understanding except for the first point, which is the new thing I discovered. I'll need to think of how to implement that in a clean way, but it shouldn't be too difficult. At the moment I can't think of anything nice though. The way I have it now is nice in that it is just like any other |
I wonder if you could cheat and not deal with it in the parser, but instead don't let the scope stack become empty from a Pop operation, always keep one scope. |
@keith-hall that would possibly work in most cases but wouldn't work correctly in all due to the ability of I think in terms of reductions it works more like there being two different |
That's a good way of looking at it @trishume :) probably my idea would have caused duplicate scopes to appear if main is in terms of other minor syntax test failures, interestingly ST is able to ignore empty subpatterns sublimehq/Packages#830 apart from that, all other syntaxes except ASP and PHP are passing with flying colours, so great work! (I didn't look into the Markdown failure, but it was a nasty syntax with |
Hmmm that's interesting, I wonder how Sublime does that ignoring empty patterns thing. It's possible the Rust and LaTeX cases you mention are separate mechanisms, but I think they might be the same:
|
I tried changing the LaTeX pattern Is this behaviour something that syntect should try to emulate? I would argue that it isn't that important - very rarely are match patterns written like this, and I've fixed the Rust one, and can submit a PR to fix the LaTeX one too if we want. |
I've been looking at the ASP syntax a bit more, and I can't work out how it works in ST... And yet, I'm the one that wrote that syntax definition! Specifically, this match pattern never matches in syntect, because the So I had a go at re-writing the syntax def to avoid the prototype conflict, but unfortunately the result in syntect is the same. The only changes are to the `inside_block` and `html_inside_block` contexts and with a new `resume_inside_block` context. Click on this paragraph to see the new end of the `ASP.sublime-syntax` file. inside_block:
- match: '%>'
scope: punctuation.section.embedded.end.inside-block.asp
push: [resume_inside_block, html_inside_block]
with_prototype: # the with_prototype only applies to the last pushed context i.e. html_inside_block - https://forum.sublimetext.com/t/dev-build-3111/19240/17
- match: '(?=<%)'
pop: true
resume_inside_block:
- match: '(?=<%)'
set:
- match: '<%=?'
scope: punctuation.section.embedded.begin.inside-block.asp
pop: true
# with_prototype: # in ST, it works without this prototype. In syntect, it still doesn't work even with this prototype...
# - match: '<%=?'
# scope: punctuation.section.embedded.begin.inside-block.asp
# pop: true
html_inside_block:
- clear_scopes: true
- meta_scope: text.html.asp
- match: '\s+$' # eat whitespace so that the lookahead on the next match pattern can match the next line if appropriate
push:
- match: ^
pop: true
- match: '(\s*")?(?=[^<>]*>|\s+\w+=\s*")' # if the next occurrence of a < or > is a >, we are inside a tag. If it looks like an attribute is being defined, we are probably in a tag
scope: string.quoted.double.html punctuation.definition.string.end.html
push: # use a push and an include so that the root scope (text.html.basic) isn't applied
- meta_scope: meta.tag.after-embedded-asp.any.html
- include: scope:text.html.basic#tag-stuff
with_prototype:
- match: '(?=<%)'
pop: true
- match: '>'
scope: punctuation.definition.tag.end.html
set: scope:text.html.asp#html
with_prototype:
- match: '(?=<%)'
pop: true
- match: ''
push: scope:text.html.asp#html So it seems we're missing some special rules that ST has related to |
@keith-hall weird. Good detective work. One thing I might try to do is disassemble Sublime and see if I can figure out how it calls Oniguruma functions to see if it is using some fancy technique I don't know of. I may also re-read the Oniguruma docs to find all the options. As for |
This is the bug that is causing at least some, probably most to all of the ASP tests to fail (cc @keith-hall).
The model of the parser outputting only the pushes and pops doesn't hold up to well in some cases. @keith-hall fixed the case of the weird behaviour of
set
, but I found another.Consider the following section of the ASP syntax:
Sublime Text passes the following test:
Notice how when the
meta_content_scope
ofinside_class
is introduced afterClass
, it is introduced undermeta.class.asp meta.class.identifier.asp
.syntect
does not do this. It pushes theinside_class
meta_content_scope
on top, but then afterTestClass2
when it pops theclass_name
context it pops 2 scopes, thinking it is popping themeta_scope
ofclass_name
, but actually theinside_class
scopes are on top of the stack.I see two ways of approaching this:
set
is in Keith's set branch where they pop the early meta scopes and then re-apply them in the right order.I'm inclined to take the first route. My worry is that if done simply it will lead to a bunch of redundant popping and pushing the same thing again in the case when only one item is pushed. It's probably a good idea to have a fast path for that case, although it would probably require a bunch more code.
The text was updated successfully, but these errors were encountered: