Improve TS/TSX/JS syntax highlighting for parameters, types, and punctuation (#44532)

Gaauwe Rombouts , MrSubidubi , and Clay Tercek created

Relands https://github.com/zed-industries/zed/pull/43437

Release Notes:

- Refined syntax highlighting in JavaScript and TypeScript for better
visual distinction of types, parameters, and JSDoc elements

---------

Co-authored-by: MrSubidubi <dev@bahn.sh>
Co-authored-by: Clay Tercek <30105080+claytercek@users.noreply.github.com>

Change summary

crates/languages/src/javascript/highlights.scm | 107 +++++++++++++
crates/languages/src/jsdoc/highlights.scm      |   1 
crates/languages/src/tsx/highlights-jsx.scm    |   0 
crates/languages/src/tsx/highlights.scm        | 161 +++++++++++++++++++
crates/languages/src/typescript/highlights.scm | 134 ++++++++++++++++
5 files changed, 397 insertions(+), 6 deletions(-)

Detailed changes

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

@@ -2,6 +2,40 @@
 
 (identifier) @variable
 
+(call_expression
+  function: (member_expression
+    object: (identifier) @type.builtin
+    (#any-of?
+      @type.builtin
+      "Promise"
+      "Array"
+      "Object"
+      "Map"
+      "Set"
+      "WeakMap"
+      "WeakSet"
+      "Date"
+      "Error"
+      "TypeError"
+      "RangeError"
+      "SyntaxError"
+      "ReferenceError"
+      "EvalError"
+      "URIError"
+      "RegExp"
+      "Function"
+      "Number"
+      "String"
+      "Boolean"
+      "Symbol"
+      "BigInt"
+      "Proxy"
+      "ArrayBuffer"
+      "DataView"
+    )
+  )
+)
+
 ; Properties
 
 (property_identifier) @property
@@ -18,6 +52,12 @@
   function: (member_expression
       property: [(property_identifier) (private_property_identifier)] @function.method))
 
+(new_expression
+  constructor: (identifier) @type)
+
+(nested_type_identifier
+  module: (identifier) @type)
+
 ; Function and method definitions
 
 (function_expression
@@ -47,10 +87,45 @@
   left: (identifier) @function
   right: [(function_expression) (arrow_function)])
 
+; Parameters
+
+(required_parameter
+  (identifier) @variable.parameter)
+
+(required_parameter
+  (_
+    ([
+      (identifier)
+      (shorthand_property_identifier_pattern)
+    ]) @variable.parameter))
+
+(optional_parameter
+  (identifier) @variable.parameter)
+
+(optional_parameter
+  (_
+    ([
+      (identifier)
+      (shorthand_property_identifier_pattern)
+    ]) @variable.parameter))
+
+(catch_clause
+  parameter: (identifier) @variable.parameter)
+
+(index_signature
+  name: (identifier) @variable.parameter)
+
+(arrow_function
+  parameter: (identifier) @variable.parameter)
+
 ; Special identifiers
+;
+(class_declaration
+  (type_identifier) @type.class)
+
+(extends_clause
+  value: (identifier) @type.class)
 
-((identifier) @type
- (#match? @type "^[A-Z]"))
 (type_identifier) @type
 (predefined_type) @type.builtin
 
@@ -251,6 +326,34 @@
 (jsx_closing_element (identifier) @tag.jsx (#match? @tag.jsx "^[a-z][^.]*$"))
 (jsx_self_closing_element (identifier) @tag.jsx (#match? @tag.jsx "^[a-z][^.]*$"))
 
+(jsx_opening_element
+  [
+    (identifier) @type
+    (member_expression
+      object: (identifier) @type
+      property: (property_identifier) @type
+    )
+  ]
+)
+(jsx_closing_element
+  [
+    (identifier) @type
+    (member_expression
+      object: (identifier) @type
+      property: (property_identifier) @type
+    )
+  ]
+)
+(jsx_self_closing_element
+  [
+    (identifier) @type
+    (member_expression
+      object: (identifier) @type
+      property: (property_identifier) @type
+    )
+  ]
+)
+
 (jsx_attribute (property_identifier) @attribute.jsx)
 (jsx_opening_element (["<" ">"]) @punctuation.bracket.jsx)
 (jsx_closing_element (["</" ">"]) @punctuation.bracket.jsx)

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

@@ -2,6 +2,40 @@
 
 (identifier) @variable
 
+(call_expression
+  function: (member_expression
+    object: (identifier) @type.builtin
+    (#any-of?
+      @type.builtin
+      "Promise"
+      "Array"
+      "Object"
+      "Map"
+      "Set"
+      "WeakMap"
+      "WeakSet"
+      "Date"
+      "Error"
+      "TypeError"
+      "RangeError"
+      "SyntaxError"
+      "ReferenceError"
+      "EvalError"
+      "URIError"
+      "RegExp"
+      "Function"
+      "Number"
+      "String"
+      "Boolean"
+      "Symbol"
+      "BigInt"
+      "Proxy"
+      "ArrayBuffer"
+      "DataView"
+    )
+  )
+)
+
 ; Properties
 
 (property_identifier) @property
@@ -18,6 +52,12 @@
   function: (member_expression
     property: [(property_identifier) (private_property_identifier)] @function.method))
 
+(new_expression
+  constructor: (identifier) @type)
+
+(nested_type_identifier
+  module: (identifier) @type)
+
 ; Function and method definitions
 
 (function_expression
@@ -47,13 +87,68 @@
   left: (identifier) @function
   right: [(function_expression) (arrow_function)])
 
+; Parameters
+
+(required_parameter
+  (identifier) @variable.parameter)
+
+(required_parameter
+  (_
+    ([
+      (identifier)
+      (shorthand_property_identifier_pattern)
+    ]) @variable.parameter))
+
+(optional_parameter
+  (identifier) @variable.parameter)
+
+(optional_parameter
+  (_
+    ([
+      (identifier)
+      (shorthand_property_identifier_pattern)
+    ]) @variable.parameter))
+
+(catch_clause
+  parameter: (identifier) @variable.parameter)
+
+(index_signature
+  name: (identifier) @variable.parameter)
+
+(arrow_function
+  parameter: (identifier) @variable.parameter)
+
+(type_predicate
+  name: (identifier) @variable.parameter)
+
 ; Special identifiers
 
-((identifier) @type
- (#match? @type "^[A-Z]"))
+(type_annotation) @type
 (type_identifier) @type
 (predefined_type) @type.builtin
 
+(type_alias_declaration
+  (type_identifier) @type)
+
+(type_alias_declaration
+  value: (_
+    (type_identifier) @type))
+
+(interface_declaration
+  (type_identifier) @type)
+
+(class_declaration
+  (type_identifier) @type.class)
+
+(extends_clause
+  value: (identifier) @type.class)
+
+(extends_type_clause
+  type: (type_identifier) @type)
+
+(implements_clause
+  (type_identifier) @type)
+
 ([
   (identifier)
   (shorthand_property_identifier)
@@ -231,8 +326,42 @@
   "<" @punctuation.bracket
   ">" @punctuation.bracket)
 
+(type_parameters
+  "<" @punctuation.bracket
+  ">" @punctuation.bracket)
+
 (decorator "@" @punctuation.special)
 
+(union_type
+  ("|") @punctuation.special)
+
+(intersection_type
+  ("&") @punctuation.special)
+
+(type_annotation
+  (":") @punctuation.special)
+
+(index_signature
+  (":") @punctuation.special)
+
+(type_predicate_annotation
+  (":") @punctuation.special)
+
+(public_field_definition
+  ("?") @punctuation.special)
+
+(property_signature
+  ("?") @punctuation.special)
+
+(method_signature
+  ("?") @punctuation.special)
+
+(optional_parameter
+  ([
+    "?"
+    ":"
+  ]) @punctuation.special)
+
 ; Keywords
 
 [ "abstract"
@@ -257,6 +386,34 @@
 (jsx_closing_element (identifier) @tag.jsx (#match? @tag.jsx "^[a-z][^.]*$"))
 (jsx_self_closing_element (identifier) @tag.jsx (#match? @tag.jsx "^[a-z][^.]*$"))
 
+(jsx_opening_element
+  [
+    (identifier) @type
+    (member_expression
+      object: (identifier) @type
+      property: (property_identifier) @type
+    )
+  ]
+)
+(jsx_closing_element
+  [
+    (identifier) @type
+    (member_expression
+      object: (identifier) @type
+      property: (property_identifier) @type
+    )
+  ]
+)
+(jsx_self_closing_element
+  [
+    (identifier) @type
+    (member_expression
+      object: (identifier) @type
+      property: (property_identifier) @type
+    )
+  ]
+)
+
 (jsx_attribute (property_identifier) @attribute.jsx)
 (jsx_opening_element (["<" ">"]) @punctuation.bracket.jsx)
 (jsx_closing_element (["</" ">"]) @punctuation.bracket.jsx)

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

@@ -2,13 +2,69 @@
 
 (identifier) @variable
 
+(call_expression
+  function: (member_expression
+    object: (identifier) @type.builtin
+    (#any-of?
+      @type.builtin
+      "Promise"
+      "Array"
+      "Object"
+      "Map"
+      "Set"
+      "WeakMap"
+      "WeakSet"
+      "Date"
+      "Error"
+      "TypeError"
+      "RangeError"
+      "SyntaxError"
+      "ReferenceError"
+      "EvalError"
+      "URIError"
+      "RegExp"
+      "Function"
+      "Number"
+      "String"
+      "Boolean"
+      "Symbol"
+      "BigInt"
+      "Proxy"
+      "ArrayBuffer"
+      "DataView"
+    )
+  )
+)
+
 ; Special identifiers
 
-((identifier) @type
- (#match? @type "^[A-Z]"))
+(type_annotation) @type
+
 (type_identifier) @type
 (predefined_type) @type.builtin
 
+(type_alias_declaration
+  (type_identifier) @type)
+
+(type_alias_declaration
+  value: (_
+    (type_identifier) @type))
+
+(interface_declaration
+  (type_identifier) @type)
+
+(class_declaration
+  (type_identifier) @type.class)
+
+(extends_clause
+  value: (identifier) @type.class)
+
+(extends_type_clause
+  type: (type_identifier) @type)
+
+(implements_clause
+  (type_identifier) @type)
+
 ;; Enables ts-pretty-errors
 ;; The Lsp returns "snippets" of typescript, which are not valid typescript in totality,
 ;; but should still be highlighted
@@ -83,6 +139,12 @@
   function: (member_expression
     property: [(property_identifier) (private_property_identifier)] @function.method))
 
+(new_expression
+  constructor: (identifier) @type)
+
+(nested_type_identifier
+  module: (identifier) @type)
+
 ; Function and method definitions
 
 (function_expression
@@ -114,6 +176,40 @@
 
 (arrow_function) @function
 
+; Parameters
+
+(required_parameter
+  (identifier) @variable.parameter)
+
+(required_parameter
+  (_
+    ([
+      (identifier)
+      (shorthand_property_identifier_pattern)
+    ]) @variable.parameter))
+
+(optional_parameter
+  (identifier) @variable.parameter)
+
+(optional_parameter
+  (_
+    ([
+      (identifier)
+      (shorthand_property_identifier_pattern)
+    ]) @variable.parameter))
+
+(catch_clause
+  parameter: (identifier) @variable.parameter)
+
+(index_signature
+  name: (identifier) @variable.parameter)
+
+(arrow_function
+  parameter: (identifier) @variable.parameter)
+
+(type_predicate
+  name: (identifier) @variable.parameter)
+
 ; Literals
 
 (this) @variable.special
@@ -244,8 +340,42 @@
   "<" @punctuation.bracket
   ">" @punctuation.bracket)
 
+(type_parameters
+  "<" @punctuation.bracket
+  ">" @punctuation.bracket)
+
 (decorator "@" @punctuation.special)
 
+(union_type
+  ("|") @punctuation.special)
+
+(intersection_type
+  ("&") @punctuation.special)
+
+(type_annotation
+  (":") @punctuation.special)
+
+(index_signature
+  (":") @punctuation.special)
+
+(type_predicate_annotation
+  (":") @punctuation.special)
+
+(public_field_definition
+  ("?") @punctuation.special)
+
+(property_signature
+  ("?") @punctuation.special)
+
+(method_signature
+  ("?") @punctuation.special)
+
+(optional_parameter
+  ([
+    "?"
+    ":"
+  ]) @punctuation.special)
+
 ; Keywords
 
 [