python: Improve function syntax highlighting (#20487)

Carroll Wainwright created

Release Notes:

- Differentiate between function and method calls and definitions.
`function.definition` matches the highlight for e.g. rust,
`function.call` is new.
- Likewise differentiate between class calls and class definitions.
- Better highlighting of function decorators (the `@` symbol is
punctuation, and now the decorator itself has a `function.decorator`
tag)
- Make `cls` a special variable (like `self`)
- Add `ellipsis` as a built-in constant

Note that most themes do not currently make use of the
`function.definition` tags, and none make use of the
`type.class.definition` tag. Hopefully more themes will pick this up.

*Before:*
<img width="248" alt="image"
src="https://github.com/user-attachments/assets/550ccd3d-594c-413a-b543-ef9caf39eee1">


*After:*
<img width="245" alt="image"
src="https://github.com/user-attachments/assets/47aa43b1-006b-4f9f-9029-510880f390ea">

Change summary

crates/languages/src/python/highlights.scm | 34 ++++++++++++++++-------
1 file changed, 23 insertions(+), 11 deletions(-)

Detailed changes

crates/languages/src/python/highlights.scm 🔗

@@ -5,6 +5,14 @@
 ; Type alias
 (type_alias_statement "type" @keyword)
 
+; Identifier naming conventions
+
+((identifier) @type.class
+ (#match? @type.class "^[A-Z]"))
+
+((identifier) @constant
+ (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
+
 ; TypeVar with constraints in type parameters
 (type
   (tuple (identifier) @type)
@@ -12,25 +20,28 @@
 
 ; Function calls
 
-(decorator) @function
+(decorator
+  "@" @punctuation.special
+  (identifier) @function.decorator)
 
 (call
-  function: (attribute attribute: (identifier) @function.method))
+  function: (attribute attribute: (identifier) @function.method.call))
 (call
-  function: (identifier) @function)
+  function: (identifier) @function.call)
 
-; Function definitions
+; Function and class definitions
 
 (function_definition
-  name: (identifier) @function)
+  name: (identifier) @function.definition)
 
-; Identifier naming conventions
+; Class definitions and calling: needs to come after the regex matching above
 
-((identifier) @type
- (#match? @type "^[A-Z]"))
+(class_definition
+  name: (identifier) @type.class.definition)
 
-((identifier) @constant
- (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
+(call
+  function: (identifier) @type.class.call
+  (#match? @type.class.call "^[A-Z][A-Z0-9_]*[a-z]"))
 
 ; Builtin functions
 
@@ -46,6 +57,7 @@
   (none)
   (true)
   (false)
+  (ellipsis)
 ] @constant.builtin
 
 [
@@ -58,7 +70,7 @@
 [
   (parameters (identifier) @variable.special)
   (attribute (identifier) @variable.special)
-  (#match? @variable.special "^self$")
+  (#match? @variable.special "^self|cls$")
 ]
 
 (comment) @comment