From 3ce2ad902b387d07e3e7095abe538faf31377100 Mon Sep 17 00:00:00 2001 From: Christoph Brandau Date: Fri, 10 Jan 2025 08:06:42 +0100 Subject: [PATCH 1/2] first try --- syntaxes/tcl.tmLanguage.json | 5469 ++++++++++++++++++++++++++++++++++ 1 file changed, 5469 insertions(+) create mode 100644 syntaxes/tcl.tmLanguage.json diff --git a/syntaxes/tcl.tmLanguage.json b/syntaxes/tcl.tmLanguage.json new file mode 100644 index 0000000..2dbe685 --- /dev/null +++ b/syntaxes/tcl.tmLanguage.json @@ -0,0 +1,5469 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "foldingStartMarker": "([{(\\[])", + "foldingEndMarker": "([})\\]])", + "name": "Tcl", + "patterns": [ + { + "include": "#root" + } + ], + "repository": { + "root": { + "patterns": [ + { + "include": "#invariant" + }, + { + "include": "#brackets" + }, + { + "include": "#proc-call" + } + ] + }, + "invariant": { + "patterns": [ + { + "include": "#ignore-long-lines" + }, + { + "include": "#no-starting-empty-brackets" + }, + { + "include": "#no-empty-square-brackets" + } + ] + }, + "no-starting-empty-brackets": { + "patterns": [ + { + "match": "(?<=^)\\s*+(\\{\\}|\\[\\])", + "captures": { + "1": { + "name": "invalid.illegal.termination.tcl" + } + } + } + ] + }, + "no-empty-square-brackets": { + "patterns": [ + { + "match": "(\\[\\])", + "captures": { + "1": { + "name": "string.empty.square.brace" + } + } + } + ] + }, + "ignore-long-lines": { + "comment": "long lines are not parsed for performance", + "patterns": [ + { + "match": "^.{1000,}" + } + ] + }, + "brackets": { + "patterns": [ + { + "include": "#invariant" + }, + { + "include": "#special-brackets" + }, + { + "include": "#empty-brackets" + }, + { + "include": "#square-brackets" + }, + { + "include": "#curly-brackets" + } + ] + }, + "square-brackets": { + "patterns": [ + { + "begin": "\\s*+(?])", + "name": "support.type.expression.operator.tcl" + }, + { + "comment": "expression bitwise", + "match": "([|^&!~])", + "name": "support.type.expression.operator.tcl" + }, + { + "comment": "expression ternary", + "match": "([?:])", + "name": "support.type.expression.operator.tcl" + } + ] + }, + "expression-functions": { + "patterns": [ + { + "begin": "\\b(abs|acos|asin|atan|atan2|bool|ceil|cos|cosh|double|entier|exp|floor|fmod|hypot|int|isqrt|log|log10|max|min|pow|rand|round|sin|sinh|sqrt|srand|tan|tanh|wide)\\b(\\()", + "end": "(\\))", + "beginCaptures": { + "1": { + "name": "entity.function.name.math.function.punctuatio.italic.tcl" + }, + "2": { + "name": "entity.function.name.math.function.brace.open.tcl" + } + }, + "endCaptures": { + "1": { + "name": "entity.function.name.math.function.brace.close.tcl" + } + }, + "patterns": [ + { + "include": "#expressions" + } + ] + } + ] + }, + "tcl-vwait": { + "patterns": [ + { + "include": "#line-escape" + }, + { + "comment": "vwait varName", + "begin": "(?<=^|\\[|{|;)\\s*(::)?\\b(vwait)\\b\\s*+(?!$|\n|;|^|\\]|})", + "end": "(?=$|\n|;|\\]|}|\\s)\\s*([^$\n^\\];}\\[\\\\]*)?(\\\\(?!\n))?", + "beginCaptures": { + "1": { + "name": "support.type.ns.tcl" + }, + "2": { + "name": "keyword.control.vwait.tcl" + } + }, + "endCaptures": { + "1": { + "name": "invalid.illegal.numargs.tcl" + }, + "2": { + "name": "invalid.illegal.escape.tcl" + } + }, + "patterns": [ + { + "include": "#line-escape" + }, + { + "include": "#variable" + }, + { + "include": "#variable-bare-italic" + } + ] + } + ] + }, + "tcl-proc": { + "patterns": [ + { + "begin": "(?<=^|[\\[{;])\\s*(::)?\\b(proc)\\b\\s+([^\\s\n]+)\\s+(?={|\\b|\\[|\"|\\\\$)", + "end": "(?=(?|=|==|<=|>=|>_|_<|%))(?=\\s*\\|)", + "name": "support.type" + }, + { + "begin": "\\s*+(\\|)", + "end": "(?=$|;|\n|}|\\])", + "beginCaptures": { + "1": { + "name": "entity.function.name.condition.tcl" + } + }, + "name": "string", + "patterns": [ + { + "include": "#variable-non-substituting" + }, + { + "include": "#glob-match" + }, + { + "include": "#constant-numeric" + } + ] + } + ] + } + ] + }, + "tcl-state-setter-getter": { + "patterns": [ + { + "begin": "(?<=set|get|pull|push)\\b", + "end": "(?=(?)", + "captures": { + "1": { + "name": "meta.constant" + } + } + }, + { + "include": "#variable" + }, + { + "include": "#square-brackets" + }, + { + "include": "#variable-bare" + }, + { + "begin": "\\s*({)", + "end": "(})", + "patterns": [ + { + "match": "(?<={)\\s*([^\\s}]*)", + "name": "string.pull.prop.tcl" + }, + { + "begin": "(?<=\\s)([^\\s}]*)", + "end": "(?=})", + "captures": { + "1": { + "patterns": [ + { + "include": "#variable-bare-italic" + } + ] + } + }, + "patterns": [ + { + "include": "#constant-numeric" + }, + { + "begin": "\\s*({)", + "end": "(})", + "contentName": "string.dict.pull.default.tcl", + "captures": { + "1": { + "name": "entity.function.name.dict.pull.props.tcl" + } + } + }, + { + "include": "#bare-string" + } + ] + }, + { + "include": "#constant-numeric" + } + ] + } + ] + }, + { + "begin": "(?<=set|unset|lappend|incr)\\b", + "end": "(?=(?)", + "name": "meta.constant.re.trashvar.tcl" + }, + { + "include": "#opt" + }, + { + "begin": "\\s*({|\")", + "end": "(}|\")(?=\\s+(?:\\\\\n|$|\n|\\[|\\$|\\b|\"|;|}|-))", + "contentName": "string.tcl", + "patterns": [ + { + "include": "#regular-expression" + } + ] + }, + { + "include": "#quoted-string" + }, + { + "include": "#variable" + }, + { + "include": "#variable-bare-italic" + } + ] + }, + { + "begin": "(?<=_regexp|_re)\\s+(?={|\")", + "end": "(?=(?)|(@|}|$|\n)|\\|", + "beginCaptures": { + "1": { + "name": "support.type.annotate.tcl" + } + }, + "endCaptures": { + "1": { + "name": "support.type.annotate.tcl" + } + }, + "patterns": [ + { + "include": "#variable-non-substituting" + }, + { + "include": "#namespace-separator" + } + ] + } + ] + }, + "annotate-properties": { + "begin": "(?=\\s*@[^\\s\n])", + "end": "(?=$|[\n}@])", + "patterns": [ + { + "comment": "special @ values that are meant as property values", + "match": "\\s*+(@)\\b(type)\\b(\\s+[^{}|@\\[<>-]*)?", + "captures": { + "1": { + "name": "meta.constant.annotate.property.tcl" + }, + "2": { + "name": "support.type.name.tcl" + }, + "3": { + "name": "entity.function.property.name.tcl" + } + } + }, + { + "comment": "special @ values that are meant as property values", + "match": "\\s*+(@)\\b(arg(?:s)?|returns|key|prop|if|example|param|params|opt|option|argument|val|value)\\b(\\s+[^\\/{}|@\\[<>]*)?", + "captures": { + "1": { + "name": "support.type.annotate.property.tcl" + }, + "2": { + "name": "variable.property.name.tcl" + }, + "3": { + "name": "support.type", + "patterns": [ + { + "include": "#opt" + } + ] + } + } + }, + { + "comment": "@ (no space after @)", + "match": "\\s*+(@)\\b([^\\s]*)\\b(\\s+[^\\/{}|@\\[<>-]*)?", + "captures": { + "1": { + "name": "meta.constant.annotate.property.tcl" + }, + "2": { + "name": "entity.function.property.name.tcl" + }, + "3": { + "name": "support.type.tcl" + } + } + }, + { + "include": "#annotate" + } + ] + }, + "annotate-control-block": { + "patterns": [ + { + "comment": "bracketed within a comment", + "contentName": "keyword.operator", + "begin": "^\\s*+(?={)", + "end": "(?<=})", + "patterns": [ + { + "include": "#brackets" + } + ] + } + ] + }, + "annotate-proc-call": { + "patterns": [ + { + "begin": "(\\[)", + "end": "(\\])", + "beginCaptures": { + "1": { + "name": "support.type.annotate.proc-call.tcl" + } + }, + "endCaptures": { + "1": { + "name": "support.type.annotate.proc-call.tcl" + } + }, + "patterns": [ + { + "include": "#proc-call" + } + ] + } + ] + }, + "annotate-type": { + "patterns": [ + { + "comment": "adding @ in a multi-line will make the line emphasized", + "contentName": "entity.function.name.comment.annotate.tcl", + "begin": "\\s*+({)", + "end": "\\s*(})", + "beginCaptures": { + "1": { + "name": "meta.constant.comment.annotate.tcl" + } + }, + "endCaptures": { + "1": { + "name": "meta.constant.comment.annotate.tcl" + } + }, + "patterns": [ + { + "include": "#annotate-regular-expression" + }, + { + "include": "#annotate-proc-call" + }, + { + "begin": "(<)", + "end": "(>)|(?=[}])", + "contentName": "support.type.comment.annotate.property.punctuation.italic.tcl", + "patterns": [ + { + "include": "#annotate-regular-expression" + }, + { + "match": "(\\|)", + "name": "entity.function.name.tcl" + }, + { + "include": "#variable-non-substituting" + }, + { + "match": "([,])", + "name": "entity.function.name.annotate.opt.tcl" + }, + { + "match": "([-])", + "name": "meta.constant.annotate.opt.tcl" + } + ] + }, + { + "match": "(?:(?<={|\\|)([?*])|([?*])(?=}|\\|))", + "name": "variable.modifier.annotate.punctuation.italic.tcl" + }, + { + "match": "(\\|)", + "name": "meta.constant.comment.annotate.tcl" + } + ] + } + ] + }, + "annotate-regular-expression": { + "patterns": [ + { + "begin": "(/)", + "end": "(/|$)", + "beginCaptures": { + "1": { + "name": "support.type.annotate.re.brace.open.tcl" + } + }, + "endCaptures": { + "1": { + "name": "support.type.annotate.re.brace.close.tcl" + } + }, + "contentName": "string.re.expression.comment.annotate.contents.tcl", + "patterns": [ + { + "include": "#regular-expression" + } + ] + } + ] + }, + "annotate-highlight": { + "patterns": [ + { + "comment": "adding | in a multi-line will make the line highlighted (string)", + "match": "(?<=\\|)\\s*([^|]*)", + "captures": { + "1": { + "name": "string.quote.annotate.comment.tcl", + "patterns": [ + { + "include": "#annotate-type" + }, + { + "include": "#annotate-proc-call" + }, + { + "include": "#variable-non-substituting" + }, + { + "match": "\\b(http://([^\\s]*))", + "name": "entity.function.name.markup.underline" + } + ] + } + } + } + ] + }, + "annotate-header": { + "patterns": [ + { + "comment": "adding > in a multi-line will make the line emphasized", + "begin": "\\s*+(>)", + "end": "(<)|(?=$|>)", + "contentName": "meta.constant.annotate.header.tcl", + "captures": { + "1": { + "name": "entity.function.name.annotate.tcl" + }, + "2": { + "name": "meta.constant.annotate.header.tcl" + } + }, + "patterns": [ + { + "include": "#annotate" + } + ] + } + ] + }, + "annotate-list": { + "patterns": [ + { + "match": "^\\s*([0-9]\\.)\\s+", + "name": "meta.class" + } + ] + }, + "opt": { + "patterns": [ + { + "comment": "Handle options sent to commands at various points (cmd -name1 value -name2 value)", + "match": "\\s*+(?<=\\s|^|\"|\\()((-)(?!-|\\s|\"|;|\n|>)[^\\s$\n\\[\\];\"{)(}]*)", + "captures": { + "1": { + "name": "support.type.opt.tcl" + }, + "2": { + "name": "meta.constant.opt.start.tcl" + } + } + } + ] + }, + "line-escape": { + "begin": "\\s*+(\\\\\n)$", + "end": "(^)(?:\\s*(?!$))?", + "beginCaptures": { + "1": { + "name": "constant.character.escape.newline.tcl" + } + }, + "endCaptures": { + "1": { + "name": "meta.lineescape.highlight.tcl" + } + } + }, + "glob-match": { + "patterns": [ + { + "begin": "({)", + "end": "(})", + "patterns": [ + { + "include": "#glob-match" + } + ] + }, + { + "match": "\\s*+(\\*)", + "name": "meta.class" + }, + { + "include": "#string-escapes" + }, + { + "begin": "(?|<|,))(?\\*}\\]/\"\\);\\(\\\\\\$,\\-\\+\\*]*)(\\([^\\s\\\\;\\*}\\]\"\\)\\(\\$,\\-\\+\\*<>]*\\))?)", + "captures": { + "1": { + "name": "support.type.variable.indicator.tcl" + }, + "2": { + "name": "entity.function.name.variable.brace.open.tcl" + }, + "3": { + "patterns": [ + { + "include": "#namespace-separator" + }, + { + "include": "#variable" + }, + { + "match": "([^\\s:\"}{]+)", + "name": "meta.constant.tcl" + } + ] + }, + "4": { + "patterns": [ + { + "begin": "(\\()", + "end": "(\\))", + "contentName": "punctuation.italic.meta.constant", + "beginCaptures": { + "1": { + "name": "support.type" + } + }, + "endCaptures": { + "1": { + "name": "support.type" + } + }, + "patterns": [ + { + "include": "#proc-call-args" + } + ] + } + ] + }, + "5": { + "name": "entity.function.name.variable.brace.close.tcl" + }, + "6": { + "patterns": [ + { + "include": "#namespace-separator" + }, + { + "match": "([^\\s:\"}{\\\\\\]\\[]+)", + "name": "meta.constant" + } + ] + }, + "7": { + "patterns": [ + { + "begin": "(\\()", + "end": "(\\))", + "contentName": "punctuation.italic.meta.constant", + "beginCaptures": { + "1": { + "name": "entity.function.name" + } + }, + "endCaptures": { + "1": { + "name": "entity.function.name" + } + }, + "patterns": [ + { + "include": "#proc-call-args" + } + ] + } + ] + } + } + } + ] + } + }, + "scopeName": "source.tcl" +} \ No newline at end of file From 5c41b8fa0afce166612753f29bc4475c69de905e Mon Sep 17 00:00:00 2001 From: Christoph Brandau Date: Fri, 10 Jan 2025 16:44:50 +0100 Subject: [PATCH 2/2] implement tcl --- package.json | 16 + syntaxes/tcl.tmLanguage.json | 5589 ++-------------------------------- syntaxes/tm.xml | 638 ++++ test/file.cdl | 32 +- test/test.tcl | 3 + 5 files changed, 945 insertions(+), 5333 deletions(-) create mode 100644 syntaxes/tm.xml create mode 100644 test/test.tcl diff --git a/package.json b/package.json index 4ccc034..c33cf10 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,17 @@ ], "contributes": { "languages": [ + { + "id": "tcl", + "aliases": [ + "NX TCL", + "tcl" + ], + "extensions": [ + ".tcl" + ], + "configuration": "./language-configuration.json" + }, { "id": "cdl", "aliases": [ @@ -46,6 +57,11 @@ } ], "grammars": [ + { + "language": "tcl", + "scopeName": "source.tcl", + "path": "./syntaxes/tcl.tmLanguage.json" + }, { "language": "cdl", "scopeName": "source.cdl", diff --git a/syntaxes/tcl.tmLanguage.json b/syntaxes/tcl.tmLanguage.json index 2dbe685..2d7bc5f 100644 --- a/syntaxes/tcl.tmLanguage.json +++ b/syntaxes/tcl.tmLanguage.json @@ -1,5469 +1,424 @@ { - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "foldingStartMarker": "([{(\\[])", - "foldingEndMarker": "([})\\]])", - "name": "Tcl", + "fileTypes": [ + "tcl" + ], + "name": "tcl", "patterns": [ { - "include": "#root" + "include": "#main" } ], + "scopeName": "source.tcl", "repository": { - "root": { + "main": { "patterns": [ { - "include": "#invariant" - }, - { - "include": "#brackets" - }, - { - "include": "#proc-call" + "include": "#command" } ] }, - "invariant": { + "args": { "patterns": [ { - "include": "#ignore-long-lines" + "include": "#quoted_args" }, { - "include": "#no-starting-empty-brackets" + "include": "#numeric" }, { - "include": "#no-empty-square-brackets" + "match": "((?<=;)\\s*#.*$)", + "name": "comment.tcl", + "comment": "Inline comments." } ] }, - "no-starting-empty-brackets": { + "braced": { "patterns": [ { - "match": "(?<=^)\\s*+(\\{\\}|\\[\\])", - "captures": { - "1": { - "name": "invalid.illegal.termination.tcl" - } - } - } - ] - }, - "no-empty-square-brackets": { - "patterns": [ - { - "match": "(\\[\\])", - "captures": { - "1": { - "name": "string.empty.square.brace" - } - } - } - ] - }, - "ignore-long-lines": { - "comment": "long lines are not parsed for performance", - "patterns": [ - { - "match": "^.{1000,}" - } - ] - }, - "brackets": { - "patterns": [ - { - "include": "#invariant" - }, - { - "include": "#special-brackets" - }, - { - "include": "#empty-brackets" - }, - { - "include": "#square-brackets" - }, - { - "include": "#curly-brackets" - } - ] - }, - "square-brackets": { - "patterns": [ - { - "begin": "\\s*+(?(?:\\\\{|\\\\}|[^\\x{007b}\\x{007d}])*)*)})", + "name": "none.tcl", + "comment": "Handle braced literal." + } + ] + }, + "braced_lit_re": { + "patterns": [ + { + "match": "((?:(?(?:\\\\{|\\\\}|[^\\x{007b}\\x{007d}])*)*)})", + "name": "string.regexp.tcl", + "comment": "Handle braced regex pattern." + } + ] + }, + "command": { + "patterns": [ + { + "begin": "(\\\\\\s*$)", + "beginCaptures": { + "1": { + "name": "constant.character.escape.tcl" + } + }, + "patterns": [ + { + "include": "#command__1" + } + ], + "end": "((?(?:\\\\{|\\\\}|[^\\x{007b}\\x{007d}])*)*)})", + "captures": { + "1": { + "name": "keyword.tcl" + }, + "2": { + "name": "entity.name.function.tcl" + }, + "3": { + "name": "none.tcl" + } + }, + "comment": "Proc command." + }, + { + "include": "#regexp" + }, + { + "include": "#keywords" + }, + { + "match": "(^\\s*\\S+|(?:(?<=[^\\x{005c}]\\[)[^\\s\\]]++(?!\\])))", + "name": "keyword.tcl", + "comment": "All other commands. (NOTE: Iro doesn't support possessive quantifiers, but the grammar does; be sure to replace the second + with ++ after regenerating!)" + }, + { + "include": "#args" + } + ] + }, + "command__1": { + "patterns": [ + { + "include": "#keywords" + }, + { + "include": "#args" + } + ] + }, + "embedded": { + "patterns": [ + { + "begin": "((?])", - "name": "support.type.expression.operator.tcl" - }, - { - "comment": "expression bitwise", - "match": "([|^&!~])", - "name": "support.type.expression.operator.tcl" - }, - { - "comment": "expression ternary", - "match": "([?:])", - "name": "support.type.expression.operator.tcl" - } - ] - }, - "expression-functions": { - "patterns": [ - { - "begin": "\\b(abs|acos|asin|atan|atan2|bool|ceil|cos|cosh|double|entier|exp|floor|fmod|hypot|int|isqrt|log|log10|max|min|pow|rand|round|sin|sinh|sqrt|srand|tan|tanh|wide)\\b(\\()", - "end": "(\\))", - "beginCaptures": { - "1": { - "name": "entity.function.name.math.function.punctuatio.italic.tcl" - }, - "2": { - "name": "entity.function.name.math.function.brace.open.tcl" - } - }, - "endCaptures": { - "1": { - "name": "entity.function.name.math.function.brace.close.tcl" - } - }, - "patterns": [ - { - "include": "#expressions" - } - ] - } - ] - }, - "tcl-vwait": { - "patterns": [ - { - "include": "#line-escape" - }, - { - "comment": "vwait varName", - "begin": "(?<=^|\\[|{|;)\\s*(::)?\\b(vwait)\\b\\s*+(?!$|\n|;|^|\\]|})", - "end": "(?=$|\n|;|\\]|}|\\s)\\s*([^$\n^\\];}\\[\\\\]*)?(\\\\(?!\n))?", - "beginCaptures": { - "1": { - "name": "support.type.ns.tcl" - }, - "2": { - "name": "keyword.control.vwait.tcl" - } - }, - "endCaptures": { - "1": { - "name": "invalid.illegal.numargs.tcl" - }, - "2": { - "name": "invalid.illegal.escape.tcl" - } - }, - "patterns": [ - { - "include": "#line-escape" - }, - { - "include": "#variable" - }, - { - "include": "#variable-bare-italic" - } - ] - } - ] - }, - "tcl-proc": { - "patterns": [ - { - "begin": "(?<=^|[\\[{;])\\s*(::)?\\b(proc)\\b\\s+([^\\s\n]+)\\s+(?={|\\b|\\[|\"|\\\\$)", - "end": "(?=(?|=|==|<=|>=|>_|_<|%))(?=\\s*\\|)", - "name": "support.type" - }, - { - "begin": "\\s*+(\\|)", - "end": "(?=$|;|\n|}|\\])", - "beginCaptures": { - "1": { - "name": "entity.function.name.condition.tcl" - } - }, - "name": "string", - "patterns": [ - { - "include": "#variable-non-substituting" - }, - { - "include": "#glob-match" - }, - { - "include": "#constant-numeric" - } - ] - } - ] - } - ] - }, - "tcl-state-setter-getter": { - "patterns": [ - { - "begin": "(?<=set|get|pull|push)\\b", - "end": "(?=(?)", - "captures": { - "1": { - "name": "meta.constant" - } - } - }, - { - "include": "#variable" - }, - { - "include": "#square-brackets" - }, - { - "include": "#variable-bare" - }, - { - "begin": "\\s*({)", - "end": "(})", - "patterns": [ - { - "match": "(?<={)\\s*([^\\s}]*)", - "name": "string.pull.prop.tcl" - }, - { - "begin": "(?<=\\s)([^\\s}]*)", - "end": "(?=})", - "captures": { - "1": { - "patterns": [ - { - "include": "#variable-bare-italic" - } - ] - } - }, - "patterns": [ - { - "include": "#constant-numeric" - }, - { - "begin": "\\s*({)", - "end": "(})", - "contentName": "string.dict.pull.default.tcl", - "captures": { - "1": { - "name": "entity.function.name.dict.pull.props.tcl" - } - } - }, - { - "include": "#bare-string" - } - ] - }, - { - "include": "#constant-numeric" - } - ] - } - ] - }, - { - "begin": "(?<=set|unset|lappend|incr)\\b", - "end": "(?=(?)", - "name": "meta.constant.re.trashvar.tcl" - }, - { - "include": "#opt" - }, - { - "begin": "\\s*({|\")", - "end": "(}|\")(?=\\s+(?:\\\\\n|$|\n|\\[|\\$|\\b|\"|;|}|-))", - "contentName": "string.tcl", - "patterns": [ - { - "include": "#regular-expression" - } - ] - }, - { - "include": "#quoted-string" - }, - { - "include": "#variable" - }, - { - "include": "#variable-bare-italic" + "include": "#regexp__1" } - ] - }, - { - "begin": "(?<=_regexp|_re)\\s+(?={|\")", - "end": "(?=(?)|(@|}|$|\n)|\\|", - "beginCaptures": { - "1": { - "name": "support.type.annotate.tcl" - } - }, - "endCaptures": { - "1": { - "name": "support.type.annotate.tcl" - } - }, - "patterns": [ - { - "include": "#variable-non-substituting" - }, - { - "include": "#namespace-separator" - } - ] - } - ] - }, - "annotate-properties": { - "begin": "(?=\\s*@[^\\s\n])", - "end": "(?=$|[\n}@])", - "patterns": [ - { - "comment": "special @ values that are meant as property values", - "match": "\\s*+(@)\\b(type)\\b(\\s+[^{}|@\\[<>-]*)?", - "captures": { - "1": { - "name": "meta.constant.annotate.property.tcl" - }, - "2": { - "name": "support.type.name.tcl" - }, - "3": { - "name": "entity.function.property.name.tcl" - } - } - }, - { - "comment": "special @ values that are meant as property values", - "match": "\\s*+(@)\\b(arg(?:s)?|returns|key|prop|if|example|param|params|opt|option|argument|val|value)\\b(\\s+[^\\/{}|@\\[<>]*)?", - "captures": { - "1": { - "name": "support.type.annotate.property.tcl" - }, - "2": { - "name": "variable.property.name.tcl" - }, - "3": { - "name": "support.type", - "patterns": [ - { - "include": "#opt" - } - ] - } - } - }, - { - "comment": "@ (no space after @)", - "match": "\\s*+(@)\\b([^\\s]*)\\b(\\s+[^\\/{}|@\\[<>-]*)?", - "captures": { - "1": { - "name": "meta.constant.annotate.property.tcl" - }, - "2": { - "name": "entity.function.property.name.tcl" - }, - "3": { - "name": "support.type.tcl" - } - } - }, - { - "include": "#annotate" - } - ] - }, - "annotate-control-block": { - "patterns": [ - { - "comment": "bracketed within a comment", - "contentName": "keyword.operator", - "begin": "^\\s*+(?={)", - "end": "(?<=})", - "patterns": [ - { - "include": "#brackets" - } - ] - } - ] - }, - "annotate-proc-call": { - "patterns": [ - { - "begin": "(\\[)", - "end": "(\\])", - "beginCaptures": { - "1": { - "name": "support.type.annotate.proc-call.tcl" - } - }, - "endCaptures": { - "1": { - "name": "support.type.annotate.proc-call.tcl" - } - }, - "patterns": [ - { - "include": "#proc-call" - } - ] - } - ] - }, - "annotate-type": { - "patterns": [ - { - "comment": "adding @ in a multi-line will make the line emphasized", - "contentName": "entity.function.name.comment.annotate.tcl", - "begin": "\\s*+({)", - "end": "\\s*(})", - "beginCaptures": { - "1": { - "name": "meta.constant.comment.annotate.tcl" - } - }, - "endCaptures": { - "1": { - "name": "meta.constant.comment.annotate.tcl" - } - }, - "patterns": [ - { - "include": "#annotate-regular-expression" - }, - { - "include": "#annotate-proc-call" - }, - { - "begin": "(<)", - "end": "(>)|(?=[}])", - "contentName": "support.type.comment.annotate.property.punctuation.italic.tcl", - "patterns": [ - { - "include": "#annotate-regular-expression" - }, - { - "match": "(\\|)", - "name": "entity.function.name.tcl" - }, - { - "include": "#variable-non-substituting" - }, - { - "match": "([,])", - "name": "entity.function.name.annotate.opt.tcl" - }, - { - "match": "([-])", - "name": "meta.constant.annotate.opt.tcl" - } - ] - }, - { - "match": "(?:(?<={|\\|)([?*])|([?*])(?=}|\\|))", - "name": "variable.modifier.annotate.punctuation.italic.tcl" - }, - { - "match": "(\\|)", - "name": "meta.constant.comment.annotate.tcl" - } - ] - } - ] - }, - "annotate-regular-expression": { - "patterns": [ - { - "begin": "(/)", - "end": "(/|$)", - "beginCaptures": { - "1": { - "name": "support.type.annotate.re.brace.open.tcl" - } - }, - "endCaptures": { - "1": { - "name": "support.type.annotate.re.brace.close.tcl" - } - }, - "contentName": "string.re.expression.comment.annotate.contents.tcl", - "patterns": [ - { - "include": "#regular-expression" - } - ] - } - ] - }, - "annotate-highlight": { - "patterns": [ - { - "comment": "adding | in a multi-line will make the line highlighted (string)", - "match": "(?<=\\|)\\s*([^|]*)", - "captures": { - "1": { - "name": "string.quote.annotate.comment.tcl", - "patterns": [ - { - "include": "#annotate-type" - }, - { - "include": "#annotate-proc-call" - }, - { - "include": "#variable-non-substituting" - }, - { - "match": "\\b(http://([^\\s]*))", - "name": "entity.function.name.markup.underline" - } - ] - } - } - } - ] - }, - "annotate-header": { - "patterns": [ - { - "comment": "adding > in a multi-line will make the line emphasized", - "begin": "\\s*+(>)", - "end": "(<)|(?=$|>)", - "contentName": "meta.constant.annotate.header.tcl", - "captures": { - "1": { - "name": "entity.function.name.annotate.tcl" - }, - "2": { - "name": "meta.constant.annotate.header.tcl" - } - }, - "patterns": [ - { - "include": "#annotate" - } - ] - } - ] - }, - "annotate-list": { - "patterns": [ - { - "match": "^\\s*([0-9]\\.)\\s+", - "name": "meta.class" - } - ] - }, - "opt": { - "patterns": [ - { - "comment": "Handle options sent to commands at various points (cmd -name1 value -name2 value)", - "match": "\\s*+(?<=\\s|^|\"|\\()((-)(?!-|\\s|\"|;|\n|>)[^\\s$\n\\[\\];\"{)(}]*)", - "captures": { - "1": { - "name": "support.type.opt.tcl" - }, - "2": { - "name": "meta.constant.opt.start.tcl" - } - } - } - ] - }, - "line-escape": { - "begin": "\\s*+(\\\\\n)$", - "end": "(^)(?:\\s*(?!$))?", - "beginCaptures": { - "1": { - "name": "constant.character.escape.newline.tcl" - } - }, - "endCaptures": { - "1": { - "name": "meta.lineescape.highlight.tcl" - } - } - }, - "glob-match": { - "patterns": [ - { - "begin": "({)", - "end": "(})", - "patterns": [ - { - "include": "#glob-match" - } - ] - }, - { - "match": "\\s*+(\\*)", - "name": "meta.class" - }, - { - "include": "#string-escapes" - }, - { - "begin": "(?|<|,))(?\\*}\\]/\"\\);\\(\\\\\\$,\\-\\+\\*]*)(\\([^\\s\\\\;\\*}\\]\"\\)\\(\\$,\\-\\+\\*<>]*\\))?)", - "captures": { - "1": { - "name": "support.type.variable.indicator.tcl" - }, - "2": { - "name": "entity.function.name.variable.brace.open.tcl" - }, - "3": { - "patterns": [ - { - "include": "#namespace-separator" - }, - { - "include": "#variable" - }, - { - "match": "([^\\s:\"}{]+)", - "name": "meta.constant.tcl" - } - ] - }, - "4": { - "patterns": [ - { - "begin": "(\\()", - "end": "(\\))", - "contentName": "punctuation.italic.meta.constant", - "beginCaptures": { - "1": { - "name": "support.type" - } - }, - "endCaptures": { - "1": { - "name": "support.type" - } - }, - "patterns": [ - { - "include": "#proc-call-args" - } - ] - } - ] - }, - "5": { - "name": "entity.function.name.variable.brace.close.tcl" - }, - "6": { - "patterns": [ - { - "include": "#namespace-separator" - }, - { - "match": "([^\\s:\"}{\\\\\\]\\[]+)", - "name": "meta.constant" - } - ] - }, - "7": { - "patterns": [ - { - "begin": "(\\()", - "end": "(\\))", - "contentName": "punctuation.italic.meta.constant", - "beginCaptures": { - "1": { - "name": "entity.function.name" - } - }, - "endCaptures": { - "1": { - "name": "entity.function.name" - } - }, - "patterns": [ - { - "include": "#proc-call-args" - } - ] - } - ] - } - } + "include": "#variable" + }, + { + "match": "(\\\\\"|[^\\x{0022}])", + "name": "string.tcl", + "comment": "All other quoted text." } ] } - }, - "scopeName": "source.tcl" + } } \ No newline at end of file diff --git a/syntaxes/tm.xml b/syntaxes/tm.xml new file mode 100644 index 0000000..e7d6e7b --- /dev/null +++ b/syntaxes/tm.xml @@ -0,0 +1,638 @@ + + + + + fileTypes + + tcl + + name + tcl + patterns + + + include + #main + + + scopeName + source.tcl + uuid + c7017136-2ff2-48e9-bdb0-570cf238b4a2 + repository + + main + + patterns + + + include + #command + + + + args + + patterns + + + include + #quoted_args + + + include + #numeric + + + match + ((?<=;)\s*#.*$) + name + comment.tcl + comment + Inline comments. + + + + braced + + patterns + + + begin + ((?<!\\)\{) + beginCaptures + + 1 + + name + punctuation.tcl + + + patterns + + + include + #braced__1 + + + end + (\}([^\s\]]*)) + endCaptures + + 1 + + name + punctuation.tcl + + + + + + braced__1 + + patterns + + + match + (\\(?:\d{1,3}|x[a-fA-F0-9]{1,2}|u[a-fA-F0-9]{1,4}|U[a-fA-F0-9]{1,8}|.)) + name + constant.character.escape.tcl + + + include + #keywords + + + match + ((?<={)\s*(?:after|append|apply|array|auto_execok|auto_import|auto_load|auto_mkindex|auto_qualify|auto_reset|bgerror|binary|break|catch|cd|chan|clock|close|concat|continue|coroutine|dde|dict|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|fileevent|file|flush|foreach|for|format|gets|global|glob|history|http|if|incr|info|interp|join|lappend|lassign|lindex|linsert|list|llength|lmap|load|lrange|lrepeat|lreplace|lreverse|lsearch|lset|lsort|memory|my|namespace|nextto|next|oo::class|oo::copy|oo::define|oo::objdefine|oo::object|open|package|parray|pid|pkg::create|pkg_mkIndex|platform::shell|proc|puts|pwd|read|regexp|registry|regsub|rename|return|scan|seek|self|set|socket|source|split|string|subst|switch|tailcall|tcl::prefix|tcl_endOfWord|tcl_findLibrary|tcl_startOfNextWord|tcl_startOfPreviousWord|tcl_wordBreakAfter|tcl_wordBreakBefore|tell|throw|time|trace|try|unknown|unload|unset|update|uplevel|upvar|variable|vwait|while|yieldto|yield)\s+) + name + keyword.tcl + comment + Special handling for known commands. + + + include + #braced_inner + + + include + #args + + + + braced_inner + + patterns + + + begin + (\{) + beginCaptures + + 1 + + name + punctuation.tcl + + + patterns + + + include + #braced_inner__1 + + + end + (\}) + endCaptures + + 1 + + name + punctuation.tcl + + + + + + braced_inner__1 + + patterns + + + match + (\\[\x{007b}\x{007d}]) + name + constant.character.escape.tcl + + + include + #numeric + + + include + #braced_inner + + + include + #args + + + + braced_lit + + patterns + + + match + ((?:(?<!\\){)(?:[^\x{007b}\x{007d}\n]*(?:\g<1>(?:\\{|\\}|[^\x{007b}\x{007d}])*)*)}) + name + none.tcl + comment + Handle braced literal. + + + + braced_lit_re + + patterns + + + match + ((?:(?<!\\){)(?:[^\x{007b}\x{007d}\n]*(?:\g<1>(?:\\{|\\}|[^\x{007b}\x{007d}])*)*)}) + name + string.regexp.tcl + comment + Handle braced regex pattern. + + + + command + + patterns + + + begin + (\\\s*$) + beginCaptures + + 1 + + name + constant.character.escape.tcl + + + patterns + + + include + #command__1 + + + end + ((?<!\\\s)$) + endCaptures + + 1 + + name + none.tcl + + + + + match + (^\s*#.*) + name + comment.tcl + comment + Line comments. + + + match + (\{\s*$|^\s*\}) + name + punctuation.tcl + comment + Leading/trailing curly braces. + + + match + (?<=^|{)(\s*proc\s+)(\S+\s+)((?:(?<!\\){)(?:[^\x{007b}\x{007d}\n]*(?:\g<1>(?:\\{|\\}|[^\x{007b}\x{007d}])*)*)}) + captures + + 1 + + name + keyword.tcl + + 2 + + name + entity.name.function.tcl + + 3 + + name + none.tcl + + + comment + Proc command. + + + include + #regexp + + + include + #keywords + + + match + (^\s*\S+|(?:(?<=[^\x{005c}]\[)[^\s\]]++(?!\]))) + name + keyword.tcl + comment + All other commands. (NOTE: Iro doesn't support possessive quantifiers, but the grammar does; be sure to replace the second + with ++ after regenerating!) + + + include + #args + + + + command__1 + + patterns + + + include + #keywords + + + include + #args + + + + embedded + + patterns + + + begin + ((?<!\\)\[) + beginCaptures + + 1 + + name + punctuation.tcl + + + patterns + + + include + #embedded__1 + + + end + ((?<!\\)\]) + endCaptures + + 1 + + name + punctuation.tcl + + + + + + embedded__1 + + patterns + + + include + #command + + + + keywords + + patterns + + + match + ((?<=^|[\[\x{007b}\x{003b}])\s*(break|catch|continue|default|error|exit|foreach|for|if|return|switch|throw|try|while)\b) + name + keyword.control.tcl + comment + Keywords. + + + match + ((?<=^|})\s*(then|elseif|else)\b) + name + keyword.control.tcl + comment + Inline keywords. + + + + numeric + + patterns + + + match + ((?:\b|[\+\-\.])(?:0b[01]+|0o[0-7]+|0x[0-9a-fA-F]+|(?:\d*\.\d+(?:[Ee][-\x{002b}]?\d+)?)|(?:\d+\.?[Ee][-\x{002b}]?\d+)|\d+|[Ii][Nn][Ff]|[Nn][Aa][Nn])\b) + name + constant.numeric.tcl + + + + quoted + + patterns + + + begin + ((?<!\\)") + beginCaptures + + 1 + + name + string.tcl + + + patterns + + + include + #quoted__1 + + + end + (") + endCaptures + + 1 + + name + string.tcl + + + + + + quoted__1 + + patterns + + + include + #quoted_args + + + match + ([^\x{0024}\x{005b}\x{0022}\x{005c}]+) + name + string.tcl + + + + quoted_args + + patterns + + + include + #braced + + + include + #quoted + + + include + #embedded + + + match + (\\(?:\d{1,3}|x[a-fA-F0-9]{1,2}|u[a-fA-F0-9]{1,4}|U[a-fA-F0-9]{1,8}|.)) + name + constant.character.escape.tcl + + + include + #variable + + + + regexp + + patterns + + + begin + ((?<=^|[\[\x{007b}\x{003b}])\s*(?:regexp|regsub)\s+)((?:(?:(?:-about|-all|-expanded|-indices|-inline|-lineanchor|-linestop|-line|-nocase|(?:-index\s+(?:end|\d+)(?:[\+\-]-?\d+)?))\s+)*(?:--\s+)?)?) + beginCaptures + + 1 + + name + keyword.tcl + + 2 + + name + none.tcl + + + patterns + + + include + #regexp__1 + + + end + (\s+) + endCaptures + + 1 + + name + none.tcl + + + + + include + #args + + + + regexp__1 + + patterns + + + include + #braced_lit_re + + + begin + ((?:(?<!\\)")) + beginCaptures + + 1 + + name + string.regexp.tcl + + + patterns + + + include + #regexp__2 + + + end + ((?:(?<!\\)")) + endCaptures + + 1 + + name + string.regexp.tcl + + + + + include + #variable + + + match + (\S+) + name + string.regexp.tcl + comment + Handle bare regex pattern. + + + + regexp__2 + + patterns + + + include + #braced_lit_re + + + include + #embedded + + + include + #variable + + + match + (\\"|[^\x{0022}]) + name + string.regexp.tcl + comment + All other quoted text. + + + + variable + + patterns + + + match + (\$(?:(?:[a-zA-Z0-9_]|::)+(?:\([^\)]+\))?|\{(?:[^\}]*|[^\}\x{0028}]+\([^\}\x{0029}]+\))\})) + name + variable.tcl + + + + word_lit__1 + + patterns + + + include + #braced_lit + + + include + #embedded + + + include + #variable + + + match + (\\"|[^\x{0022}]) + name + string.tcl + comment + All other quoted text. + + + + + + \ No newline at end of file diff --git a/test/file.cdl b/test/file.cdl index 9660e9a..da7e3d1 100644 --- a/test/file.cdl +++ b/test/file.cdl @@ -282,11 +282,11 @@ EVENT lib_event_cycle_60 { # - #Engraving - CYCLE60 - #CYCLE60(STRING[200] _TEXT, REAL _RTP, REAL _RFP, REAL _SDIS, REAL _DP, REAL _DPR, REAL _PA, REAL _PO, REAL _STA, REAL _CP1, REAL _CP2,REAL _WID, REAL _DF, REAL _FFD, REAL _FFP1, INT _VARI, INT _CODEP,INT _UMODE, INT _GMODE, INT _DMODE, INT _AMODE) + # Engraving - CYCLE60 + # CYCLE60(STRING[200] _TEXT, REAL _RTP, REAL _RFP, REAL _SDIS, REAL _DP, REAL _DPR, REAL _PA, REAL _PO, REAL _STA, REAL _CP1, REAL _CP2,REAL _WID, REAL _DF, REAL _FFD, REAL _FFP1, INT _VARI, INT _CODEP,INT _UMODE, INT _GMODE, INT _DMODE, INT _AMODE) # - #Gravurzyklus - CYCLE60 - #CYCLE60(STRING[200] _TEXT, REAL _RTP, REAL _RFP, REAL _SDIS, REAL _DP, REAL _DPR, REAL _PA, REAL _PO, REAL _STA, REAL _CP1, REAL _CP2,REAL _WID, REAL _DF, REAL _FFD, REAL _FFP1, INT _VARI, INT _CODEP,INT _UMODE, INT _GMODE, INT _DMODE, INT _AMODE) + # Gravurzyklus - CYCLE60 + # CYCLE60(STRING[200] _TEXT, REAL _RTP, REAL _RFP, REAL _SDIS, REAL _DP, REAL _DPR, REAL _PA, REAL _PO, REAL _STA, REAL _CP1, REAL _CP2,REAL _WID, REAL _DF, REAL _FFD, REAL _FFP1, INT _VARI, INT _CODEP,INT _UMODE, INT _GMODE, INT _DMODE, INT _AMODE) UI_LABEL "SAMSON: Gravieren (CYCLE60)" UI_HELP "Detailierte Zyklus Beschrieb" "file://${POST_LIB_CURRENT_BMP_DIR}/CYCL60_DE.pdf" @@ -364,18 +364,18 @@ EVENT lib_event_cycle_60 UI_LABEL "Zeichenabstand, Breite, Winkel _DF" } - # # - # # Text direction - # # - # # Textrichtung - # - # PARAM cycle60_engraving_text_direction - # { - # TYPE o - # DEFVAL "1-Normal" - # OPTIONS "0-Spiegel","1-Normal" - # UI_LABEL "Text direction" - # } + # # + # # Text direction + # # + # # Textrichtung + # + # PARAM cycle60_engraving_text_direction + # { + # TYPE o + # DEFVAL "1-Normal" + # OPTIONS "0-Spiegel","1-Normal" + # UI_LABEL "Text direction" + # } # # Text orientation diff --git a/test/test.tcl b/test/test.tcl new file mode 100644 index 0000000..0163f2d --- /dev/null +++ b/test/test.tcl @@ -0,0 +1,3 @@ +proc myProc {arg {opt 1}} { + +} \ No newline at end of file