├── .gitignore ├── spwn_logo_smol.png ├── .vscodeignore ├── spwn_logo_colored.png ├── .gitattributes ├── CHANGELOG.md ├── .vscode └── launch.json ├── README.md ├── package.json ├── language-configuration.json └── syntaxes └── spwn.tmLanguage.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.vsix -------------------------------------------------------------------------------- /spwn_logo_smol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spu7Nix/SPWN-vscode/HEAD/spwn_logo_smol.png -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | vsc-extension-quickstart.md 5 | -------------------------------------------------------------------------------- /spwn_logo_colored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spu7Nix/SPWN-vscode/HEAD/spwn_logo_colored.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behavior to automatically normalize line endings. 2 | * text=auto 3 | 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | - Initial release 4 | 5 | ## 0.0.2 6 | 7 | - Bugfixes 8 | - Added support for single-quoted strings 9 | 10 | ## 0.0.3 11 | 12 | - Bugfixes 13 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.7.0", 7 | "configurations": [ 8 | 9 | 10 | { 11 | "name": "Extension", 12 | "type": "extensionHost", 13 | "request": "launch", 14 | "args": [ 15 | "--extensionDevelopmentPath=${workspaceFolder}" 16 | ] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![SPWN](spwn_logo_colored.png) 2 | 3 | ## Features 4 | 5 | Basic language support for the SPWN programming language for Geometry Dash, including basic syntax highlighting, auto-indentation, collapsing, and more. 6 | 7 | ## Release Notes 8 | 9 | ## 0.1.0 10 | 11 | - Initial release 12 | 13 | ## 0.2.0 14 | 15 | - Bugfixes 16 | - Added support for single-quoted strings 17 | 18 | ## 0.3.0 19 | 20 | - Bugfixes 21 | 22 | ## 0.4.0 23 | 24 | - Bugfixes 25 | - Added new keywords 26 | 27 | ## 0.5.0 28 | 29 | - Made syntax highlighting actually good 30 | 31 | ## 0.6.0 32 | 33 | - Added support for `while`-loops 34 | - Added support for raw strings 35 | - Added support for special property names 36 | - Fixed some bugs 37 | 38 | ### 0.7.0 39 | 40 | - Implemented the spwn file icon -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spwn-language-support", 3 | "publisher": "Spu7Nix", 4 | "displayName": "SPWN Language Support", 5 | "description": "Language support for SPWN", 6 | "version": "0.0.4", 7 | "icon": "spwn_logo_smol.png", 8 | "repository": { 9 | "type" : "git", 10 | "url" : "https://github.com/Spu7Nix/SPWN-vscode.git" 11 | }, 12 | "engines": { 13 | "vscode": "^1.49.0" 14 | }, 15 | "categories": [ 16 | "Programming Languages" 17 | ], 18 | "contributes": { 19 | "languages": [{ 20 | "id": "spwn", 21 | "aliases": ["SPWN", "spwn"], 22 | "extensions": [".spwn"], 23 | "configuration": "./language-configuration.json", 24 | "icon": { 25 | "dark": "./spwn_logo_smol.png", 26 | "light": "./spwn_logo_smol.png" 27 | } 28 | }], 29 | "grammars": [{ 30 | "language": "spwn", 31 | "scopeName": "source.spwn", 32 | "path": "./syntaxes/spwn.tmLanguage.json" 33 | }] 34 | } 35 | } -------------------------------------------------------------------------------- /language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "//", 5 | // symbols used for start and end a block comment. Remove this entry if your language does not support block comments 6 | "blockComment": [ "/*", "*/" ] 7 | }, 8 | // symbols used as brackets 9 | "brackets": [ 10 | ["{", "}"], 11 | ["!{", "}"], 12 | ["[", "]"], 13 | ["#[", "]"], 14 | ["(", ")"] 15 | ], 16 | // symbols that are auto closed when typing 17 | "autoClosingPairs": [ 18 | ["{", "}"], 19 | ["!{", "}"], 20 | ["[", "]"], 21 | ["#[", "]"], 22 | ["(", ")"], 23 | ["\"", "\""], 24 | ["'", "'"] 25 | ], 26 | // symbols that can be used to surround a selection 27 | "surroundingPairs": [ 28 | ["{", "}"], 29 | ["!{", "}"], 30 | ["[", "]"], 31 | ["#[", "]"], 32 | ["(", ")"], 33 | ["\"", "\""], 34 | ["'", "'"] 35 | ], 36 | "indentationRules": { 37 | "increaseIndentPattern": "(\\[|\\{|\\()\n", 38 | "decreaseIndentPattern": "(?<=\n(\\]|\\}|\\)))" 39 | } 40 | } -------------------------------------------------------------------------------- /syntaxes/spwn.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "scopeName": "source.spwn", 3 | "name": "SPWN", 4 | "comment": "just a modified version of the grammar of Golang", 5 | "fileTypes": [ 6 | "spwn" 7 | ], 8 | 9 | "patterns": [ 10 | {"include": "#root"} 11 | ], 12 | 13 | "repository": { 14 | "root": { 15 | "patterns": [ 16 | {"include": "#comments"}, 17 | 18 | { 19 | "comment": "Raw string", 20 | "begin": "\\br([\"'])", 21 | "beginCaptures": [{"name": "punctuation.definition.string.begin.spwn"}], 22 | "end": "\\1", 23 | "endCaptures": [{"name": "punctuation.definition.string.end.spwn"}], 24 | "name": "string.quoted.raw.spwn" 25 | }, 26 | { 27 | "comment": "Double quoted string", 28 | "begin": "\"", 29 | "beginCaptures": [{"name": "punctuation.definition.string.begin.spwn"}], 30 | "end": "\"", 31 | "endCaptures": [{"name": "punctuation.definition.string.end.spwn"}], 32 | "name": "string.quoted.double.spwn", 33 | "patterns": [ 34 | {"include": "#string_escaped_char"}, 35 | {"include": "#string_placeholder"} 36 | ] 37 | }, 38 | { 39 | "comment": "Single quoted string", 40 | "begin": "'", 41 | "beginCaptures": [{"name": "punctuation.definition.string.begin.spwn"}], 42 | "end": "'", 43 | "endCaptures": [{"name": "punctuation.definition.string.end.spwn"}], 44 | "name": "string.quoted.single.spwn", 45 | "patterns": [ 46 | {"include": "#string_escaped_char"}, 47 | {"include": "#string_placeholder"} 48 | ] 49 | }, 50 | 51 | { 52 | "comment": "Methods", 53 | "match": "(?<=\\.)(?)", 128 | "name": "variable.parameter.spwn" 129 | }, 130 | 131 | { 132 | "comment": "Terminators", 133 | "match": ";", 134 | "name": "punctuation.terminator.spwn" 135 | }, 136 | {"include": "#brackets"}, 137 | {"include": "#delimiters"}, 138 | {"include": "#operators"} 139 | ] 140 | }, 141 | 142 | "space": { 143 | "patterns": [ 144 | { 145 | "match": "\\s+", 146 | "name": "text.spwn" 147 | }, 148 | { 149 | "comment": "A funny hack that forces vscode to eat the newline", 150 | "match": "\\n$", 151 | "name": "text.spwn" 152 | } 153 | ] 154 | }, 155 | 156 | "comments": { 157 | "patterns": [ 158 | { 159 | "comment": "Block comments", 160 | "begin": "/\\*", 161 | "end": "\\*/", 162 | "captures": [{"name": "punctuation.definition.comment.spwn"}], 163 | "name": "comment.block.spwn" 164 | }, 165 | { 166 | "comment": "Line comments", 167 | "begin": "//", 168 | "beginCaptures": [{"name": "punctuation.definition.comment.spwn"}], 169 | "end": "$", 170 | "name": "comment.line.double-slash.spwn" 171 | } 172 | ] 173 | }, 174 | 175 | "func-args": { 176 | "patterns": [ 177 | { 178 | "comment": "`self` is allowed in params list", 179 | "match": "\\bself\\b", 180 | "name": "constant.language.spwn" 181 | }, 182 | { 183 | "begin": "\\b([a-zA-Z_]\\w*)(?:\\s*(:(?!:)|=(?![=>]))|\\b)", 184 | "beginCaptures": { 185 | "1": {"name": "variable.parameter.spwn"}, 186 | "2": {"name": "keyword.operator.spwn"} 187 | }, 188 | "end": "(?=[,)])", 189 | "patterns": [ 190 | {"include": "#root"} 191 | ] 192 | }, 193 | {"include": "#root"} 194 | ] 195 | }, 196 | 197 | "brackets": { 198 | "patterns": [ 199 | { 200 | "begin": "(!)(\\{)", 201 | "beginCaptures": { 202 | "1": {"name": "keyword.spwn"}, 203 | "2": {"name": "punctuation.other.bracket.curly.begin.spwn"} 204 | }, 205 | "end": "\\}", 206 | "endCaptures": [{"name": "punctuation.other.bracket.curly.end.spwn"}], 207 | "patterns": [ 208 | {"include": "#root"} 209 | ] 210 | }, 211 | 212 | { 213 | "begin": "\\{", 214 | "beginCaptures": [{"name": "punctuation.other.bracket.curly.begin.spwn"}], 215 | "end": "\\}", 216 | "endCaptures": [{"name": "punctuation.other.bracket.curly.end.spwn"}], 217 | "patterns": [ 218 | {"include": "#space"}, 219 | {"include": "#comments"}, 220 | { 221 | "begin": "(?=\\w+\\s*:(?!:)|\\b(?!(?:continue|break|return|self|true|false|null)\\b)[a-zA-Z_]\\w*\\s*[,}]|\\.{2})", 222 | "end": "(?=\\})", 223 | "patterns": [ 224 | {"include": "#space"}, 225 | {"include": "#comments"}, 226 | { 227 | "begin": "(\\d+)\\s*(:)(?!:)", 228 | "beginCaptures": { 229 | "1": {"name": "constant.numeric.spwn"}, 230 | "2": {"name": "keyword.operator.spwn"} 231 | }, 232 | "end": ",|(?=\\})", 233 | "endCaptures": [{"name": "punctuation.separator.spwn"}], 234 | "patterns": [ 235 | {"include": "#root"} 236 | ] 237 | }, 238 | { 239 | "begin": "([a-zA-Z_]\\w*)\\s*(:)(?!:)", 240 | "beginCaptures": { 241 | "1": {"patterns": [ 242 | {"include": "#property-name"} 243 | ]}, 244 | "2": {"name": "keyword.operator.spwn"} 245 | }, 246 | "end": ",|(?=\\})", 247 | "endCaptures": [{"name": "punctuation.separator.spwn"}], 248 | "patterns": [ 249 | {"include": "#root"} 250 | ] 251 | }, 252 | { 253 | "begin": "[a-zA-Z_]\\w*", 254 | "beginCaptures": [{"name": "variable.property.spwn"}], 255 | "end": ",|(?=\\})", 256 | "endCaptures": [{"name": "punctuation.separator.spwn"}], 257 | "patterns": [ 258 | {"include": "#root"} 259 | ] 260 | }, 261 | { 262 | "begin": "(?=\\.{2})", 263 | "end": ",|(?=\\})", 264 | "endCaptures": [{"name": "punctuation.separator.spwn"}], 265 | "patterns": [ 266 | {"include": "#root"} 267 | ] 268 | } 269 | ] 270 | }, 271 | { 272 | "begin": "(?=.)", 273 | "end": "(?=\\})", 274 | "patterns": [ 275 | {"include": "#root"} 276 | ] 277 | } 278 | ] 279 | }, 280 | 281 | { 282 | "comment": "Definitely a regular function or arrow function", 283 | "begin": "(?])|\\)\\s*(?:\\{|=>)))", 284 | "beginCaptures": [{"name": "punctuation.other.parameters.begin.spwn"}], 285 | "end": "\\)", 286 | "endCaptures": [{"name": "punctuation.other.parameters.end.spwn"}], 287 | "patterns": [ 288 | {"include": "#func-args"} 289 | ] 290 | }, 291 | 292 | { 293 | "comment": "Either a paren expression, regular function, or arrow function", 294 | "begin": "(?])|\\)\\s*\\{))", 301 | "end": "(?=\\))", 302 | "patterns": [ 303 | {"include": "#func-args"} 304 | ] 305 | }, 306 | {"include": "#root"} 307 | ] 308 | }, 309 | 310 | { 311 | "comment": "Some sort of function call", 312 | "begin": "\\(", 313 | "beginCaptures": [{"name": "punctuation.other.bracket.round.begin.spwn"}], 314 | "end": "\\)", 315 | "endCaptures": [{"name": "punctuation.other.bracket.round.end.spwn"}], 316 | "patterns": [ 317 | { 318 | "comment": "A named argument", 319 | "match": "\\b([a-zA-Z_]\\w*)\\s*(=)(?![=>])", 320 | "captures": { 321 | "1": {"name": "variable.parameter.spwn"}, 322 | "2": {"name": "keyword.operator.spwn"} 323 | } 324 | }, 325 | {"include": "#root"} 326 | ] 327 | }, 328 | 329 | { 330 | "begin": "#\\[", 331 | "beginCaptures": [{"name": "keyword.directive.begin.spwn"}], 332 | "end": "\\]", 333 | "endCaptures": [{"name": "keyword.directive.end.spwn"}], 334 | "patterns": [ 335 | { 336 | "match": "\\b[a-zA-Z_]\\w*\\b", 337 | "name": "support.function.directive.spwn" 338 | }, 339 | {"include": "#root"} 340 | ] 341 | }, 342 | 343 | { 344 | "begin": "\\[", 345 | "beginCaptures": [{"name": "punctuation.other.bracket.square.begin.spwn"}], 346 | "end": "\\]", 347 | "endCaptures": [{"name": "punctuation.other.bracket.square.end.spwn"}], 348 | "patterns": [ 349 | {"include": "#root"} 350 | ] 351 | } 352 | ] 353 | }, 354 | 355 | "property-name": { 356 | "patterns": [ 357 | { 358 | "match": "\\b(type)\\b", 359 | "name": "keyword.spwn" 360 | }, 361 | {"include": "#op-overloads"}, 362 | { 363 | "match": "[a-zA-Z_]\\w*", 364 | "name": "variable.property.spwn" 365 | } 366 | ] 367 | }, 368 | "op-overloads": { 369 | "match": "\\b_(?:either|or|and|equal|not_equal|more_or_equal|less_or_equal|more_than|less_than|times|mod|pow|plus|minus|divided_by|not|assign|add|subtract|multiply|divide|exponate|modulate|increment|pre_increment|decrement|pre_decrement|as|has|range|intdivide|intdivided_by|swap|negate|unary_range|to)_\\b", 370 | "name": "keyword.spwn" 371 | }, 372 | 373 | "delimiters": { 374 | "patterns": [ 375 | { 376 | "match": ",", 377 | "name": "punctuation.other.comma.spwn" 378 | }, 379 | { 380 | "match": "\\.(?!\\.)", 381 | "name": "punctuation.other.period.spwn" 382 | } 383 | ] 384 | }, 385 | 386 | "keywords": { 387 | "patterns": [ 388 | { 389 | "begin": "\\bimpl\\b", 390 | "beginCaptures": [{"name": "keyword.spwn"}], 391 | "end": "(?<=\\})", 392 | "patterns": [ 393 | { 394 | "begin": "@[a-zA-Z_]\\w*", 395 | "beginCaptures": [{"name": "entity.name.type.spwn"}], 396 | "end": "(?<=\\})", 397 | "patterns": [ 398 | { 399 | "begin": "\\{", 400 | "beginCaptures": [{"name": "punctuation.other.bracket.curly.begin.spwn"}], 401 | "end": "\\}", 402 | "endCaptures": [{"name": "punctuation.other.bracket.curly.end.spwn"}], 403 | "patterns": [ 404 | {"include": "#space"}, 405 | {"include": "#comments"}, 406 | { 407 | "begin": "([a-zA-Z_]\\w*)\\s*(:)(?!:)", 408 | "beginCaptures": { 409 | "1": {"patterns": [ 410 | {"include": "#op-overloads"}, 411 | { 412 | "match": "[a-zA-Z_]\\w*", 413 | "name": "entity.name.function.spwn" 414 | } 415 | ]}, 416 | "2": {"name": "keyword.operator.spwn"} 417 | }, 418 | "end": ",|(?=\\})", 419 | "endCaptures": [{"name": "punctuation.separator.spwn"}], 420 | "patterns": [ 421 | {"include": "#root"} 422 | ] 423 | } 424 | ] 425 | } 426 | ] 427 | } 428 | ] 429 | }, 430 | 431 | { 432 | "begin": "\\bfor\\b", 433 | "beginCaptures": [{"name": "keyword.spwn"}], 434 | "end": "\\bin\\b", 435 | "endCaptures": [{"name": "keyword.spwn"}], 436 | "patterns": [ 437 | {"include": "#space"}, 438 | {"include": "#comments"}, 439 | { 440 | "match": "\\b[a-zA-Z_]\\w*\\b", 441 | "name": "variable.spwn" 442 | } 443 | ] 444 | }, 445 | 446 | { 447 | "comment": "Flow control keywords", 448 | "match": "\\b(else|for|if|return|error|extract|in|type|import|impl|break|continue|while|as|throw|switch|has|case|sync)\\b", 449 | "name": "keyword.control.spwn" 450 | } 451 | ] 452 | }, 453 | 454 | "operators": { 455 | "comment": "Note that the order here is very important!", 456 | "patterns": [ 457 | { 458 | "match": "(==|!=|<=|>=|<|>)", 459 | "name": "keyword.operator.comparison.spwn" 460 | }, 461 | { 462 | "match": "(&&|\\|\\||!)", 463 | "name": "keyword.operator.logical.spwn" 464 | }, 465 | { 466 | "match": "(=|\\+=|\\-=|\\*=|\/=)", 467 | "name": "keyword.operator.assignment.spwn" 468 | }, 469 | { 470 | "match": "(\\+|\\-|\\*|\/|%|\\^|\\|)", 471 | "name": "keyword.operator.arithmetic.spwn" 472 | }, 473 | { 474 | "match": "\\.\\.", 475 | "name": "keyword.operator.range.spwn" 476 | }, 477 | { 478 | "match": "::", 479 | "name": "keyword.operator.spwn" 480 | }, 481 | { 482 | "match": "->|=>", 483 | "name": "keyword.control.spwn" 484 | } 485 | ] 486 | }, 487 | 488 | 489 | "string_escaped_char": { 490 | "patterns": [ 491 | { 492 | "match": "\\\\([0-7]{3}|[abfnrtv\\\\'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})", 493 | "name": "constant.character.escape.spwn" 494 | }, 495 | { 496 | "match": "\\\\[^0-7xuUabfnrtv\\'\"]", 497 | "name": "invalid.illegal.unknown-escape.spwn" 498 | } 499 | ] 500 | }, 501 | 502 | "string_placeholder": { 503 | "patterns": [ 504 | { 505 | "match": "%(\\[\\d+\\])?([\\+#\\-0\\x20]{,2}((\\d+|\\*)?(\\.?(\\d+|\\*|(\\[\\d+\\])\\*?)?(\\[\\d+\\])?)?))?[vT%tbcdoqxXUbeEfFgGsp]", 506 | "name": "constant.other.placeholder.spwn" 507 | } 508 | ] 509 | } 510 | 511 | } 512 | } --------------------------------------------------------------------------------