Sublime Forum

Python scope for braces ()

#1

Hello. I’ve modified ‘Python.tmLanguage’ - in a slightly ad-hoc fashion :laughing: - but it behaves as I want in terms of scope, colourization.

I end up with a number of bracket pairs ( ) which are still scoped as ‘source.python’ - the screenshot may help…

Because they are still scoped as ‘source.python’ I figure it may be possible to create a scope for them, by adding *something *right towards the end of the tmLanguage file(?). That is, i need an expression that will grab an opening ( any text here, and closing ). Is this possible? Or is it likely to create ‘havoc’?

I realise that ‘blah.something(other())’ will cause issues (nested brackets); but, in principle, is my target achievable? Andy.


0 Likes

#2

You can create a scope for anything. You just have to construct the rules well. In order to scope them, I would scope them at the same time the function method gets scoped. The way the current Python language is set up, you could even scope the nested ones as well. You would have to handle the non function “()” ones in a separate rule if you wanted to scope them.

0 Likes

#3

Hello @facelessuser, thank you.

I’ve been struggling to fully understand the code you provided me with previously. Can we pretend I’m a bit simple :wink: and describe one or two things pl?

  1. Why is ‘meta.function-call.python’ **nested **within the ‘dict’ for the st2-api? I can understand it following the ‘st2-api’, as something which is not caught within this would then be caught as ‘meta.function-call’.
  2. Is it not possible to modify ‘meta.function-call’ so that it only captures the single word preceding the brackets()?
  3. To achieve this, would modifying (or deleting!) the definition for ‘dotted.name’ help?
  4. What is the purpose of ‘generic_object_names’ that follows?

Sorry to go over this again, but the documentation is minimal. Andy.

<key>st2_api</key> <dict> <key>begin</key> <string>(?:\.)?(size|substr|begin_edit|end_edit|insert|erase|replace|sel|line|full_line|lines|split_by_newlines|word|find|find_all|rowcol|text_point)\s*(?=\()</string> <key>beginCaptures</key> <dict> <key>1</key> <dict> <key>name</key> <string>meta.function-call.st2-api.python</string> </dict> </dict> <key>end</key> <string>(\))</string> <key>endCaptures</key> <dict> <key>1</key> <dict> <key>name</key> <string>punctuation.definition.arguments.end.python</string> </dict> </dict> <key>name</key> <string>meta.function-call.python</string> <key>patterns</key> <array> <dict> <key>begin</key> <string>(?=[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*\s*\()</string> <key>end</key> <string>(?=\s*\()</string> <key>patterns</key> <array> <dict> <key>include</key> <string>#dotted_name</string> </dict> </array> </dict> <dict> <key>begin</key> <string>(\()</string> <key>beginCaptures</key> <dict> <key>1</key> <dict> <key>name</key> <string>punctuation.definition.arguments.begin.python</string> </dict> </dict> <key>contentName</key> <string>meta.function-call.arguments.python</string> <key>end</key> <string>(?=\))</string> <key>patterns</key> <array> <dict> <key>include</key> <string>#keyword_arguments</string> </dict> <dict> <key>include</key> <string>$self</string> </dict> </array> </dict> </array> </dict> <key>generic_object_names</key> <dict> <key>match</key> <string>(\.\b([A-Za-z_][A-Za-z0-9_]*)\b(?!\()|\b([A-Za-z_][A-Za-z0-9_]*)\b\.)</string> </dict>

0 Likes

#4

It is nested under the the dict under beginCaptures. What that tells the syntax highlighter is that once you find the begin rule highlight the following groups with these scopes.

So, here I am saying that in the begin rule, highlight group 1 with the API scope:

<dict> <key>1</key> <dict> <key>name</key> <string>meta.function-call.st2-api.python</string> </dict> </dict>

So basically group 1 is the work before the bracket.

So if I wanted to only highlight the word only as meta.function.call, you will notice that we have a beginCaptures and endCaptures followed by one more key that gives the entire begin and end a meta.function-call.python scope. I have marked it below with ** <==Remove Me**. This was how Python did it before I modified it. I just added an extra rule in begin capture to give an additional API scope to the word only. By removing those three lines, I believe it should still highlight the word with the function-call and the API scope because of the beginCapture rule, and it will only be applied to the word.

<key>begin</key> <string>(?:\.)?(size|substr|begin_edit|end_edit|insert|erase|replace|sel|line|full_line|lines|split_by_newlines|word|find|find_all|rowcol|text_point)\s*(?=\()</string> <key>beginCaptures</key> <dict> <key>1</key> <dict> <key>name</key> <string>meta.function-call.st2-api.python</string> </dict> </dict> <key>end</key> <string>(\))</string> <key>endCaptures</key> <dict> <key>1</key> <dict> <key>name</key> <string>punctuation.definition.arguments.end.python</string> </dict> </dict> <key>name</key> <==Remove Me <string>meta.function-call.python</string> <==Remove Me <key>patterns</key> <==Remove Me

The generic_object_names as you can see is meant to capture dot members of an object but assign no scope to them.

<key>generic_object_names</key> <dict> <key>match</key> <string>(\.\b([A-Za-z_][A-Za-z0-9_]*)\b(?!\(|\)|\b([A-Za-z_][A-Za-z0-9_]*)\b\.)</string> </dict>

They automatically get python.source applied, but no additional scoping.
I define it in the repository (order does not matter because it is just a place to define rules that can be included in the main dict), and then I include it in key locations to capture them so they don’t get scoped along with things like function calls, or mistaken as a system name etc. because print is not the same thing as obj.print etc.

I hope that makes some sense. I don’t really have more time right now to explain further or to test anything out, but hopefully I have helped.

0 Likes

#5

You cannot remove the three lines I mentioned earlier, just make the string key empty:

<key>name</key> <string></string> <key>patterns</key>

There also seems to be some additional scoping of the “(” bracket as well deeper in (meta.function-call.arguments.python), I don’t have time to sort out how to leave the bracket alone, but it can be done.

0 Likes

#6

Hello @facelessuser and thanks again :smile:. I will also have to look at this again tomorrow.

I’ve abandoned my version for the mo and have started with your ‘.tmLanguage’. The main thing I’m interested in changing is to scope for the st-api ONLY if preceded by a dot.

That is, ‘begin_edit()’ should fall into meta.function-call, but ‘spam.begin_edit()’ should see ‘begin_edit’ scoped as st-api. I tried replacing your (?:.)? with the second ? removed, {1} and just . - to no avail. I suspect I need to modify in a few places… :question:

Regards. Tomorrow. Andy.

0 Likes

#7

[quote=“agibsonsw”]Hello @facelessuser and thanks again :smile:. I will also have to look at this again tomorrow.

I’ve abandoned my version for the mo and have started with your ‘.tmLanguage’. The main thing I’m interested in changing is to scope for the st-api ONLY if preceded by a dot.

That is, ‘begin_edit()’ should fall into meta.function-call, but ‘spam.begin_edit()’ should see ‘begin_edit’ scoped as st-api. I tried replacing your (?:.)? with the second ? removed, {1} and just . - to no avail. I suspect I need to modify in a few places… :question:

Regards. Tomorrow. Andy.[/quote]

I will take a look later, it shouldn’t be too hard, but I haven’t looked into it yet.

0 Likes

#8

It wasn’t too bad, all I had to do was move the ST2 include before generic_objects, and include the requirement of API calls being preceded by a generic dot object, or just a dot.
Python.tmLanguage.zip (6.21 KB)

0 Likes

#9

Thank you: even more for me to get my head around :astonished: :wink:

So, to add other methods (with different scope) I would need to copy the whole of lines 1485-1552, and repeat the include (for st2_api)?

0 Likes

#10

[quote=“agibsonsw”]

Thank you: even more for me to get my head around :astonished: :wink:

So, to add other methods (with different scope) I would need to copy the whole of lines 1485-1552, and repeat the include (for st2_api)?[/quote]

Yeah, for now I guess. Some of it could probably be moved into a common location like under Repository so you could just include it, so then you would only have to copy a little. That would probably be much cleaner moving forward with lots of different method scopes.

0 Likes

#11

Ta, again :smile:

There’s mention of ‘tuple’ in the .tmLanguage file, but it doesn’t seem to catch anything. So I might struggle to get it to capture any remaining un-scoped braces ( ). Added: but you know this already!]

Still, I might give it a go :smile:

0 Likes