Improve gdscript-ts-mode highlighting with (#165)

* Added class_name highlighting
* Simplified keyword highlighting
* Added missing for/in keywords
* Added builtin types support
* Fixed class_definition face; treat preload() as builtin
* Fixed int/bool/float/void not being treated as builtin types
* Fixed escape sequences highlighting
This commit is contained in:
Alexandr Semenov
2025-04-20 19:18:34 +05:00
committed by GitHub
parent 3f3739dd88
commit 1938aa7e2d

View File

@@ -68,64 +68,121 @@ It must be a function with two arguments: TYPE and NAME.")
(if (string= type "class")
"*class definition*"
"*function definition*"))
;;; Keywords
(defvar gdscript-ts--treesit-keywords '("and" "as" "break" "class" "class_name"
"const" "continue" "elif" "else" "enum" "export" "extends" "for" "func" "if" "in" "is"
"master" "match" "not" "onready" "or" "pass" "puppet" "remote" "remotesync" "return" "setget" "signal"
"var" "while"))
(defvar gdscript-ts--keyword-regex
(rx bot (| "func" "var" "const" "set" "get" "setget" "signal" "extends"
"match" "if" "elif" "else" "for" "in" "while" "break" "continue"
"pass" "return" "when" "yield" "await"
"class" "class_name" "abstract" "is" "onready" "tool" "static"
"export" "as" "void" "enum" "assert" "breakpoint"
"sync" "remote" "master" "puppet"
"remotesync" "mastersync" "puppetsync"
"trait" "namespace" "super"
"and" "or" "not"
"await" "yield" "self") eot))
;;; Types
(defvar gdscript-ts--builtin-type-regex
"\\`\\(int\\|bool\\|float\\|void\\|Vector2\\|Vector2i\\|Vector3\\|Vector3i\\|Vector4\\|Vector4i\\|Color\\|Rect2\\|Rect2i\\|Array\\|Basis\\|Dictionary\\|Plane\\|Quat\\|RID\\|Rect3\\|Transform\\|Transform2D\\|Transform3D\\|AABB\\|String\\|Color\\|NodePath\\|PoolByteArray\\|PoolIntArray\\|PoolRealArray\\|PoolStringArray\\|PoolVector2Array\\|PoolVector3Array\\|PoolColorArray\\|bool\\|int\\|float\\|Signal\\|Callable\\|StringName\\|Quaternion\\|Projection\\|PackedByteArray\\|PackedInt32Array\\|PackedInt64Array\\|PackedFloat32Array\\|PackedFloat64Array\\|PackedStringArray\\|PackedVector2Array\\|PackedVector2iArray\\|PackedVector3Array\\|PackedVector3iArray\\|PackedVector4Array\\|PackedColorArray\\|JSON\\|UPNP\\|OS\\|IP\\|JSONRPC\\|XRVRS\\)\\'")
(defvar gdscript-ts--type-regex
"\\`[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\\'")
;;; Constants
(defvar gdscript-ts--constant-regex "\\`[A-Z_][A-Z0-9_]+\\'")
;;; Setting
(defvar gdscript-ts--feature-list
'(( comment definition)
( keyword string type annotation)
( number constant escape-sequence)
( bracket delimiter function operator property)))
(defvar gdscript-ts--treesit-settings
(treesit-font-lock-rules
:language 'gdscript
:feature 'comment
'((comment) @font-lock-comment-face)
:language 'gdscript
:feature 'constant
`(([(null) (false) (true)] @font-lock-constant-face)
(const_statement name: (name) @font-lock-constant-face)
(enumerator left: (identifier) @font-lock-constant-face)
((identifier) @font-lock-constant-face
(:match ,gdscript-ts--constant-regex @font-lock-constant-face))
(variable_statement
name: (name) @font-lock-constant-face
(:match ,gdscript-ts--constant-regex @font-lock-constant-face)))
:language 'gdscript
:feature 'bracket
`(["[" "]" "(" ")" "{" "}"] @font-lock-bracket-face)
:language 'gdscript
:feature 'delimiter
`(["," ":" "."] @font-lock-delimiter-face)
:language 'gdscript
:feature 'type
`(((identifier) @font-lock-builtin-face
(:match ,gdscript-ts--builtin-type-regex @font-lock-builtin-face))
(get_node) @font-lock-builtin-face
((identifier) @font-lock-type-face
(:match ,gdscript-ts--type-regex @font-lock-type-face))
(enum_definition name: (_) @font-lock-type-face)
(class_name_statement (name) @font-lock-type-face)
(class_definition (name) @font-lock-type-face))
:language 'gdscript
:feature 'definition
'((function_definition (name) @font-lock-function-name-face)
(class_definition
(name) @font-lock-function-name-face)
(parameters (identifier) @font-lock-variable-name-face))
'((function_definition (name) @font-lock-function-name-face))
:language 'gdscript
:feature 'annotation
'((annotation "@" @font-lock-preprocessor-face
(identifier) @font-lock-preprocessor-face))
:language 'gdscript
:feature 'keyword
`(([,@gdscript-ts--treesit-keywords] @font-lock-keyword-face)
([(false) (true)] @font-lock-keyword-face))
`((ERROR _ @font-lock-keyword-face (:match ,gdscript-ts--keyword-regex @font-lock-keyword-face))
(_ _ @font-lock-keyword-face (:match ,gdscript-ts--keyword-regex @font-lock-keyword-face)))
:language 'gdscript
:feature 'string
'((string) @font-lock-string-face)
:language 'gdscript
:feature 'type
'(((type) @font-lock-type-face)
(get_node) @font-lock-type-face)
:feature 'function
:language 'gdscript
'((call (identifier) @font-lock-function-call-face)
'((call (identifier) @font-lock-builtin-face (:match "preload" @font-lock-builtin-face))
(call (identifier) @font-lock-function-call-face)
(attribute_call (identifier) @font-lock-function-call-face))
:language 'gdscript
:feature 'variable
'((_ (name) @font-lock-variable-name-face))
:feature 'number
:language 'gdscript
'(([(integer) (float)] @font-lock-number-face))
:feature 'property
:language 'gdscript
:feature 'property
'((attribute (identifier) (identifier) @font-lock-property-use-face))
:feature 'operator
:language 'gdscript
`(["+" "-" "*" "/" "^" ">" "<" "="] @font-lock-operator-face)))
`(["+" "+=" "-" "-=" "*" "*=" "/" "/=" "^" "^=" ">" ">="
"<" "<=" "|" "|=" "%" "%=" "&" "&=" ">>" ">>=" "<<" "<<="
"||" "&&" "==" "!=" "->" "~" "=" ":="]
@font-lock-operator-face)
:language 'gdscript
:override t
:feature 'escape-sequence
'((escape_sequence) @font-lock-escape-face)))
;;; Funtion
@@ -220,10 +277,7 @@ Similar to `gdscript-imenu-create-index' but use tree-sitter."
:syntax-table gdscript-mode-syntax-table
(when (treesit-ready-p 'gdscript)
(treesit-parser-create 'gdscript)
(setq-local treesit-font-lock-feature-list
'(( comment definition)
( keyword string type)
( function variable number property operator)))
(setq-local treesit-font-lock-feature-list gdscript-ts--feature-list)
(setq-local treesit-font-lock-settings gdscript-ts--treesit-settings)
;;; TODO: create-imenu
(setq-local imenu-create-index-function