{
	"fileTypes": [ "gd" ],
	"scopeName": "source.gdscript",
	"name": "GDScript",
	"patterns": [
		{ "include": "#statement" },
		{ "include": "#expression" }
	],
	"repository": {
		"statement": {
			"patterns": [ { "include": "#extends_statement" } ]
		},
		"statement_keyword": {
			"patterns": [
				{
					"name": "keyword.control.flow.gdscript",
					"match": "(?x)\n  \\b(?<!\\.)(\n continue | assert | break | elif | else | if | pass | return | while )\\b\n"
				},
				{
					"name": "storage.type.class.gdscript",
					"match": "\\b(?<!\\.)(class)\\b"
				},
				{
					"match": "(?x)\n  ^\\s*(\n    case | match\n  )(?=\\s*([-+\\w\\d(\\[{'\":#]|$))\\b\n",
					"captures": { "1": { "name": "keyword.control.flow.gdscript" } }
				}
			]
		},
		"extends_statement": {
			"match": "(extends)\\s+([a-zA-Z_]\\w*\\.[a-zA-Z_]\\w*)?",
			"captures": {
				"1": { "name": "keyword.language.gdscript" },
				"2": { "name": "entity.other.inherited-class.gdscript" }
			}
		},
		"expression": {
			"patterns": [
				{ "include": "#base_expression" },
				{ "include": "#getter_setter_godot4" },
				{ "include": "#assignment_operator" },
				{ "include": "#annotations" },
				{ "include": "#class_name" },
				{ "include": "#builtin_classes" },
				{ "include": "#class_new" },
				{ "include": "#class_is" },
				{ "include": "#class_enum" },
				{ "include": "#any_method" },
				{ "include": "#any_variable" },
				{ "include": "#any_property" }
			]
		},
		"base_expression": {
			"patterns": [
				{ "include": "#builtin_get_node_shorthand" },
				{ "include": "#nodepath_object" },
				{ "include": "#nodepath_function" },
				{ "include": "#strings" },
				{ "include": "#const_vars" },
				{ "include": "#keywords" },
				{ "include": "#logic_operator" },
				{ "include": "#compare_operator" },
				{ "include": "#arithmetic_operator" },
				{ "include": "#lambda_declaration" },
				{ "include": "#class_declaration" },
				{ "include": "#variable_declaration" },
				{ "include": "#signal_declaration_bare" },
				{ "include": "#signal_declaration" },
				{ "include": "#function_declaration" },
				{ "include": "#statement_keyword" },
				{ "include": "#assignment_operator" },
				{ "include": "#in_keyword" },
				{ "include": "#control_flow" },
				{ "include": "#round_braces" },
				{ "include": "#function_call" },
				{ "include": "#comment" },
				{ "include": "#self" },
				{ "include": "#func" },
				{ "include": "#letter" },
				{ "include": "#numbers" },
				{ "include": "#builtin_classes" },
				{ "include": "#pascal_case_class" },
				{ "include": "#line_continuation" }
			]
		},
		"comment": {
			"match": "(#).*$\\n?",
			"name": "comment.line.number-sign.gdscript",
			"captures": { "1": { "name": "punctuation.definition.comment.number-sign.gdscript" } }
		},
		"strings": {
			"name": "string.quoted.gdscript",
			"begin": "(r)?(\"\"\"|'''|\"|')",
			"end": "\\2",
			"beginCaptures": { "1": { "name": "constant.character.escape.gdscript" } },
			"patterns": [
				{
					"name": "constant.character.escape.gdscript",
					"match": "\\\\."
				},
				{ "include": "#string_formatting" }
			]
		},
		"string_formatting": {
			"name": "meta.format.percent.gdscript",
			"match": "(?x)\n  (\n % (\\([\\w\\s]*\\))?\n [-+#0 ]*\n (\\d+|\\*)? (\\.(\\d+|\\*))?\n ([hlL])?\n [diouxXeEfFgGcrsab%]\n  )\n",
			"captures": { "1": { "name": "constant.character.format.placeholder.other.gdscript" } }
		},
		"nodepath_object": {
			"name": "meta.literal.nodepath.gdscript",
			"begin": "(NodePath)\\s*(?:\\()",
			"beginCaptures": { "1": { "name": "support.class.library.gdscript" } },
			"end": "(?:\\))",
			"patterns": [
				{
					"begin": "(\"|')",
					"end": "\\1",
					"name": "string.quoted.gdscript constant.character.escape.gdscript",
					"patterns": [
						{
							"match": "%",
							"name": "keyword.control.flow.gdscript"
						}
					]
				}
			]
		},
		"nodepath_function": {
			"begin": "(get_node_or_null|has_node|has_node_and_resource|find_node|get_node)\\s*(\\()",
			"beginCaptures": {
				"1": { "name": "entity.name.function.gdscript" },
				"2": { "name": "punctuation.definition.parameters.begin.gdscript" }
			},
			"end": "(\\))",
			"endCaptures": { "1": { "name": "punctuation.definition.parameters.end.gdscript" } },
			"patterns": [
				{
					"begin": "(\"|')",
					"end": "\\1",
					"name": "string.quoted.gdscript meta.literal.nodepath.gdscript constant.character.escape",
					"patterns": [
						{
							"match": "%",
							"name": "keyword.control.flow"
						}
					]
				}
			]
		},
		"self": {
			"match": "\\bself\\b",
			"name": "variable.language.gdscript"
		},
		"func": {
			"match": "\\bfunc\\b",
			"name": "keyword.language.gdscript"
		},
		"logic_operator": {
			"match": "\\b(and|or|not|!)\\b",
			"name": "keyword.operator.wordlike.gdscript"
		},
		"in_keyword": {
			"patterns": [
				{
					"begin": "\\b(for)\\b",
					"end": ":",
					"captures": { "1": { "name": "keyword.control.gdscript" } },
					"patterns": [
						{
							"match": "\\bin\\b",
							"name": "keyword.control.gdscript"
						},
						{ "include": "#base_expression" },
						{ "include": "#any_variable" },
						{ "include": "#any_property" }
					]
				},
				{
					"match": "\\bin\\b",
					"name": "keyword.operator.wordlike.gdscript"
				}
			]
		},
		"compare_operator": {
			"match": "<=|>=|==|<|>|!=",
			"name": "keyword.operator.comparison.gdscript"
		},
		"arithmetic_operator": {
			"match": "->|\\+=|-=|\\*=|/=|%=|&=|\\|=|\\*|/|%|\\+|-|<<|>>|&|\\||\\^|~|!",
			"name": "keyword.operator.arithmetic.gdscript"
		},
		"assignment_operator": {
			"match": "=",
			"name": "keyword.operator.assignment.gdscript"
		},
		"control_flow": {
			"match": "\\b(?:if|elif|else|while|break|continue|pass|return|match|yield|await)\\b",
			"name": "keyword.control.gdscript"
		},
		"keywords": {
			"match": "\\b(?:class|class_name|is|onready|tool|static|export|as|void|enum|preload|assert|breakpoint|rpc|sync|remote|master|puppet|slave|remotesync|mastersync|puppetsync|trait|namespace)\\b",
			"name": "keyword.language.gdscript"
		},
		"letter": {
			"match": "\\b(?:true|false|null)\\b",
			"name": "constant.language.gdscript"
		},
		"numbers": {
			"patterns": [
				{
					"match": "0b[01_]+",
					"name": "constant.numeric.integer.binary.gdscript"
				},
				{
					"match": "0x[0-9A-Fa-f_]+",
					"name": "constant.numeric.integer.hexadecimal.gdscript"
				},
				{
					"match": "[-]?([0-9][0-9_]+\\.[0-9_]*(e[\\-\\+]?[0-9_]+)?)",
					"name": "constant.numeric.float.gdscript"
				},
				{
					"match": "[-]?(\\.[0-9][0-9_]*(e[\\-\\+]?[0-9_]+)?)",
					"name": "constant.numeric.float.gdscript"
				},
				{
					"match": "[-]?([0-9][0-9_]*e[\\-\\+]?\\[0-9_])",
					"name": "constant.numeric.float.gdscript"
				},
				{
					"match": "[-]?[0-9][0-9_]*",
					"name": "constant.numeric.integer.gdscript"
				}
			]
		},
		"variable_declaration": {
			"name": "meta.variable.gdscript",
			"begin": "\\b(?:(var)|(const))\\s+(?:(\\b[A-Z_][A-Z_0-9]*\\b)|([A-Za-z_]\\w*))\\s*",
			"beginCaptures": {
				"1": { "name": "keyword.language.gdscript storage.type.var.gdscript" },
				"2": { "name": "keyword.language.gdscript storage.type.const.gdscript" },
				"3": { "name": "constant.language.gdscript" },
				"4": { "name": "variable.other.gdscript" }
			},
			"end": "$|;",
			"patterns": [
				{
					"match": "(:)?\\s*(set|get)\\s+=\\s+([a-zA-Z_]\\w*)",
					"captures": {
						"1": { "name": "punctuation.separator.annotation.gdscript" },
						"2": { "name": "keyword.language.gdscript storage.type.const.gdscript" },
						"3": { "name": "entity.name.function.gdscript" }
					}
				},
				{
					"match": ":=|=(?!=)",
					"name": "keyword.operator.assignment.gdscript"
				},
				{
					"match": "(:)\\s*([a-zA-Z_]\\w*)?",
					"captures": {
						"1": { "name": "punctuation.separator.annotation.gdscript" },
						"2": { "name": "entity.name.type.class.gdscript" }
					}
				},
				{
					"match": "(setget)\\s+([a-zA-Z_]\\w*)(?:[,]\\s*([a-zA-Z_]\\w*))?",
					"captures": {
						"1": { "name": "keyword.language.gdscript storage.type.const.gdscript" },
						"2": { "name": "entity.name.function.gdscript" },
						"3": { "name": "entity.name.function.gdscript" }
					}
				},
				{ "include": "#expression" },
				{ "include": "#letter" },
				{ "include": "#any_variable" },
				{ "include": "#any_property" },
				{ "include": "#keywords" }
			]
		},
		"getter_setter_godot4": {
			"patterns": [
				{
					"match": "\\b(get):",
					"captures": { "1": { "name": "entity.name.function.gdscript" } }
				},
				{
					"name": "meta.function.gdscript",
					"begin": "(?x) \\s+\n (set) \\s*\n (?=\\()",
					"end": "(:|(?=[#'\"\\n]))",
					"beginCaptures": { "1": { "name": "entity.name.function.gdscript" } },
					"patterns": [
						{ "include": "#parameters" },
						{ "include": "#line_continuation" }
					]
				}
			]
		},
		"class_declaration": {
			"match": "(?<=^class)\\s+([a-zA-Z_]\\w*)\\s*(?=:)",
			"captures": {
				"1": { "name": "entity.name.type.class.gdscript" },
				"2": { "name": "class.other.gdscript" }
			}
		},
		"class_new": {
			"match": "\\b([a-zA-Z_]\\w*).(new)\\(",
			"captures": {
				"1": { "name": "entity.name.type.class.gdscript" },
				"2": { "name": "storage.type.new.gdscript" },
				"3": { "name": "punctuation.parenthesis.begin.gdscript" }
			}
		},
		"class_is": {
			"match": "\\s+(is)\\s+([a-zA-Z_]\\w*)",
			"captures": {
				"1": { "name": "storage.type.is.gdscript" },
				"2": { "name": "entity.name.type.class.gdscript" }
			}
		},
		"class_enum": {
			"match": "\\b([A-Z][a-zA-Z_0-9]*)\\.([A-Z_0-9]+)",
			"captures": {
				"1": { "name": "entity.name.type.class.gdscript" },
				"2": { "name": "constant.language.gdscript" }
			}
		},
		"class_name": {
			"match": "(?<=class_name)\\s+([a-zA-Z_]\\w*(\\.([a-zA-Z_]\\w*))?)",
			"captures": {
				"1": { "name": "entity.name.type.class.gdscript" },
				"2": { "name": "class.other.gdscript" }
			}
		},
		"builtin_get_node_shorthand": {
			"patterns": [
				{ "include": "#builtin_get_node_shorthand_quoted" },
				{ "include": "#builtin_get_node_shorthand_bare" },
				{ "include": "#builtin_get_node_shorthand_bare_multi" }
			]
		},
		"builtin_get_node_shorthand_quoted": {
			"name": "string.quoted.gdscript meta.literal.nodepath.gdscript constant.character.escape.gdscript",
			"begin": "(?:(\\$)|(&|\\^|@))(\"|')",
			"beginCaptures": {
				"1": { "name": "keyword.control.flow.gdscript" },
				"2": { "name": "variable.other.enummember.gdscript" }
			},
			"end": "(\\3)",
			"patterns": [
				{
					"match": "%",
					"name": "keyword.control.flow"
				}
			]
		},
		"builtin_get_node_shorthand_bare": {
			"name": "meta.literal.nodepath.gdscript",
			"match": "(?<!/\\s*)(\\$|%|\\$%)([a-zA-Z_]\\w*)\\b(?!\\s*/)",
			"captures": {
				"1": { "name": "keyword.control.flow.gdscript" },
				"2": { "name": "constant.character.escape.gdscript" },
				"3": { "name": "constant.character.escape.gdscript" }
			}
		},
		"builtin_get_node_shorthand_bare_multi": {
			"name": "meta.literal.nodepath.gdscript",
			"begin": "(\\$|%|\\$%)([a-zA-Z_]\\w*)",
			"beginCaptures": {
				"1": { "name": "keyword.control.flow.gdscript" },
				"2": { "name": "constant.character.escape.gdscript" }
			},
			"end": "(?!\\s*/\\s*%?\\s*[a-zA-Z_]\\w*)",
			"patterns": [
				{
					"match": "(/)\\s*(%)?\\s*([a-zA-Z_]\\w*)\\s*",
					"captures": {
						"1": { "name": "constant.character.escape.gdscript" },
						"2": { "name": "keyword.control.flow.gdscript" },
						"3": { "name": "constant.character.escape.gdscript" }
					}
				}
			]
		},
		"annotations": {
			"match": "(@)(export|export_color_no_alpha|export_dir|export_enum|export_exp_easing|export_file|export_flags|export_flags_2d_navigation|export_flags_2d_physics|export_flags_2d_render|export_flags_3d_navigation|export_flags_3d_physics|export_flags_3d_render|export_global_dir|export_global_file|export_multiline|export_node_path|export_placeholder|export_range|icon|onready|rpc|tool|warning_ignore|abstract)\\b",
			"captures": {
				"1": { "name": "entity.name.function.decorator.gdscript" },
				"2": { "name": "entity.name.function.decorator.gdscript" }
			}
		},
		"builtin_classes": {
			"match": "(?<![^.]\\.|:)\\b(OS|GDScript|Vector2|Vector2i|Vector3|Vector3i|Color|Rect2|Rect2i|Array|Basis|Dictionary|Plane|Quat|RID|Rect3|Transform|Transform2D|Transform3D|AABB|String|Color|NodePath|Object|PoolByteArray|PoolIntArray|PoolRealArray|PoolStringArray|PoolVector2Array|PoolVector3Array|PoolColorArray|bool|int|float|StringName|Quaternion|PackedByteArray|PackedInt32Array|PackedInt64Array|PackedFloat32Array|PackedFloat64Array|PackedStringArray|PackedVector2Array|PackedVector2iArray|PackedVector3Array|PackedVector3iArray|PackedColorArray|super)\\b",
			"name": "entity.name.type.class.builtin.gdscript"
		},
		"const_vars": {
			"match": "\\b([A-Z_][A-Z_0-9]*)\\b",
			"name": "constant.language.gdscript"
		},
		"pascal_case_class": {
			"match": "\\b([A-Z][a-z_0-9]*([A-Z]?[a-z_0-9]+)*[A-Z]?)\\b",
			"name": "entity.name.type.class.gdscript"
		},
		"signal_declaration_bare": {
			"name": "meta.signal.gdscript",
			"match": "(?x) \\s*\n (signal) \\s+\n ([a-zA-Z_]\\w*)(?=[\\n\\s])",
			"captures": {
				"1": { "name": "keyword.language.gdscript storage.type.function.gdscript" },
				"2": { "name": "entity.name.function.gdscript" }
			}
		},
		"signal_declaration": {
			"name": "meta.signal.gdscript",
			"begin": "(?x) \\s*\n (signal) \\s+\n ([a-zA-Z_]\\w*) \\s*\n (?=\\()",
			"end": "((?=[#'\"\\n]))",
			"beginCaptures": {
				"1": { "name": "keyword.language.gdscript storage.type.function.gdscript" },
				"2": { "name": "entity.name.function.gdscript" }
			},
			"patterns": [
				{ "include": "#parameters" },
				{ "include": "#line_continuation" }
			]
		},
		"lambda_declaration": {
			"name": "meta.function.gdscript",
			"begin": "(func)\\s?(?=\\()",
			"beginCaptures": {
				"1": { "name": "keyword.language.gdscript storage.type.function.gdscript" },
				"2": { "name": "entity.name.function.gdscript" }
			},
			"end": "(:|(?=[#'\"\\n]))",
			"end2": "(\\s*(\\-\\>)\\s*(void\\w*)|([a-zA-Z_]\\w*)\\s*\\:)",
			"endCaptures2": {
				"1": { "name": "punctuation.separator.annotation.result.gdscript" },
				"2": { "name": "keyword.language.void.gdscript" },
				"3": { "name": "entity.name.type.class.gdscript markup.italic" }
			},
			"patterns": [
				{ "include": "#parameters" },
				{ "include": "#line_continuation" },
				{ "include": "#base_expression" },
				{ "include": "#any_variable" },
				{ "include": "#any_property" }
			]
		},
		"function_declaration": {
			"name": "meta.function.gdscript",
			"begin": "(?x) \\s*\n (func) \\s+\n ([a-zA-Z_]\\w*) \\s*\n (?=\\()",
			"beginCaptures": {
				"1": { "name": "keyword.language.gdscript storage.type.function.gdscript" },
				"2": { "name": "entity.name.function.gdscript" }
			},
			"end": "(:|(?=[#'\"\\n]))",
			"end2": "(\\s*(\\-\\>)\\s*(void\\w*)|([a-zA-Z_]\\w*)\\s*\\:)",
			"endCaptures2": {
				"1": { "name": "punctuation.separator.annotation.result.gdscript" },
				"2": { "name": "keyword.language.void.gdscript" },
				"3": { "name": "entity.name.type.class.gdscript markup.italic" }
			},
			"patterns": [
				{ "include": "#parameters" },
				{ "include": "#line_continuation" },
				{ "include": "#base_expression" }
			]
		},
		"parameters": {
			"name": "meta.function.parameters.gdscript",
			"begin": "(\\()",
			"end": "(\\))",
			"beginCaptures": { "1": { "name": "punctuation.definition.parameters.begin.gdscript" } },
			"endCaptures": { "1": { "name": "punctuation.definition.parameters.end.gdscript" } },
			"patterns": [
				{ "include": "#annotated_parameter" },
				{
					"match": "(?x)\n  ([a-zA-Z_]\\w*)\n    \\s* (?: (,) | (?=[)#\\n=]))\n",
					"captures": {
						"1": { "name": "variable.parameter.function.language.gdscript" },
						"2": { "name": "punctuation.separator.parameters.gdscript" }
					}
				},
				{ "include": "#comment" },
				{ "include": "#loose_default" }
			]
		},
		"loose_default": {
			"begin": "(=)",
			"end": "(,)|(?=\\))",
			"beginCaptures": { "1": { "name": "keyword.operator.gdscript" } },
			"endCaptures": { "1": { "name": "punctuation.separator.parameters.gdscript" } },
			"patterns": [ { "include": "#base_expression" } ]
		},
		"annotated_parameter": {
			"begin": "(?x)\n \\s* ([a-zA-Z_]\\w*) \\s* (:)\\s* ([a-zA-Z_]\\w*)? \n",
			"beginCaptures": {
				"1": { "name": "variable.parameter.function.language.gdscript" },
				"2": { "name": "punctuation.separator.annotation.gdscript" },
				"3": { "name": "entity.name.type.class.builtin.gdscript" }
			},
			"end": "(,)|(?=\\))",
			"endCaptures": { "1": { "name": "punctuation.separator.parameters.gdscript" } },
			"patterns": [
				{ "include": "#base_expression" },
				{
					"name": "keyword.operator.assignment.gdscript",
					"match": "=(?!=)"
				}
			]
		},
		"round_braces": {
			"begin": "\\(",
			"end": "\\)",
			"beginCaptures": { "0": { "name": "punctuation.parenthesis.begin.gdscript" } },
			"endCaptures": { "0": { "name": "punctuation.parenthesis.end.gdscript" } },
			"patterns": [
				{ "include": "#base_expression" },
				{ "include": "#any_variable" }
			]
		},
		"line_continuation": {
			"patterns": [
				{
					"match": "(\\\\)\\s*(\\S.*$\\n?)",
					"captures": {
						"1": { "name": "punctuation.separator.continuation.line.gdscript" },
						"2": { "name": "invalid.illegal.line.continuation.gdscript" }
					}
				},
				{
					"begin": "(\\\\)\\s*$\\n?",
					"end": "(?x)\n  (?=^\\s*$)\n  |\n  (?! (\\s* [rR]? (\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))\n      |\n      (\\G $)  (?# '\\G' is necessary for ST)\n  )\n",
					"beginCaptures": { "1": { "name": "punctuation.separator.continuation.line.gdscript" } },
					"patterns": [ { "include": "#base_expression" } ]
				}
			]
		},
		"any_method": {
			"match": "\\b([A-Za-z_]\\w*)\\b(?=\\s*(?:[(]))",
			"name": "support.function.any-method.gdscript"
		},
		"any_variable": {
			"match": "\\b(?<![@\\$#%])([A-Za-z_]\\w*)\\b(?![(])",
			"name": "variable.other.gdscript"
		},
		"any_property": {
			"match": "\\b(\\.)\\s*(?<![@\\$#%])(?:([A-Z_][A-Z_0-9]*)|([A-Za-z_]\\w*))\\b(?![(])",
			"captures": {
				"1": { "name": "punctuation.accessor.gdscript" },
				"2": { "name": "constant.language.gdscript" },
				"3": { "name": "variable.other.property.gdscript" }
			}
		},
		"function_call": {
			"name": "meta.function-call.gdscript",
			"comment": "Regular function call of the type \"name(args)\"",
			"begin": "(?x)\n  \\b(?=\n    ([a-zA-Z_]\\w*) \\s* (\\()\n  )\n",
			"beginCaptures": { "2": { "name": "punctuation.definition.arguments.begin.gdscript" } },
			"end": "(\\))",
			"endCaptures": { "1": { "name": "punctuation.definition.arguments.end.gdscript" } },
			"patterns": [
				{ "include": "#function_name" },
				{ "include": "#function_arguments" }
			]
		},
		"function_name": {
			"patterns": [
				{ "include": "#builtin_classes" },
				{
					"comment": "Some color schemas support meta.function-call.generic scope",
					"name": "support.function.any-method.gdscript",
					"match": "(?x)\n  \\b ([a-zA-Z_]\\w*) \\b\n"
				}
			]
		},
		"function_arguments": {
			"begin": "(\\()",
			"end": "(?=\\))(?!\\)\\s*\\()",
			"beginCaptures": { "1": { "name": "punctuation.definition.arguments.begin.gdscript" } },
			"contentName": "meta.function.parameters.gdscript",
			"patterns": [
				{
					"name": "punctuation.separator.arguments.gdscript",
					"match": "(,)"
				},
				{
					"match": "\\b([a-zA-Z_]\\w*)\\s*(=)(?!=)",
					"captures": {
						"1": { "name": "variable.parameter.function-call.gdscript" },
						"2": { "name": "keyword.operator.assignment.gdscript" }
					}
				},
				{
					"name": "keyword.operator.assignment.gdscript",
					"match": "=(?!=)"
				},
				{ "include": "#base_expression" },
				{
					"match": "\\s*(\\))\\s*(\\()",
					"captures": {
						"1": { "name": "punctuation.definition.arguments.end.gdscript" },
						"2": { "name": "punctuation.definition.arguments.begin.gdscript" }
					}
				},
				{ "include": "#letter" },
				{ "include": "#any_variable" },
				{ "include": "#any_property" },
				{ "include": "#keywords" }
			]
		}
	}
}
