diff --git a/src/renderer/components/editor/grammars/languages.ts b/src/renderer/components/editor/grammars/languages.ts index 8df46c6b..8e383f3d 100644 --- a/src/renderer/components/editor/grammars/languages.ts +++ b/src/renderer/components/editor/grammars/languages.ts @@ -562,6 +562,12 @@ export const languages: LanguageOption[] = [ grammar: () => import('./textmate/nix.tmLanguage.json'), scopeName: 'source.nix', }, + { + name: 'Nushell', + value: 'nu', + grammar: () => import('./textmate/nu.tmLanguage.json'), + scopeName: 'source.nushell', + }, { name: 'NSIS', value: 'nsis', diff --git a/src/renderer/components/editor/grammars/textmate/nu.tmLanguage.json b/src/renderer/components/editor/grammars/textmate/nu.tmLanguage.json new file mode 100644 index 00000000..eff5e9ff --- /dev/null +++ b/src/renderer/components/editor/grammars/textmate/nu.tmLanguage.json @@ -0,0 +1,719 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "nushell", + "scopeName": "source.nushell", + "patterns": [ + { "include": "#define-variable" }, + { "include": "#define-alias" }, + { "include": "#function" }, + { "include": "#extern" }, + { "include": "#module" }, + { "include": "#use-module" }, + { "include": "#expression" }, + { "include": "#comment" } + ], + "repository": { + "string": { + "patterns": [ + { "include": "#string-single-quote" }, + { "include": "#string-backtick" }, + { "include": "#string-double-quote" }, + { "include": "#string-interpolated-double" }, + { "include": "#string-interpolated-single" }, + { "include": "#string-raw" }, + { "include": "#string-bare" } + ] + }, + "string-escape": { + "match": "\\\\(?:[bfrnt\\\\'\"/]|u[0-9a-fA-F]{4})", + "name": "constant.character.escape.nushell" + }, + "string-bare": { + "match": "[^$\\[{(\"',|#\\s|;][^\\[\\]{}()\"'\\s,|;]*", + "name": "string.bare.nushell" + }, + "string-raw": { + "begin": "r(#+)'", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.nushell" } + }, + "end": "'\\1", + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.nushell" } + }, + "name": "string.raw.nushell" + }, + "string-single-quote": { + "begin": "'", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.nushell" } + }, + "end": "'", + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.nushell" } + }, + "name": "string.quoted.single.nushell" + }, + "string-backtick": { + "begin": "`", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.nushell" } + }, + "end": "`", + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.nushell" } + }, + "name": "string.quoted.single.nushell" + }, + "string-double-quote": { + "begin": "\"", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.nushell" } + }, + "end": "\"", + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.nushell" } + }, + "name": "string.quoted.double.nushell", + "patterns": [ + { + "match": "\\w+" + }, + { "include": "#string-escape" } + ] + }, + "string-interpolated-double": { + "begin": "\\$\"", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.nushell" } + }, + "end": "\"", + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.nushell" } + }, + "name": "string.interpolated.double.nushell", + "patterns": [ + { + "match": "\\\\[()]", + "name": "constant.character.escape.nushell" + }, + { "include": "#string-escape" }, + { "include": "#paren-expression" } + ] + }, + "string-interpolated-single": { + "begin": "\\$'", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.nushell" } + }, + "end": "'", + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.nushell" } + }, + "name": "string.interpolated.single.nushell", + "patterns": [{ "include": "#paren-expression" }] + }, + "control-keywords": { + "comment": "Regex generated with list-to-tree (https://github.com/glcraft/list-to-tree)", + "match": "(?=]=?|[!=]~|\\+\\+=?)(?= |$)", + "name": "keyword.control.nushell" + }, + "operators": { + "patterns": [ + { "include": "#operators-word" }, + { "include": "#operators-symbols" }, + { "include": "#ranges" } + ] + }, + "table": { + "begin": "\\[", + "beginCaptures": { + "0": { "name": "meta.brace.square.begin.nushell" } + }, + "end": "\\]", + "endCaptures": { + "0": { "name": "meta.brace.square.end.nushell" } + }, + "name": "meta.table.nushell", + "patterns": [ + { "include": "#spread" }, + { "include": "#value" }, + { + "match": ",", + "name": "punctuation.separator.nushell" + } + ] + }, + "types": { + "patterns": [ + { + "name": "meta.list.nushell", + "begin": "\\b(list)\\s*<", + "beginCaptures": { + "1": { "name": "entity.name.type.nushell" } + }, + "end": ">", + "patterns": [{ "include": "#types" }] + }, + { + "name": "meta.record.nushell", + "begin": "\\b(record)\\s*<", + "beginCaptures": { + "1": { "name": "entity.name.type.nushell" } + }, + "end": ">", + "patterns": [ + { + "match": "([\\w\\-]+|\"[\\w\\- ]+\"|'[^']+')\\s*:\\s*", + "captures": { + "1": { "name": "variable.parameter.nushell" } + } + }, + { "include": "#types" } + ] + }, + { + "match": "\\b(\\w+)\\b", + "name": "entity.name.type.nushell" + } + ] + }, + "function-parameter": { + "patterns": [ + { + "match": "(-{0,2}|\\.{3})[\\w-]+(?:\\((-[\\w?])\\))?", + "name": "variable.parameter.nushell", + "captures": { + "1": { "name": "keyword.control.nushell" } + } + }, + { + "begin": "\\??:\\s*", + "end": "(?=(?:\\s+(?:-{0,2}|\\.{3})[\\w-]+)|(?:\\s*(?:,|\\]|\\||@|=|#|$)))", + "patterns": [{ "include": "#types" }] + }, + { + "begin": "@(?=\"|')", + "end": "(?<=\"|')", + "patterns": [{ "include": "#string" }] + }, + { + "name": "default.value.nushell", + "begin": "=\\s*", + "end": "(?=(?:\\s+-{0,2}[\\w-]+)|(?:\\s*(?:,|\\]|\\||#|$)))", + "patterns": [{ "include": "#value" }] + } + ] + }, + "function-parameters": { + "begin": "\\[", + "beginCaptures": { + "0": { "name": "meta.brace.square.begin.nushell" } + }, + "end": "\\]", + "endCaptures": { + "0": { "name": "meta.brace.square.end.nushell" } + }, + "patterns": [ + { "include": "#function-parameter" }, + { "include": "#comment" } + ], + "name": "meta.function.parameters.nushell" + }, + "function-multiple-inout": { + "begin": "(?<=]\\s*)(:)\\s+(\\[)", + "beginCaptures": { + "1": { "name": "punctuation.definition.in-out.nushell" }, + "2": { "name": "meta.brace.square.begin.nushell" } + }, + "end": "\\]", + "endCaptures": { + "0": { "name": "meta.brace.square.end.nushell" } + }, + "patterns": [ + { "include": "#types" }, + { + "match": "\\s*(,)\\s*", + "captures": { + "1": { "name": "punctuation.separator.nushell" } + } + }, + { + "match": "\\s+(->)\\s+", + "captures": { + "1": { "name": "keyword.operator.nushell" } + } + } + ] + }, + "function-inout": { + "patterns": [ + { "include": "#types" }, + { + "match": "->", + "name": "keyword.operator.nushell" + }, + { "include": "#function-multiple-inout" } + ] + }, + "function-body": { + "begin": "\\{", + "beginCaptures": { + "0": { "name": "punctuation.definition.function.begin.nushell" } + }, + "end": "\\}", + "endCaptures": { + "0": { "name": "punctuation.definition.function.end.nushell" } + }, + "name": "meta.function.body.nushell", + "patterns": [{ "include": "source.nushell" }] + }, + "function": { + "begin": "((?:export\\s+)?def)(?:\\s+((?:--\\w+(?:\\s+--\\w+)*)))?\\s+([\\w\\-]+|\"[\\w\\- ]+\"|'[\\w\\- ]+'|`[\\w\\- ]+`)(?:\\s+((?:--\\w+(?:\\s+--\\w+)*)))?", + "beginCaptures": { + "1": { "name": "entity.name.function.nushell" }, + "2": { "name": "entity.name.function.nushell" }, + "3": { "name": "entity.name.type.nushell" }, + "4": { "name": "entity.name.function.nushell" } + }, + "end": "(?<=\\})", + "patterns": [ + { "include": "#function-parameters" }, + { "include": "#function-body" }, + { "include": "#function-inout" } + ] + }, + "extern": { + "begin": "((?:export\\s+)?extern)\\s+([\\w\\-]+|\"[\\w\\- ]+\")", + "beginCaptures": { + "1": { "name": "entity.name.function.nushell" }, + "2": { "name": "entity.name.type.nushell" } + }, + "end": "(?<=\\])", + "endCaptures": { + "0": { "name": "punctuation.definition.function.end.nushell" } + }, + "patterns": [{ "include": "#function-parameters" }] + }, + "module": { + "begin": "((?:export\\s+)?module)\\s+([\\w\\-]+)\\s*\\{", + "beginCaptures": { + "1": { "name": "entity.name.function.nushell" }, + "2": { "name": "entity.name.namespace.nushell" } + }, + "end": "\\}", + "endCaptures": { + "0": { "name": "punctuation.definition.module.end.nushell" } + }, + "name": "meta.module.nushell", + "patterns": [{ "include": "source.nushell" }] + }, + "use-module": { + "patterns": [ + { + "match": "^\\s*((?:export )?use)\\s+([\\w\\-]+|\"[\\w\\- ]+\"|'[\\w\\- ]+')(?:\\s+([\\w\\-]+|\"[\\w\\- ]+\"|'[\\w\\- ]+'|\\*))?\\s*;?$", + "captures": { + "1": { "name": "entity.name.function.nushell" }, + "2": { "name": "entity.name.namespace.nushell" }, + "3": { "name": "keyword.other.nushell" } + } + }, + { + "begin": "^\\s*((?:export )?use)\\s+([\\w\\-]+|\"[\\w\\- ]+\"|'[\\w\\- ]+')\\s*\\[", + "beginCaptures": { + "1": { "name": "entity.name.function.nushell" }, + "2": { "name": "entity.name.namespace.nushell" } + }, + "end": "(\\])\\s*;?\\s*$", + "endCaptures": { + "1": { "name": "meta.brace.square.end.nushell" } + }, + "patterns": [ + { + "match": "([\\w\\-]+|\"[\\w\\- ]+\"|'[\\w\\- ]+'|\\*),?", + "captures": { + "1": { "name": "keyword.other.nushell" } + } + }, + { + "include": "#comment" + } + ] + }, + { + "match": "(?(?:/|\\\\|~[\\/\\\\]|\\.\\.?[\\/\\\\])?(?:[^\\/\\\\]+[\\/\\\\])*[\\w\\- ]+(?:\\.nu)?){0}^\\s*((?:export )?use)\\s+(\"\\g\"|'\\g\\'|(?![\"'])\\g)(?:\\s+([\\w\\-]+|\"[\\w\\- ]+\"|'[^']+'|\\*))?\\s*;?$", + "captures": { + "2": { "name": "entity.name.function.nushell" }, + "3": { + "name": "string.bare.nushell", + "patterns": [ + { + "match": "([\\w\\- ]+)(?:\\.nu)?(?=$|\"|')", + "captures": { + "1": { "name": "entity.name.namespace.nushell" } + } + } + ] + }, + "4": { "name": "keyword.other.nushell" } + } + }, + { + "begin": "(?(?:/|\\\\|~[\\/\\\\]|\\.\\.?[\\/\\\\])?(?:[^\\/\\\\]+[\\/\\\\])*[\\w\\- ]+(?:\\.nu)?){0}^\\s*((?:export )?use)\\s+(\"\\g\"|'\\g\\'|(?![\"'])\\g)\\s+\\[", + "beginCaptures": { + "2": { "name": "entity.name.function.nushell" }, + "3": { + "name": "string.bare.nushell", + "patterns": [ + { + "match": "([\\w\\- ]+)(?:\\.nu)?(?=$|\"|')", + "captures": { + "1": { "name": "entity.name.namespace.nushell" } + } + } + ] + } + }, + "end": "(\\])\\s*;?\\s*$", + "endCaptures": { + "1": { "name": "meta.brace.square.end.nushell" } + }, + "patterns": [ + { + "match": "([\\w\\-]+|\"[\\w\\- ]+\"|'[\\w\\- ]+'|\\*),?", + "captures": { + "0": { "name": "keyword.other.nushell" } + } + }, + { + "include": "#comment" + } + ] + }, + { + "match": "^\\s*(?:export )?use\\b", + "captures": { + "0": { "name": "entity.name.function.nushell" } + } + } + ] + }, + "for-loop": { + "begin": "(for)\\s+(\\$?\\w+)\\s+(in)\\s+(.+)\\s*(\\{)", + "beginCaptures": { + "1": { "name": "keyword.other.nushell" }, + "2": { "name": "variable.other.nushell" }, + "3": { "name": "keyword.other.nushell" }, + "4": { "patterns": [{ "include": "#value" }] }, + "5": { "name": "punctuation.section.block.begin.bracket.curly.nushell" } + }, + "end": "\\}", + "endCaptures": { + "0": { "name": "punctuation.section.block.end.bracket.curly.nushell" } + }, + "name": "meta.for-loop.nushell", + "patterns": [{ "include": "source.nushell" }] + }, + "paren-expression": { + "begin": "\\(", + "beginCaptures": { + "0": { "name": "meta.brace.round.begin.nushell" } + }, + "end": "\\)", + "endCaptures": { + "0": { "name": "meta.brace.round.end.nushell" } + }, + "name": "meta.expression.parenthesis.nushell", + "patterns": [{ "include": "#expression" }] + }, + "braced-expression": { + "begin": "\\{", + "beginCaptures": { + "0": { "name": "punctuation.section.block.begin.bracket.curly.nushell" } + }, + "end": "\\}", + "endCaptures": { + "0": { "name": "punctuation.section.block.end.bracket.curly.nushell" } + }, + "name": "meta.expression.braced.nushell", + "patterns": [ + { + "begin": "(?<=\\{)\\s*\\|", + "end": "\\|", + "name": "meta.closure.parameters.nushell", + "patterns": [{ "include": "#function-parameter" }] + }, + { + "match": "(\\w+)\\s*(:)\\s*", + "captures": { + "1": { "name": "variable.other.nushell" }, + "2": { "name": "keyword.control.nushell" } + } + }, + { + "match": "(\\$\"((?:[^\"\\\\]|\\\\.)*)\")\\s*(:)\\s*", + "captures": { + "1": { "name": "variable.other.nushell" }, + "2": { + "name": "variable.other.nushell", + "patterns": [{ "include": "#paren-expression" }] + }, + "3": { "name": "keyword.control.nushell" } + }, + "name": "meta.record-entry.nushell" + }, + { + "match": "(\"(?:[^\"\\\\]|\\\\.)*\")\\s*(:)\\s*", + "captures": { + "1": { "name": "variable.other.nushell" }, + "2": { "name": "keyword.control.nushell" } + }, + "name": "meta.record-entry.nushell" + }, + { + "match": "(\\$'([^']*)')\\s*(:)\\s*", + "captures": { + "1": { "name": "variable.other.nushell" }, + "2": { + "name": "variable.other.nushell", + "patterns": [{ "include": "#paren-expression" }] + }, + "3": { "name": "keyword.control.nushell" } + }, + "name": "meta.record-entry.nushell" + }, + { + "match": "('[^']*')\\s*(:)\\s*", + "captures": { + "1": { "name": "variable.other.nushell" }, + "2": { "name": "keyword.control.nushell" } + }, + "name": "meta.record-entry.nushell" + }, + { "include": "#spread" }, + { "include": "source.nushell" } + ] + }, + "define-variable": { + "match": "(let|mut|(?:export\\s+)?const)\\s+(\\w+)\\s+(=)", + "captures": { + "1": { "name": "keyword.other.nushell" }, + "2": { "name": "variable.other.nushell" }, + "3": { + "patterns": [{ "include": "#operators" }] + } + } + }, + "define-alias": { + "match": "((?:export )?alias)\\s+([\\w\\-!]+)\\s*(=)", + "captures": { + "1": { "name": "entity.name.function.nushell" }, + "2": { "name": "entity.name.type.nushell" }, + "3": { + "patterns": [{ "include": "#operators" }] + } + } + }, + "pre-command": { + "begin": "(\\w+)(=)", + "beginCaptures": { + "1": { "name": "variable.other.nushell" }, + "2": { + "patterns": [{ "include": "#operators" }] + } + }, + "end": "(?=\\s+)", + "patterns": [{ "include": "#value" }] + }, + + "command": { + "begin": "(?