diff --git a/Moder.Core/Assets/CodeEditor/Grammars/yaml/cgmanifest.json b/Moder.Core/Assets/CodeEditor/Grammars/yaml/cgmanifest.json new file mode 100644 index 0000000..e6c3ca1 --- /dev/null +++ b/Moder.Core/Assets/CodeEditor/Grammars/yaml/cgmanifest.json @@ -0,0 +1,37 @@ +{ + "registrations": [ + { + "component": { + "type": "git", + "git": { + "name": "textmate/yaml.tmbundle", + "repositoryUrl": "https://github.com/textmate/yaml.tmbundle", + "commitHash": "e54ceae3b719506dba7e481a77cea4a8b576ae46" + } + }, + "licenseDetail": [ + "Copyright (c) 2015 FichteFoll ", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and associated documentation files (the \"Software\"), to deal", + "in the Software without restriction, including without limitation the rights", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", + "copies of the Software, and to permit persons to whom the Software is", + "furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all", + "copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ], + "license": "TextMate Bundle License", + "version": "0.0.0" + } + ], + "version": 1 +} \ No newline at end of file diff --git a/Moder.Core/Assets/CodeEditor/Grammars/yaml/language-configuration.json b/Moder.Core/Assets/CodeEditor/Grammars/yaml/language-configuration.json new file mode 100644 index 0000000..16dc5a0 --- /dev/null +++ b/Moder.Core/Assets/CodeEditor/Grammars/yaml/language-configuration.json @@ -0,0 +1,35 @@ +{ + "comments": { + "lineComment": "#" + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "folding": { + "offSide": true, + "markers": { + "start": "^\\s*#\\s*region\\b", + "end": "^\\s*#\\s*endregion\\b" + } + }, + "indentationRules": { + "increaseIndentPattern": "^\\s*.*(:|-) ?(&\\w+)?(\\{[^}\"']*|\\([^)\"']*)?$", + "decreaseIndentPattern": "^\\s+\\}$" + } +} diff --git a/Moder.Core/Assets/CodeEditor/Grammars/yaml/package.json b/Moder.Core/Assets/CodeEditor/Grammars/yaml/package.json new file mode 100644 index 0000000..fc7503a --- /dev/null +++ b/Moder.Core/Assets/CodeEditor/Grammars/yaml/package.json @@ -0,0 +1,72 @@ +{ + "name": "yaml", + "displayName": "%displayName%", + "description": "%description%", + "version": "1.0.0", + "publisher": "vscode", + "license": "MIT", + "engines": { + "vscode": "*" + }, + "scripts": { + "update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/yaml.tmbundle Syntaxes/YAML.tmLanguage ./syntaxes/yaml.tmLanguage.json" + }, + "contributes": { + "languages": [ + { + "id": "dockercompose", + "aliases": [ + "Compose", + "compose" + ], + "filenamePatterns": [ + "compose.yml", + "compose.yaml", + "compose.*.yml", + "compose.*.yaml", + "*docker*compose*.yml", + "*docker*compose*.yaml" + ], + "configuration": "./language-configuration.json" + }, + { + "id": "yaml", + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "firstLine": "^#cloud-config", + "configuration": "./language-configuration.json" + } + ], + "grammars": [ + { + "language": "dockercompose", + "scopeName": "source.yaml", + "path": "./syntaxes/yaml.tmLanguage.json" + }, + { + "language": "yaml", + "scopeName": "source.yaml", + "path": "./syntaxes/yaml.tmLanguage.json" + } + ], + "configurationDefaults": { + "[yaml]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + "editor.autoIndent": "advanced" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/microsoft/vscode.git" + } +} diff --git a/Moder.Core/Assets/CodeEditor/Grammars/yaml/package.nls.json b/Moder.Core/Assets/CodeEditor/Grammars/yaml/package.nls.json new file mode 100644 index 0000000..0299831 --- /dev/null +++ b/Moder.Core/Assets/CodeEditor/Grammars/yaml/package.nls.json @@ -0,0 +1,4 @@ +{ + "displayName": "YAML Language Basics", + "description": "Provides syntax highlighting and bracket matching in YAML files." +} diff --git a/Moder.Core/Assets/CodeEditor/Grammars/yaml/syntaxes/yaml.tmLanguage.json b/Moder.Core/Assets/CodeEditor/Grammars/yaml/syntaxes/yaml.tmLanguage.json new file mode 100644 index 0000000..447df71 --- /dev/null +++ b/Moder.Core/Assets/CodeEditor/Grammars/yaml/syntaxes/yaml.tmLanguage.json @@ -0,0 +1,621 @@ +{ + "information_for_contributors": [ + "This file has been converted from https://github.com/textmate/yaml.tmbundle/blob/master/Syntaxes/YAML.tmLanguage", + "If you want to provide a fix or improvement, please create a pull request against the original repository.", + "Once accepted there, we are happy to receive an update request." + ], + "version": "https://github.com/textmate/yaml.tmbundle/commit/e54ceae3b719506dba7e481a77cea4a8b576ae46", + "name": "YAML", + "scopeName": "source.yaml", + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#property" + }, + { + "include": "#directive" + }, + { + "match": "^---", + "name": "entity.other.document.begin.yaml" + }, + { + "match": "^\\.{3}", + "name": "entity.other.document.end.yaml" + }, + { + "include": "#node" + } + ], + "repository": { + "block-collection": { + "patterns": [ + { + "include": "#block-sequence" + }, + { + "include": "#block-mapping" + } + ] + }, + "block-mapping": { + "patterns": [ + { + "include": "#block-pair" + } + ] + }, + "block-node": { + "patterns": [ + { + "include": "#prototype" + }, + { + "include": "#block-scalar" + }, + { + "include": "#block-collection" + }, + { + "include": "#flow-scalar-plain-out" + }, + { + "include": "#flow-node" + } + ] + }, + "block-pair": { + "patterns": [ + { + "begin": "\\?", + "beginCaptures": { + "1": { + "name": "punctuation.definition.key-value.begin.yaml" + } + }, + "end": "(?=\\?)|^ *(:)|(:)", + "endCaptures": { + "1": { + "name": "punctuation.separator.key-value.mapping.yaml" + }, + "2": { + "name": "invalid.illegal.expected-newline.yaml" + } + }, + "name": "meta.block-mapping.yaml", + "patterns": [ + { + "include": "#block-node" + } + ] + }, + { + "begin": "(?x)\n (?=\n (?x:\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] \\S\n )\n (\n [^\\s:]\n | : \\S\n | \\s+ (?![#\\s])\n )*\n \\s*\n :\n\t\t\t\t\t\t\t(\\s|$)\n )\n ", + "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n ", + "patterns": [ + { + "include": "#flow-scalar-plain-out-implicit-type" + }, + { + "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] \\S\n ", + "beginCaptures": { + "0": { + "name": "entity.name.tag.yaml" + } + }, + "contentName": "entity.name.tag.yaml", + "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n ", + "name": "string.unquoted.plain.out.yaml" + } + ] + }, + { + "match": ":(?=\\s|$)", + "name": "punctuation.separator.key-value.mapping.yaml" + } + ] + }, + "block-scalar": { + "begin": "(?:(\\|)|(>))([1-9])?([-+])?(.*\\n?)", + "beginCaptures": { + "1": { + "name": "keyword.control.flow.block-scalar.literal.yaml" + }, + "2": { + "name": "keyword.control.flow.block-scalar.folded.yaml" + }, + "3": { + "name": "constant.numeric.indentation-indicator.yaml" + }, + "4": { + "name": "storage.modifier.chomping-indicator.yaml" + }, + "5": { + "patterns": [ + { + "include": "#comment" + }, + { + "match": ".+", + "name": "invalid.illegal.expected-comment-or-newline.yaml" + } + ] + } + }, + "end": "^(?=\\S)|(?!\\G)", + "patterns": [ + { + "begin": "^([ ]+)(?! )", + "end": "^(?!\\1|\\s*$)", + "name": "string.unquoted.block.yaml" + } + ] + }, + "block-sequence": { + "match": "(-)(?!\\S)", + "name": "punctuation.definition.block.sequence.item.yaml" + }, + "comment": { + "begin": "(?:(^[ \\t]*)|[ \\t]+)(?=#\\p{Print}*$)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.yaml" + } + }, + "end": "(?!\\G)", + "patterns": [ + { + "begin": "#", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.yaml" + } + }, + "end": "\\n", + "name": "comment.line.number-sign.yaml" + } + ] + }, + "directive": { + "begin": "^%", + "beginCaptures": { + "0": { + "name": "punctuation.definition.directive.begin.yaml" + } + }, + "end": "(?=$|[ \\t]+($|#))", + "name": "meta.directive.yaml", + "patterns": [ + { + "captures": { + "1": { + "name": "keyword.other.directive.yaml.yaml" + }, + "2": { + "name": "constant.numeric.yaml-version.yaml" + } + }, + "match": "\\G(YAML)[ \\t]+(\\d+\\.\\d+)" + }, + { + "captures": { + "1": { + "name": "keyword.other.directive.tag.yaml" + }, + "2": { + "name": "storage.type.tag-handle.yaml" + }, + "3": { + "name": "support.type.tag-prefix.yaml" + } + }, + "match": "(?x)\n \\G\n (TAG)\n (?:[ \\t]+\n ((?:!(?:[0-9A-Za-z\\-]*!)?))\n (?:[ \\t]+ (\n ! (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )*\n | (?![,!\\[\\]{}]) (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )+\n )\n )?\n )?\n " + }, + { + "captures": { + "1": { + "name": "support.other.directive.reserved.yaml" + }, + "2": { + "name": "string.unquoted.directive-name.yaml" + }, + "3": { + "name": "string.unquoted.directive-parameter.yaml" + } + }, + "match": "(?x) \\G (\\w+) (?:[ \\t]+ (\\w+) (?:[ \\t]+ (\\w+))? )?" + }, + { + "match": "\\S+", + "name": "invalid.illegal.unrecognized.yaml" + } + ] + }, + "flow-alias": { + "captures": { + "1": { + "name": "keyword.control.flow.alias.yaml" + }, + "2": { + "name": "punctuation.definition.alias.yaml" + }, + "3": { + "name": "variable.other.alias.yaml" + }, + "4": { + "name": "invalid.illegal.character.anchor.yaml" + } + }, + "match": "((\\*))([^\\s\\[\\]/{/},]+)([^\\s\\]},]\\S*)?" + }, + "flow-collection": { + "patterns": [ + { + "include": "#flow-sequence" + }, + { + "include": "#flow-mapping" + } + ] + }, + "flow-mapping": { + "begin": "\\{", + "beginCaptures": { + "0": { + "name": "punctuation.definition.mapping.begin.yaml" + } + }, + "end": "\\}", + "endCaptures": { + "0": { + "name": "punctuation.definition.mapping.end.yaml" + } + }, + "name": "meta.flow-mapping.yaml", + "patterns": [ + { + "include": "#prototype" + }, + { + "match": ",", + "name": "punctuation.separator.mapping.yaml" + }, + { + "include": "#flow-pair" + } + ] + }, + "flow-node": { + "patterns": [ + { + "include": "#prototype" + }, + { + "include": "#flow-alias" + }, + { + "include": "#flow-collection" + }, + { + "include": "#flow-scalar" + } + ] + }, + "flow-pair": { + "patterns": [ + { + "begin": "\\?", + "beginCaptures": { + "0": { + "name": "punctuation.definition.key-value.begin.yaml" + } + }, + "end": "(?=[},\\]])", + "name": "meta.flow-pair.explicit.yaml", + "patterns": [ + { + "include": "#prototype" + }, + { + "include": "#flow-pair" + }, + { + "include": "#flow-node" + }, + { + "begin": ":(?=\\s|$|[\\[\\]{},])", + "beginCaptures": { + "0": { + "name": "punctuation.separator.key-value.mapping.yaml" + } + }, + "end": "(?=[},\\]])", + "patterns": [ + { + "include": "#flow-value" + } + ] + } + ] + }, + { + "begin": "(?x)\n (?=\n (?:\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] [^\\s[\\[\\]{},]]\n )\n (\n [^\\s:[\\[\\]{},]]\n | : [^\\s[\\[\\]{},]]\n | \\s+ (?![#\\s])\n )*\n \\s*\n :\n\t\t\t\t\t\t\t(\\s|$)\n )\n ", + "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n ", + "name": "meta.flow-pair.key.yaml", + "patterns": [ + { + "include": "#flow-scalar-plain-in-implicit-type" + }, + { + "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] [^\\s[\\[\\]{},]]\n ", + "beginCaptures": { + "0": { + "name": "entity.name.tag.yaml" + } + }, + "contentName": "entity.name.tag.yaml", + "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n ", + "name": "string.unquoted.plain.in.yaml" + } + ] + }, + { + "include": "#flow-node" + }, + { + "begin": ":(?=\\s|$|[\\[\\]{},])", + "captures": { + "0": { + "name": "punctuation.separator.key-value.mapping.yaml" + } + }, + "end": "(?=[},\\]])", + "name": "meta.flow-pair.yaml", + "patterns": [ + { + "include": "#flow-value" + } + ] + } + ] + }, + "flow-scalar": { + "patterns": [ + { + "include": "#flow-scalar-double-quoted" + }, + { + "include": "#flow-scalar-single-quoted" + }, + { + "include": "#flow-scalar-plain-in" + } + ] + }, + "flow-scalar-double-quoted": { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.yaml" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.yaml" + } + }, + "name": "string.quoted.double.yaml", + "patterns": [ + { + "match": "\\\\([0abtnvfre \"/\\\\N_Lp]|x\\d\\d|u\\d{4}|U\\d{8})", + "name": "constant.character.escape.yaml" + }, + { + "match": "\\\\\\n", + "name": "constant.character.escape.double-quoted.newline.yaml" + } + ] + }, + "flow-scalar-plain-in": { + "patterns": [ + { + "include": "#flow-scalar-plain-in-implicit-type" + }, + { + "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] [^\\s[\\[\\]{},]]\n ", + "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n ", + "name": "string.unquoted.plain.in.yaml" + } + ] + }, + "flow-scalar-plain-in-implicit-type": { + "patterns": [ + { + "captures": { + "1": { + "name": "constant.language.null.yaml" + }, + "2": { + "name": "constant.language.boolean.yaml" + }, + "3": { + "name": "constant.numeric.integer.yaml" + }, + "4": { + "name": "constant.numeric.float.yaml" + }, + "5": { + "name": "constant.other.timestamp.yaml" + }, + "6": { + "name": "constant.language.value.yaml" + }, + "7": { + "name": "constant.language.merge.yaml" + } + }, + "match": "(?x)\n (?x:\n (null|Null|NULL|~)\n | (y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)\n | (\n (?:\n [-+]? 0b [0-1_]+ # (base 2)\n | [-+]? 0 [0-7_]+ # (base 8)\n | [-+]? (?: 0|[1-9][0-9_]*) # (base 10)\n | [-+]? 0x [0-9a-fA-F_]+ # (base 16)\n | [-+]? [1-9] [0-9_]* (?: :[0-5]?[0-9])+ # (base 60)\n )\n )\n | (\n (?x:\n [-+]? (?: [0-9] [0-9_]*)? \\. [0-9.]* (?: [eE] [-+] [0-9]+)? # (base 10)\n | [-+]? [0-9] [0-9_]* (?: :[0-5]?[0-9])+ \\. [0-9_]* # (base 60)\n | [-+]? \\. (?: inf|Inf|INF) # (infinity)\n | \\. (?: nan|NaN|NAN) # (not a number)\n )\n )\n | (\n (?x:\n \\d{4} - \\d{2} - \\d{2} # (y-m-d)\n | \\d{4} # (year)\n - \\d{1,2} # (month)\n - \\d{1,2} # (day)\n (?: [Tt] | [ \\t]+) \\d{1,2} # (hour)\n : \\d{2} # (minute)\n : \\d{2} # (second)\n (?: \\.\\d*)? # (fraction)\n (?:\n (?:[ \\t]*) Z\n | [-+] \\d{1,2} (?: :\\d{1,2})?\n )? # (time zone)\n )\n )\n | (=)\n | (<<)\n )\n (?:\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n )\n " + } + ] + }, + "flow-scalar-plain-out": { + "patterns": [ + { + "include": "#flow-scalar-plain-out-implicit-type" + }, + { + "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] \\S\n ", + "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n ", + "name": "string.unquoted.plain.out.yaml" + } + ] + }, + "flow-scalar-plain-out-implicit-type": { + "patterns": [ + { + "captures": { + "1": { + "name": "constant.language.null.yaml" + }, + "2": { + "name": "constant.language.boolean.yaml" + }, + "3": { + "name": "constant.numeric.integer.yaml" + }, + "4": { + "name": "constant.numeric.float.yaml" + }, + "5": { + "name": "constant.other.timestamp.yaml" + }, + "6": { + "name": "constant.language.value.yaml" + }, + "7": { + "name": "constant.language.merge.yaml" + } + }, + "match": "(?x)\n (?x:\n (null|Null|NULL|~)\n | (y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)\n | (\n (?:\n [-+]? 0b [0-1_]+ # (base 2)\n | [-+]? 0 [0-7_]+ # (base 8)\n | [-+]? (?: 0|[1-9][0-9_]*) # (base 10)\n | [-+]? 0x [0-9a-fA-F_]+ # (base 16)\n | [-+]? [1-9] [0-9_]* (?: :[0-5]?[0-9])+ # (base 60)\n )\n )\n | (\n (?x:\n [-+]? (?: [0-9] [0-9_]*)? \\. [0-9.]* (?: [eE] [-+] [0-9]+)? # (base 10)\n | [-+]? [0-9] [0-9_]* (?: :[0-5]?[0-9])+ \\. [0-9_]* # (base 60)\n | [-+]? \\. (?: inf|Inf|INF) # (infinity)\n | \\. (?: nan|NaN|NAN) # (not a number)\n )\n )\n | (\n (?x:\n \\d{4} - \\d{2} - \\d{2} # (y-m-d)\n | \\d{4} # (year)\n - \\d{1,2} # (month)\n - \\d{1,2} # (day)\n (?: [Tt] | [ \\t]+) \\d{1,2} # (hour)\n : \\d{2} # (minute)\n : \\d{2} # (second)\n (?: \\.\\d*)? # (fraction)\n (?:\n (?:[ \\t]*) Z\n | [-+] \\d{1,2} (?: :\\d{1,2})?\n )? # (time zone)\n )\n )\n | (=)\n | (<<)\n )\n (?x:\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n )\n " + } + ] + }, + "flow-scalar-single-quoted": { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.yaml" + } + }, + "end": "'(?!')", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.yaml" + } + }, + "name": "string.quoted.single.yaml", + "patterns": [ + { + "match": "''", + "name": "constant.character.escape.single-quoted.yaml" + } + ] + }, + "flow-sequence": { + "begin": "\\[", + "beginCaptures": { + "0": { + "name": "punctuation.definition.sequence.begin.yaml" + } + }, + "end": "\\]", + "endCaptures": { + "0": { + "name": "punctuation.definition.sequence.end.yaml" + } + }, + "name": "meta.flow-sequence.yaml", + "patterns": [ + { + "include": "#prototype" + }, + { + "match": ",", + "name": "punctuation.separator.sequence.yaml" + }, + { + "include": "#flow-pair" + }, + { + "include": "#flow-node" + } + ] + }, + "flow-value": { + "patterns": [ + { + "begin": "\\G(?![},\\]])", + "end": "(?=[},\\]])", + "name": "meta.flow-pair.value.yaml", + "patterns": [ + { + "include": "#flow-node" + } + ] + } + ] + }, + "node": { + "patterns": [ + { + "include": "#block-node" + } + ] + }, + "property": { + "begin": "(?=!|&)", + "end": "(?!\\G)", + "name": "meta.property.yaml", + "patterns": [ + { + "captures": { + "1": { + "name": "keyword.control.property.anchor.yaml" + }, + "2": { + "name": "punctuation.definition.anchor.yaml" + }, + "3": { + "name": "entity.name.type.anchor.yaml" + }, + "4": { + "name": "invalid.illegal.character.anchor.yaml" + } + }, + "match": "\\G((&))([^\\s\\[\\]/{/},]+)(\\S+)?" + }, + { + "match": "(?x)\n \\G\n (?:\n ! < (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )+ >\n | (?:!(?:[0-9A-Za-z\\-]*!)?) (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$_.~*'()] )+\n | !\n )\n (?=\\ |\\t|$)\n ", + "name": "storage.type.tag-handle.yaml" + }, + { + "match": "\\S+", + "name": "invalid.illegal.tag-handle.yaml" + } + ] + }, + "prototype": { + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#property" + } + ] + } + } +} \ No newline at end of file diff --git a/Moder.Core/Controls/TextEditorControl.axaml b/Moder.Core/Controls/TextEditorControl.axaml new file mode 100644 index 0000000..ccb0566 --- /dev/null +++ b/Moder.Core/Controls/TextEditorControl.axaml @@ -0,0 +1,15 @@ + + + diff --git a/Moder.Core/Controls/TextEditorControl.axaml.cs b/Moder.Core/Controls/TextEditorControl.axaml.cs new file mode 100644 index 0000000..a2c5279 --- /dev/null +++ b/Moder.Core/Controls/TextEditorControl.axaml.cs @@ -0,0 +1,134 @@ +using System.Diagnostics.CodeAnalysis; +using Avalonia.Controls; +using Avalonia.Media; +using AvaloniaEdit.TextMate; +using Moder.Core.Editor; + +namespace Moder.Core.Controls; + +public sealed partial class TextEditorControl : UserControl +{ + public string Text + { + get => TextEditor.Text; + set => TextEditor.Text = value; + } + private TextMate.Installation _installation; + private ParadoxRegistryOptions _options; + + public TextEditorControl() + { + InitializeComponent(); + InitializeTextEditor(); + + ActualThemeVariantChanged += (_, _) => + { + _installation.SetTheme(_options.LoadTheme(ActualThemeVariant)); + }; + } + + public void SetGrammar(string extensionName) + { + if (extensionName.Equals(".yml")) + { + _installation.SetGrammar(ScopeNameTypes.Yml); + } + else + { + _installation.SetGrammar(ScopeNameTypes.Hoi4); + } + } + + // TODO: 状态栏 + [MemberNotNull(nameof(_installation))] + [MemberNotNull(nameof(_options))] + private void InitializeTextEditor() + { + _options = new ParadoxRegistryOptions(App.Current.ActualThemeVariant); + TextEditor.Options.HighlightCurrentLine = true; + TextEditor.Options.EnableTextDragDrop = true; + TextEditor.TextArea.RightClickMovesCaret = true; + TextEditor.Options.ShowBoxForControlCharacters = true; + TextEditor.Options.AllowToggleOverstrikeMode = true; + TextEditor.ShowLineNumbers = true; + _installation = TextEditor.InstallTextMate(_options); + _installation.AppliedTheme += ChangeThemeOnAppliedTheme; + + ApplyThemeColorsToEditor(_installation); + } + + private void ChangeThemeOnAppliedTheme(object? sender, TextMate.Installation e) + { + ApplyThemeColorsToEditor(e); + } + + private void ApplyThemeColorsToEditor(TextMate.Installation installation) + { + ApplyBrushAction(installation, "editor.background", brush => TextEditor.Background = brush); + ApplyBrushAction(installation, "editor.foreground", brush => TextEditor.Foreground = brush); + + if ( + !ApplyBrushAction( + installation, + "editor.selectionBackground", + brush => TextEditor.TextArea.SelectionBrush = brush + ) + ) + { + if (App.Current.TryGetResource("TextAreaSelectionBrush", out var resourceObject)) + { + if (resourceObject is IBrush brush) + { + TextEditor.TextArea.SelectionBrush = brush; + } + } + } + + if ( + !ApplyBrushAction( + installation, + "editor.lineHighlightBackground", + brush => + { + TextEditor.TextArea.TextView.CurrentLineBackground = brush; + TextEditor.TextArea.TextView.CurrentLineBorder = new Pen(brush); + } + ) + ) + { + TextEditor.TextArea.TextView.SetDefaultHighlightLineColors(); + } + + if ( + !ApplyBrushAction( + installation, + "editorLineNumber.foreground", + brush => TextEditor.LineNumbersForeground = brush + ) + ) + { + TextEditor.LineNumbersForeground = TextEditor.Foreground; + } + } + + private static bool ApplyBrushAction( + TextMate.Installation e, + string colorKeyNameFromJson, + Action applyColorAction + ) + { + if (!e.TryGetThemeColor(colorKeyNameFromJson, out var colorString)) + { + return false; + } + + if (!Color.TryParse(colorString, out var color)) + { + return false; + } + + var colorBrush = new SolidColorBrush(color); + applyColorAction(colorBrush); + return true; + } +} diff --git a/Moder.Core/Editor/ParadoxRegistryOptions.cs b/Moder.Core/Editor/ParadoxRegistryOptions.cs index 5cfa321..758bab6 100644 --- a/Moder.Core/Editor/ParadoxRegistryOptions.cs +++ b/Moder.Core/Editor/ParadoxRegistryOptions.cs @@ -30,9 +30,17 @@ public IRawTheme GetTheme(string scopeName) public IRawGrammar GetGrammar(string scopeName) { - return GrammarReader.ReadGrammarSync( - File.OpenText(Path.Combine(GrammarsFolderPath, "paradox.tmLanguage.json")) - ); + // TODO: 补全语法格式文件 + string path; + if (scopeName == ScopeNameTypes.Yml) + { + path = Path.Combine(GrammarsFolderPath, "yaml", "syntaxes", "yaml.tmLanguage.json"); + } + else + { + path = Path.Combine(GrammarsFolderPath, "paradox.tmLanguage.json"); + } + return GrammarReader.ReadGrammarSync(File.OpenText(path)); } public ICollection? GetInjections(string scopeName) @@ -42,12 +50,17 @@ public IRawGrammar GetGrammar(string scopeName) public IRawTheme GetDefaultTheme() { - return ThemeReader.ReadThemeSync(File.OpenText(Path.Combine(ThemesFolderPath, GetThemeFileName(_theme)))); + return ThemeReader.ReadThemeSync( + File.OpenText(Path.Combine(ThemesFolderPath, GetThemeFileName(_theme))) + ); } - + public IRawTheme LoadTheme(ThemeVariant theme) { - return ThemeReader.ReadThemeSync(File.OpenText(Path.Combine(ThemesFolderPath, GetThemeFileName(theme))));; + return ThemeReader.ReadThemeSync( + File.OpenText(Path.Combine(ThemesFolderPath, GetThemeFileName(theme))) + ); + ; } private static string GetThemeFileName(ThemeVariant? theme) diff --git a/Moder.Core/Editor/ScopeNameTypes.cs b/Moder.Core/Editor/ScopeNameTypes.cs new file mode 100644 index 0000000..3b3fe4c --- /dev/null +++ b/Moder.Core/Editor/ScopeNameTypes.cs @@ -0,0 +1,7 @@ +namespace Moder.Core.Editor; + +public static class ScopeNameTypes +{ + public const string Yml = "source.yaml"; + public const string Hoi4 = "source.hoi4"; +} \ No newline at end of file diff --git a/Moder.Core/Infrastructure/ITabViewItem.cs b/Moder.Core/Infrastructure/ITabViewItem.cs index a32655a..7b17291 100644 --- a/Moder.Core/Infrastructure/ITabViewItem.cs +++ b/Moder.Core/Infrastructure/ITabViewItem.cs @@ -1,8 +1,12 @@ -namespace Moder.Core.Infrastructure; +using FluentAvalonia.UI.Controls; + +namespace Moder.Core.Infrastructure; public interface ITabViewItem { - // TODO: 添加Icon + /// + /// 选项卡显示的名称 + /// public string Header { get; } /// @@ -11,6 +15,11 @@ public interface ITabViewItem public string Id { get; } public string ToolTip { get; } + /// + /// 选项卡左侧显示的图标 + /// + public IconSource? Icon => null; + public bool Equals(ITabViewItem? other) { return Id == other?.Id; diff --git a/Moder.Core/Services/TabViewNavigationService.cs b/Moder.Core/Services/TabViewNavigationService.cs index 0f200c9..7c78e47 100644 --- a/Moder.Core/Services/TabViewNavigationService.cs +++ b/Moder.Core/Services/TabViewNavigationService.cs @@ -46,7 +46,12 @@ private void AddTabCore(TabViewItem? tabViewItem, Func action) if (tabViewItem is null) { var content = action(); - tabViewItem = new TabViewItem { Header = content.Header, Content = content }; + tabViewItem = new TabViewItem + { + Header = content.Header, + Content = content, + IconSource = content.Icon + }; ToolTip.SetTip(tabViewItem, content.ToolTip); _openedTabFileItems.Add(tabViewItem); diff --git a/Moder.Core/Views/Game/CharacterEditorControlView.axaml b/Moder.Core/Views/Game/CharacterEditorControlView.axaml index a55425d..bfd6d5c 100644 --- a/Moder.Core/Views/Game/CharacterEditorControlView.axaml +++ b/Moder.Core/Views/Game/CharacterEditorControlView.axaml @@ -2,8 +2,8 @@ x:Class="Moder.Core.Views.Game.CharacterEditorControlView" xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:avaloniaEdit="https://github.com/avaloniaui/avaloniaedit" xmlns:behaviors="clr-namespace:Moder.Core.Behaviors" + xmlns:controls="clr-namespace:Moder.Core.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity" xmlns:lang="clr-namespace:Moder.Language.Strings;assembly=Moder.Language" @@ -153,12 +153,11 @@