Sublime Forum

BracketHighlighter2 BETA Branch

#35

[quote=“iamntz”]Ok, so, as i said, me dumb :smiley:
I’m trying to make ST to also highlight if/endif foreach/endforeach and so on in php. What i have now (after like 50 different combinations or so) is this:

open": "(^if|foreach|while.+:$)", "close": "(^endif|endforeach|endwhile;$)",

But will not match correctly what i need (php have two ways of doing blocks; one is with if/endif and the other is with curly braces)

However, if i’ll do only this:

"open": "(^if.+:$)", "close": "(^endif;$)",

works good…ish. Because will make things red (which is an error) when i focus inside of the condition:

While things are peachy when i’m inside of the block:

What do i do wrong?

Thanks![/quote]

You are doing nothing wrong. What you need is a bracket plugin that taps into the compare event. During that event, you would need to compare the values to help sort out which closing bracket goes with which opening bracket. Give me an hour or so and I will try and show you what I mean. You are diving into undocumented awesomeness.

0 Likes

#36

Okay, I got to it quite a bit earlier…

Tweak this to your liking:
[pre=#2D2D2D] {
“name”: “php_keywords”,
“open”: “^\s*(if|foreach|while.+:$)”,
“close”: “^\s*(endif|endforeach|endwhile;$)”,
“icon”: “dot”,
“color”: “brackethighlighter.tag”,
“style”: “underline”,
“language_filter”: “whitelist”,
“scope_exclude”: “string”, “comment”],
“language_list”: “HTML”, “HTML 5”, “XML”, “PHP”, “HTML+CFML”, “ColdFusion”, “ColdFusionCFC”],
“plugin_library”: “User.phpkeywords”,
“enabled”: true
},[/pre]

Here is the awesome sauce…save as User/phpkeywords.py
[pre=#2D2D2D]def compare(name, first, second, bfr):
return “end” + bfrfirst.begin:first.end] == bfrsecond.begin:second.end][/pre]

Not so bad eh?

0 Likes

#37

is it a default behaviour for Sublime to add icon in the gutter for each line of a multiline underlined (mouthful) region, or it’s something you control?
i found myself exploitinhg BH2 in attempt to match Obj-C @interface @implementation directives and noticed if i use style:underline for each line of the opening “bracket” there’s an icon in gutter, while the same is not true for outline, solid (icon only on first line).

0 Likes

#38

Sorry, got a little careless:

[pre=#2D2D2D]def compare(name, first, second, bfr):
opening = bfrfirst.begin:first.end]
closing = bfrsecond.begin:second.end]
match = False
if opening.startswith(“while”):
if closing.startswith(“endwhile”):
match = True
else:
match = “end” + bfrfirst.begin:first.end] == bfrsecond.begin:second.end]
return match[/pre]

That should be better.

0 Likes

#39

[quote=“vitaLee”]is it a default behaviour for Sublime to add icon in the gutter for each line of a multiline underlined (mouthful) region, or it’s something you control?
i found myself exploitinhg BH2 in attempt to match Obj-C @interface @implementation directives and noticed if i use style:underline for each line of the opening “bracket” there’s an icon in gutter, while the same is not true for outline, solid (icon only on first line).[/quote]

Underline is a trick. It isn’t like a normal region. There is no underline style really. There is an option in Sublime that says if a region is size 0, you can render it as an underline. So, to simulate an underline region, I take region X, Y and break it up into a series of zero size regions. So really an underline (y-x) regions, not one. That is why multi-line will show multiple icons. Because each underlined character is its own region.

0 Likes

#40

Thanks! Works… partially :smile:

because it also match if(){} expressions (and it shouldn’t)

what i came up is this pattern:

            "open": "^\\s*(if|foreach|while).*:$",
            "close": "^\\s*(endif|endforeach|endwhile;$)"

Thing is… while in regexbuddy works just fine, in editor it doesn’t. Most likely i do some escaping wrong. Any idea which is that? Thanks!

Btw, i noticed that if there is an error somewhere in the config file, the plugin stop to works until i restart ST. It’s a bug, a feature or a bit of both? :smiley:

0 Likes

#41

[quote=“iamntz”]Thanks! Works… partially :smile:

because it also match if(){} expressions (and it shouldn’t)

what i came up is this pattern:

            "open": "^\\s*(if|foreach|while).*:$",
            "close": "^\\s*(endif|endforeach|endwhile;$)"

Thing is… while in regexbuddy works just fine, in editor it doesn’t. Most likely i do some escaping wrong. Any idea which is that? Thanks!

Btw, i noticed that if there is an error somewhere in the config file, the plugin stop to works until i restart ST. It’s a bug, a feature or a bit of both? :smiley:[/quote]

I need to think about this. Basically the open regex and close regex occur on separate passes. So for “if():” the open regex gobbles up “(” and “)”, but the close pass finds “)”. So when the brackets get resolved, it can’t pair up “)”, because the open got gobbled up in “if():”.

Basically, the this is a case where the open regex intersects with the close. I need time to think how to resolve this issue.

As for the plugin stopping working on bad settings file? I will have to think about how to gracefully handle that as well.

0 Likes

#42

@iamntz
I need to change the algorithm to do opening and closing in one pass. I have it working on my computer, but I need to stream line it. I guess it will actually be a little quicker this way.

I will let you know when it is done, maybe sometime in the next couple of days.

0 Likes

#43

I survived about 4-5 years without that highlight, I guess i’ll handle it few more days! :mrgreen:

Thanks!

0 Likes

#44

Dunno what you doing exactly but look ahead / behinds?

0 Likes

#45

Yes lookaheads will help him because they won’t capture, and can allow things like “()” to be used twice, but regardless it is probably better to do find opening and closing in one shot to limit confusion.

With the current implementation of processing opening and closing separately, it is easy for a user to not really understand what is happening. They expect if they capture something in opening, it shouldn’t be captured in closing.

I should have a fix posted in a couple of minutes. I will also post a solution for your problem @imantz using lookaheads.

0 Likes

#46

Fix is in on the alpha branch.

Based on your earlier config, try this (I am not entirely sure what you are looking for, so I have just adapted your earlier post):

[pre=#2D2D2D] {
“name”: “php_keywords”,
“open”: “^\s*\b(if|foreach|while)\b(?=.:$)",
“close”: "^\s
\b(endif\b|endforeach\b|endwhile(?=;$))”,
“icon”: “dot”,
“color”: “brackethighlighter.tag”,
“style”: “underline”,
“language_filter”: “whitelist”,
“scope_exclude”: “string”, “comment”],
“language_list”: “HTML”, “HTML 5”, “XML”, “PHP”, “HTML+CFML”, “ColdFusion”, “ColdFusionCFC”],
“plugin_library”: “User.phpkeywords”,
“enabled”: true
},[/pre]

A much simplier phpkeywords.py now:
[pre=#2D2D2D]def compare(name, first, second, bfr):
return “end” + bfrfirst.begin:first.end].lower() == bfrsecond.begin:second.end].lower()[/pre]

Just to be safe, restart ST2 when you update BH to the latest commit.

Edit: The regex is a little sloppy and can be cleaned up, but it is fine for a starting point.

0 Likes

#47

Yes, lookaheads might help but the problem is they won’t capture.
The consequence of that will be if later you’d like to take advantage of other features like “select between brackets”, “remove brackets”, “go to opening/closing bracket” you’ll have problems with leftovers that were’t captured, etc…

0 Likes

#48

[quote=“vitaLee”]Yes, lookaheads might help but the problem is they won’t capture.
The consequence of that will be if later you’d like to take advantage of other features like “select between brackets”, “remove brackets”, “go to opening/closing bracket” you’ll have problems with leftovers that were’t captured, etc…[/quote]

Yes, there will be a tradeoff. If you use lookaheads, “select between brackets” will grab the “()” brackets which may not be desirable. If you don’t use the lookaheads. BH will not match the “()”. The good news is I fixed the issue where BH would find the closing bracket twice, now it will just ignore it.

The tradeoff is a limitation of BH. The needed complexity of recursive bracket matching to overcome this I don’t think is worth it, but it could be a possibility in the future if it is really required, but I will push back on it for now.

0 Likes

#49

oh @iamntz, you can use the old PHP configuration if you want to capture the round brackets. BH supports that now. I just posted the other because @castles_made_of_sand mentioned the lookaheads. It is a good example of how you can workaround certain scenarios.

0 Likes

#50

You rock! Works beautiful. Thanks a lot!

0 Likes

#51

I admit, I am a bit surprised that that was the first real bug discovered; I expected more :smiley:.

As for a bad settings file causing BH to stop, I will try and put in a catch to keep it from exiting the script. I will see if I can keep the BH thread functional. Worse case scenario, I can add a restart command to start it again.

0 Likes

#52

@iamntz
What kind of settings errors were you talking about. Before I approach this, I want to make sure I understand what kind bad settings issues I should be looking into.

0 Likes

#53

Well, not sure. When i tried different patterns on that if/endif thing i noticed that a bad regex will stop highlight everywhere. The thing is i can’t reproduce it, it’s some kind of Lance Armstrong bug :smiley:

I’ll let you know if i will figure out.

0 Likes

#54

No biggie, just let me know if/when you can pinpoint it.

I haven’t spent much time hardening the plugin against bad settings inputs yet. This is because I haven’t finalized the settings file yet. If/when I separate style stuff from bracket definitions, it will probably change a lot of stuff.

As I get closer to a beta, hopefully a lot of that will get cleared up.

0 Likes