gdscript.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. """
  2. pygments.lexers.gdscript
  3. ~~~~~~~~~~~~~~~~~~~~~~~~
  4. Lexer for GDScript.
  5. Modified by Daniel J. Ramirez <djrmuv@gmail.com> based on the original
  6. python.py.
  7. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS.
  8. :license: BSD, see LICENSE for details.
  9. """
  10. import re
  11. from pygments.lexer import RegexLexer, include, bygroups, default, words, \
  12. combined
  13. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  14. Number, Punctuation, Whitespace
  15. __all__ = ["GDScriptLexer"]
  16. class GDScriptLexer(RegexLexer):
  17. """
  18. For GDScript source code.
  19. """
  20. name = "GDScript"
  21. url = 'https://www.godotengine.org'
  22. aliases = ["gdscript", "gd"]
  23. filenames = ["*.gd"]
  24. mimetypes = ["text/x-gdscript", "application/x-gdscript"]
  25. version_added = ''
  26. def innerstring_rules(ttype):
  27. return [
  28. # the old style '%s' % (...) string formatting
  29. (r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?"
  30. "[hlL]?[E-GXc-giorsux%]",
  31. String.Interpol),
  32. # backslashes, quotes and formatting signs must be parsed one at a time
  33. (r'[^\\\'"%\n]+', ttype),
  34. (r'[\'"\\]', ttype),
  35. # unhandled string formatting sign
  36. (r"%", ttype),
  37. # newlines are an error (use "nl" state)
  38. ]
  39. tokens = {
  40. "root": [
  41. (r"\n", Whitespace),
  42. (r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")',
  43. bygroups(Whitespace, String.Affix, String.Doc)),
  44. (r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')",
  45. bygroups(Whitespace, String.Affix, String.Doc)),
  46. (r"[^\S\n]+", Whitespace),
  47. (r"#.*$", Comment.Single),
  48. (r"[]{}:(),;[]", Punctuation),
  49. (r"(\\)(\n)", bygroups(Text, Whitespace)),
  50. (r"\\", Text),
  51. (r"(in|and|or|not)\b", Operator.Word),
  52. (r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]",
  53. Operator),
  54. include("keywords"),
  55. (r"(func)(\s+)", bygroups(Keyword, Whitespace), "funcname"),
  56. (r"(class)(\s+)", bygroups(Keyword, Whitespace), "classname"),
  57. include("builtins"),
  58. ('([rR]|[uUbB][rR]|[rR][uUbB])(""")',
  59. bygroups(String.Affix, String.Double),
  60. "tdqs"),
  61. ("([rR]|[uUbB][rR]|[rR][uUbB])(''')",
  62. bygroups(String.Affix, String.Single),
  63. "tsqs"),
  64. ('([rR]|[uUbB][rR]|[rR][uUbB])(")',
  65. bygroups(String.Affix, String.Double),
  66. "dqs"),
  67. ("([rR]|[uUbB][rR]|[rR][uUbB])(')",
  68. bygroups(String.Affix, String.Single),
  69. "sqs"),
  70. ('([uUbB]?)(""")',
  71. bygroups(String.Affix, String.Double),
  72. combined("stringescape", "tdqs")),
  73. ("([uUbB]?)(''')",
  74. bygroups(String.Affix, String.Single),
  75. combined("stringescape", "tsqs")),
  76. ('([uUbB]?)(")',
  77. bygroups(String.Affix, String.Double),
  78. combined("stringescape", "dqs")),
  79. ("([uUbB]?)(')",
  80. bygroups(String.Affix, String.Single),
  81. combined("stringescape", "sqs")),
  82. include("name"),
  83. include("numbers"),
  84. ],
  85. "keywords": [
  86. (words(("and", "in", "not", "or", "as", "breakpoint", "class",
  87. "class_name", "extends", "is", "func", "setget", "signal",
  88. "tool", "const", "enum", "export", "onready", "static",
  89. "var", "break", "continue", "if", "elif", "else", "for",
  90. "pass", "return", "match", "while", "remote", "master",
  91. "puppet", "remotesync", "mastersync", "puppetsync"),
  92. suffix=r"\b"), Keyword),
  93. ],
  94. "builtins": [
  95. (words(("Color8", "ColorN", "abs", "acos", "asin", "assert", "atan",
  96. "atan2", "bytes2var", "ceil", "char", "clamp", "convert",
  97. "cos", "cosh", "db2linear", "decimals", "dectime", "deg2rad",
  98. "dict2inst", "ease", "exp", "floor", "fmod", "fposmod",
  99. "funcref", "hash", "inst2dict", "instance_from_id", "is_inf",
  100. "is_nan", "lerp", "linear2db", "load", "log", "max", "min",
  101. "nearest_po2", "pow", "preload", "print", "print_stack",
  102. "printerr", "printraw", "prints", "printt", "rad2deg",
  103. "rand_range", "rand_seed", "randf", "randi", "randomize",
  104. "range", "round", "seed", "sign", "sin", "sinh", "sqrt",
  105. "stepify", "str", "str2var", "tan", "tan", "tanh",
  106. "type_exist", "typeof", "var2bytes", "var2str", "weakref",
  107. "yield"), prefix=r"(?<!\.)", suffix=r"\b"),
  108. Name.Builtin),
  109. (r"((?<!\.)(self|false|true)|(PI|TAU|NAN|INF)" r")\b",
  110. Name.Builtin.Pseudo),
  111. (words(("bool", "int", "float", "String", "NodePath", "Vector2",
  112. "Rect2", "Transform2D", "Vector3", "Rect3", "Plane", "Quat",
  113. "Basis", "Transform", "Color", "RID", "Object", "NodePath",
  114. "Dictionary", "Array", "PackedByteArray", "PackedInt32Array",
  115. "PackedInt64Array", "PackedFloat32Array", "PackedFloat64Array",
  116. "PackedStringArray", "PackedVector2Array", "PackedVector3Array",
  117. "PackedColorArray", "null", "void"),
  118. prefix=r"(?<!\.)", suffix=r"\b"),
  119. Name.Builtin.Type),
  120. ],
  121. "numbers": [
  122. (r"(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?", Number.Float),
  123. (r"\d+[eE][+-]?[0-9]+j?", Number.Float),
  124. (r"0[xX][a-fA-F0-9]+", Number.Hex),
  125. (r"\d+j?", Number.Integer),
  126. ],
  127. "name": [(r"[a-zA-Z_]\w*", Name)],
  128. "funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")],
  129. "classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")],
  130. "stringescape": [
  131. (
  132. r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|'
  133. r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})",
  134. String.Escape,
  135. )
  136. ],
  137. "strings-single": innerstring_rules(String.Single),
  138. "strings-double": innerstring_rules(String.Double),
  139. "dqs": [
  140. (r'"', String.Double, "#pop"),
  141. (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings
  142. include("strings-double"),
  143. ],
  144. "sqs": [
  145. (r"'", String.Single, "#pop"),
  146. (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings
  147. include("strings-single"),
  148. ],
  149. "tdqs": [
  150. (r'"""', String.Double, "#pop"),
  151. include("strings-double"),
  152. (r"\n", Whitespace),
  153. ],
  154. "tsqs": [
  155. (r"'''", String.Single, "#pop"),
  156. include("strings-single"),
  157. (r"\n", Whitespace),
  158. ],
  159. }
  160. def analyse_text(text):
  161. score = 0.0
  162. if re.search(
  163. r"func (_ready|_init|_input|_process|_unhandled_input)", text
  164. ):
  165. score += 0.8
  166. if re.search(
  167. r"(extends |class_name |onready |preload|load|setget|func [^_])",
  168. text
  169. ):
  170. score += 0.4
  171. if re.search(r"(var|const|enum|export|signal|tool)", text):
  172. score += 0.2
  173. return min(score, 1.0)