├── .gitignore ├── .vscode └── launch.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── icons └── talon_border_small.bmp ├── images └── example.png ├── language-configuration.json ├── package-lock.json ├── package.json ├── samples ├── grab_bag.talon └── multi_line.talon └── syntaxes ├── talon-markdown-injection.json ├── talon.tmLanguage.json └── talon.tmLanguage.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "args": [ 9 | "--extensionDevelopmentPath=${workspaceFolder}" 10 | ] 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | ./samples/** 4 | .gitignore 5 | vsc-extension-quickstart.md 6 | get_ico.ps1 7 | icons/talon.bmp 8 | icons/talon.png 9 | icons/talon.svg 10 | icons/talon_big.png 11 | icons/talon_border.bmp 12 | icons/talon_small.png 13 | publish.txt 14 | test.talon 15 | TODO.md 16 | *.vsix 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "vscode-talonscript" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2020 Mike Roberts 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | json: 3 | # cargo install yj 4 | cat syntaxes/talon.tmLanguage.yml | yj > syntaxes/talon.tmLanguage.json 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TalonFile VS code syntax highlighting extension 2 | 3 | Syntax highlighting for `.talon` voice coding command grammar files. 4 | 5 | [Visual Studio Code Marketplace](https://marketplace.visualstudio.com/items?itemName=mrob95.vscode-talonscript) 6 | 7 | [Open VSX Registry](https://open-vsx.org/extension/mrob95/vscode-talonscript) 8 | 9 | ![Example](images/example.png) 10 | -------------------------------------------------------------------------------- /icons/talon_border_small.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirober/vscode-TalonScript/96978ded90b6983064765e7dc565db5ca6ffcc99/icons/talon_border_small.bmp -------------------------------------------------------------------------------- /images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirober/vscode-TalonScript/96978ded90b6983064765e7dc565db5ca6ffcc99/images/example.png -------------------------------------------------------------------------------- /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 | }, 6 | // symbols used as brackets 7 | "brackets": [ 8 | ["{", "}"], 9 | ["[", "]"], 10 | ["(", ")"] 11 | ], 12 | // symbols that are auto closed when typing 13 | "autoClosingPairs": [ 14 | ["{", "}"], 15 | ["[", "]"], 16 | ["(", ")"], 17 | ["\"", "\""], 18 | ["'", "'"] 19 | ], 20 | // symbols that that can be used to surround a selection 21 | "surroundingPairs": [ 22 | ["{", "}"], 23 | ["[", "]"], 24 | ["(", ")"], 25 | ["\"", "\""], 26 | ["'", "'"] 27 | ], 28 | "indentationRules": { 29 | "increaseIndentPattern": "^.+?:\\s*$", 30 | "decreaseIndentPattern": "^\\s+.+?:\\s*$" 31 | } 32 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-talonscript", 3 | "version": "0.3.24", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "vscode-talonscript", 9 | "version": "0.3.24", 10 | "engines": { 11 | "vscode": "^1.2.0" 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-talonscript", 3 | "publisher": "mrob95", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/mrob95/vscode-TalonScript" 7 | }, 8 | "bugs": { 9 | "url": "https://github.com/mrob95/vscode-TalonScript/issues" 10 | }, 11 | "displayName": "TalonFile syntax highlighting", 12 | "description": "Syntax highlighting for .talon files.", 13 | "version": "0.3.24", 14 | "engines": { 15 | "vscode": "^1.2.0" 16 | }, 17 | "categories": [ 18 | "Programming Languages" 19 | ], 20 | "contributes": { 21 | "languages": [ 22 | { 23 | "id": "talon", 24 | "aliases": [ 25 | "TalonScript", 26 | "talon" 27 | ], 28 | "extensions": [ 29 | ".talon" 30 | ], 31 | "icon": { 32 | "light": "./icons/talon_border_small.bmp", 33 | "dark": "./icons/talon_border_small.bmp" 34 | }, 35 | "configuration": "./language-configuration.json" 36 | }, 37 | { 38 | "id": "talon-list", 39 | "aliases": [ 40 | "Talon List" 41 | ], 42 | "extensions": [ 43 | ".talon-list" 44 | ], 45 | "icon": { 46 | "light": "./icons/talon_border_small.bmp", 47 | "dark": "./icons/talon_border_small.bmp" 48 | }, 49 | "configuration": "./language-configuration.json" 50 | }, 51 | { 52 | "id": "talon-markdown-injection" 53 | } 54 | ], 55 | "grammars": [ 56 | { 57 | "language": "talon", 58 | "scopeName": "source.talon", 59 | "path": "./syntaxes/talon.tmLanguage.json" 60 | }, 61 | { 62 | "language": "talon-list", 63 | "scopeName": "source.talon", 64 | "path": "./syntaxes/talon.tmLanguage.json" 65 | }, 66 | { 67 | "language": "talon-markdown-injection", 68 | "scopeName": "markdown.talon.codeblock", 69 | "path": "./syntaxes/talon-markdown-injection.json", 70 | "injectTo": [ 71 | "text.html.markdown" 72 | ], 73 | "embeddedLanguages": { 74 | "meta.embedded.block.talon": "talon" 75 | } 76 | } 77 | ] 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /samples/grab_bag.talon: -------------------------------------------------------------------------------- 1 | os: windows 2 | tag: terminal 3 | app: /.*/ 4 | and title: /[A-Z]*\.md.*.*$/ #comment 5 | # app: Notepad #comment 6 | app: notepad.exe 7 | and title: /^user - .*\.py$/ 8 | - 9 | command: "command" 10 | key(enter): "key" 11 | gamepad(north): "gamepad" 12 | face(smile): "face" 13 | face(smile:stop): "face" 14 | face(smile:start): "face" 15 | parrot(pop): "parrot" 16 | parrot(pop:repeat): "parrot" 17 | deck(stuff): "deck" 18 | deck(button_1): "test" 19 | deck(button_2): "test" 20 | deck(pedal_left):"test" 21 | deck(pedal_middle): "test" 22 | deck(pedal_right): "test" 23 | deck(dial_1): "test 24 | deck(dial_2): "test 25 | deck(dial_1:change): print(value) 26 | deck(touch): print("{x} {y}") 27 | key(ctrl-t:down):key(ctrl-t:down) 28 | key(ctrl-/:down):key(ctrl-t:down) 29 | key(ctrl-::down):key(ctrl-t:down) 30 | key(ctrl-):down):key(ctrl-):down) 31 | key(ctrl-):down): key(ctrl-):down) 32 | key(ctrl-):down): 33 | key(ctrl-):down) 34 | key(ctrl-):down): "test" 35 | key(ctrl--): "test" 36 | key(-): "test" 37 | 38 | gamepad(left_xy:repeat): 39 | x = x * 20 40 | y = y * -60 41 | mouse_scroll(y, x) 42 | 43 | gamepad(north): key(cmd-`) 44 | gamepad(south): key(cmd-tab) 45 | 46 | gamepad(r1:down): mouse_drag(0) 47 | gamepad(r1:up): mouse_release(0) 48 | 49 | gamepad(l1:down): mouse_drag(1) 50 | gamepad(l1:up): mouse_release(1) 51 | 52 | gamepad(right_xy:repeat): 53 | mx = mouse_x() 54 | my = mouse_y() 55 | x = x * 25 56 | y = y * 25 57 | mouse_move(mx + x, my - y) 58 | 59 | # test 60 | 5 o'clock: "test" # test 61 | 5 o'clock: # test 62 | "test" # test 63 | 5 o'clock: "test:" 64 | a: "b" 65 | A: "b" 66 | A (o'clock | | {list}): "b" 67 | with open {user.py_fopen_modes}+: 68 | (with open {user.py_fopen_modes}+ | A): 69 | modes = user.cat(print(py_fopen_modes_list)) #Test 70 | modes = user.cat(print(py_fopen_modes_lister)) #Test 71 | modes = user.cat(print(py_fopen_modes_55)) #Test 72 | modes = "{user.cat(print(py_fopen_modes_55))}" #Test 73 | modes = "{py_fopen_modes_lister}" #Test 74 | modes = py_fopen_modes_list 75 | modes = py_fopen_modes_55 76 | modes = py_fopen_modes_55_6 77 | modes = 5 + 5 78 | modes = "Test" + "Test" 79 | 5+5 80 | modes = """ Test # t""" 81 | insert(py_fopen_modes_list) 82 | user.cat(print(py_fopen_modes_list)) #Test 83 | tag(): user.terminal 84 | test action: user.clip_replace("\\\\t", "/") 85 | test action: user.clip_replace("\\\\", "/") 86 | key(ctrl-t): user.clip_replace("\\\\", "/") 87 | insert horizontal rule: "---" 88 | insert in-line code: 89 | "``" 90 | # insert code block: 91 | "``````" 92 | insert("``````") 93 | settings(): 94 | key_wait = 1.0 95 | test action: key(ctrl--:3) 96 | insert heading: "# " + " " 97 | insert testing: 98 | key(t) 99 | "testing 100 | testing" 101 | 102 | insert heading: "# " + "t " 103 | insert subheading: "## " 104 | insert subheading: "## \"\"\"" 105 | insert image: 106 | "![]()" 107 | key(left left left:2) 108 | key("left left left:2") 109 | key("left left left:{test}") 110 | insert sub sub heading: "### {test}" #comment 111 | insert sub sub heading: "##" 112 | 113 | ^commenter $: insert(user.formatted_text(phrase or "t", 2, 2, 2)) 114 | "# " 115 | insert(user.formatted_text(phrase or "t", 2, 2, 2)) 116 | user.formatted_text(2, 2) 117 | user.formatted_text(phrase or "", 2, 2, 2) 118 | insert(test) 119 | 120 | 121 | # {test.test or 5i}" #comment 122 | insert subheading: '# \'\'' 123 | <0> {test.testing} insert sub sub : "### {{test}}" #comment 124 | <0> {test.testing} insert sub sub : "### {test}" #comment 125 | insert reference: #comment 126 | "0\"s" = "0" or 0 #comment 127 | "0\"s" = "0" + 0 #comment 128 | user.test_action(n20) 129 | n20 = 0 or 1 130 | n20 = n20n 131 | "[@] = t" #comment 132 | test() 133 | key(left:down) 134 | key(left:5) 135 | key("ctrl-left:{test}") 136 | key("ctrl-left:5i") 137 | key('left:up') 138 | "{{t}} {t}" 139 | "__" 140 | key(left) 141 | key(ctrl-left): 142 | "test" 143 | action(test.test): "test" 144 | insert bold text: 145 | "labs(x = \"\",\ny = \"\",\ntitle = \"\",\nsu{test}btitle = \"\",\nca\\tption = \"\")" 146 | "****" 147 | insert("test" or 5) 148 | key(left left) 149 | settings(): 150 | a = b 151 | b = 2.0 152 | #comment 153 | #comme 154 | action(user.line_down): key("down") 155 | mod down: ":down " 156 | 157 | action class: 158 | insert('''@mod.action_class 159 | class Actions:''', "test", 5, 160 | 3) 161 | insert(user.formatted_text(phrase, 162 | capitalisation or 0, 163 | spacing or 0)) 164 | 165 | '''@mod.action_class 166 | class Actions:''' 167 | context and module: 168 | """mod = Module() 169 | test 170 | ctx = Context()""" 171 | action class: 172 | 173 | """@mod.action_class 174 | class Actions:""" 175 | -------------------------------------------------------------------------------- /samples/multi_line.talon: -------------------------------------------------------------------------------- 1 | 2 | # Example from the talon wiki https://talon.wiki/Customization/talon-files 3 | # Comments must be on their own line (optionally preceeded by whitespace) 4 | some [] command: 5 | # or operator is used to deal with optional or alternative command parts. It works as the null 6 | # coalescing operator, not like boolean or. 7 | letter_defaulted = letter or "default" 8 | 9 | """ 10 | type in this 11 | multiline 12 | string using auto_insert() 13 | """ 14 | 15 | # Local variable assignment 16 | a = 2.2 17 | b = "foo" 18 | c = "interpolate the {letter_defaulted} and {b} variables into the string" 19 | c = """ 20 | multiline string 21 | """ 22 | # Only a single mathematical operation per line 23 | d = 2 24 | a = a + d 25 | a = a - d 26 | a = a * d 27 | a = a / d 28 | a = a % d 29 | 30 | # Sleep is a built in function and takes arguments of the (|) form. 31 | # Float allows specifying (fractions) of a second. The form can be '1m', '5s', '500ms', '1000000us' etc. 32 | # Be aware sleeping in this way will prevent Talon from processing voice commands until the 33 | # sleep is over 34 | sleep(2s) 35 | 36 | # Repeats the previous line the given number of times, so in this case we'd sleep for a further 4 seconds 37 | repeat(2) 38 | 39 | # The key() action. Allows pressing, holding, and repeating individual key presses. 40 | # See the "key() action" wiki page for more details 41 | key(ctrl-f) 42 | 43 | insert("type in this literal string") 44 | auto_insert("process this string with the auto_format action, then type it in with insert()") 45 | 46 | # Stylistically we only recommend the following shorthand if it is the only action being 47 | # performed by the command. 48 | "type in this string using auto_insert()" 49 | 50 | 51 | # Call built in or user defined actions 52 | app.notify("show this in a notification balloon") 53 | user.grid_activate() 54 | -------------------------------------------------------------------------------- /syntaxes/talon-markdown-injection.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": [], 3 | "injectionSelector": "L:text.html.markdown", 4 | "patterns": [ 5 | { 6 | "include": "#talon-code-block" 7 | } 8 | ], 9 | "repository": { 10 | "talon-code-block": { 11 | "begin": "(^|\\G)(\\s*)(\\`{3,}|~{3,})\\s*(?i:(talon)(\\s+[^`~]*)?$)", 12 | "name": "markup.fenced_code.block.markdown", 13 | "end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$", 14 | "beginCaptures": { 15 | "3": { 16 | "name": "punctuation.definition.markdown" 17 | }, 18 | "4": { 19 | "name": "fenced_code.block.language.markdown" 20 | }, 21 | "5": { 22 | "name": "fenced_code.block.language.attributes.markdown" 23 | } 24 | }, 25 | "endCaptures": { 26 | "3": { 27 | "name": "punctuation.definition.markdown" 28 | } 29 | }, 30 | "patterns": [ 31 | { 32 | "begin": "(^|\\G)(\\s*)(.*)", 33 | "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)", 34 | "contentName": "meta.embedded.block.talon", 35 | "patterns": [ 36 | { 37 | "include": "source.talon" 38 | } 39 | ] 40 | } 41 | ] 42 | } 43 | }, 44 | "scopeName": "markdown.talon.codeblock" 45 | } 46 | -------------------------------------------------------------------------------- /syntaxes/talon.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TalonScript", 3 | "scopeName": "source.talon", 4 | "patterns": [ 5 | { 6 | "include": "#body-header" 7 | }, 8 | { 9 | "include": "#header" 10 | }, 11 | { 12 | "include": "#body-noheader" 13 | }, 14 | { 15 | "include": "#comment" 16 | }, 17 | { 18 | "include": "#settings" 19 | } 20 | ], 21 | "repository": { 22 | "header": { 23 | "begin": "(?=^app:|title:|os:|tag:|list:|language:)", 24 | "end": "(?=^-$)", 25 | "patterns": [ 26 | { 27 | "include": "#comment" 28 | }, 29 | { 30 | "include": "#context" 31 | } 32 | ] 33 | }, 34 | "context": { 35 | "match": "(.*): (.*)", 36 | "captures": { 37 | "1": { 38 | "name": "entity.name.tag.talon", 39 | "patterns": [ 40 | { 41 | "match": "(and |or )", 42 | "name": "keyword.operator.talon" 43 | } 44 | ] 45 | }, 46 | "2": { 47 | "name": "entity.name.type.talon", 48 | "patterns": [ 49 | { 50 | "include": "#comment" 51 | }, 52 | { 53 | "include": "#comment-invalid" 54 | }, 55 | { 56 | "include": "#regexp" 57 | } 58 | ] 59 | } 60 | } 61 | }, 62 | "regexp": { 63 | "begin": "(/)", 64 | "end": "(/)", 65 | "name": "string.regexp.talon", 66 | "patterns": [ 67 | { 68 | "match": "\\.", 69 | "name": "support.other.match.any.regexp" 70 | }, 71 | { 72 | "match": "\\$", 73 | "name": "support.other.match.end.regexp" 74 | }, 75 | { 76 | "match": "\\^", 77 | "name": "support.other.match.begin.regexp" 78 | }, 79 | { 80 | "match": "\\\\\\.|\\\\\\*|\\\\\\^|\\\\\\$|\\\\\\+|\\\\\\?", 81 | "name": "constant.character.escape.talon" 82 | }, 83 | { 84 | "match": "\\[(\\\\\\]|[^\\]])*\\]", 85 | "name": "constant.other.set.regexp" 86 | }, 87 | { 88 | "match": "\\*|\\+|\\?", 89 | "name": "keyword.operator.quantifier.regexp" 90 | } 91 | ] 92 | }, 93 | "body-header": { 94 | "begin": "^-$", 95 | "end": "(?=not)possible", 96 | "patterns": [ 97 | { 98 | "include": "#body-noheader" 99 | } 100 | ] 101 | }, 102 | "body-noheader": { 103 | "patterns": [ 104 | { 105 | "include": "#comment" 106 | }, 107 | { 108 | "include": "#comment-invalid" 109 | }, 110 | { 111 | "include": "#other-rule-definition" 112 | }, 113 | { 114 | "include": "#speech-rule-definition" 115 | } 116 | ] 117 | }, 118 | "capture": { 119 | "match": "(\\<[a-zA-Z0-9._]+\\>)", 120 | "name": "variable.parameter.talon" 121 | }, 122 | "list": { 123 | "match": "({[a-zA-Z0-9._]+?})", 124 | "name": "string.interpolated.talon" 125 | }, 126 | "comment": { 127 | "match": "^\\s*(#.*)$", 128 | "name": "comment.line.number-sign.talon" 129 | }, 130 | "comment-invalid": { 131 | "match": "(\\s*#.*)$", 132 | "name": "invalid.illegal" 133 | }, 134 | "operator": { 135 | "match": "\\s(\\+|-|\\*|/|or)\\s", 136 | "name": "keyword.operator.talon" 137 | }, 138 | "number": { 139 | "match": "(?<=\\b)\\d+(\\.\\d+)?", 140 | "name": "constant.numeric.talon" 141 | }, 142 | "varname": { 143 | "match": "([a-zA-Z0-9._])(_(list|\\d+)(?=[^a-zA-Z0-9._]))?", 144 | "name": "variable.parameter.talon", 145 | "captures": { 146 | "2": { 147 | "name": "constant.numeric.talon", 148 | "patterns": [ 149 | { 150 | "match": "_", 151 | "name": "keyword.operator.talon" 152 | } 153 | ] 154 | } 155 | } 156 | }, 157 | "fstring": { 158 | "match": "{(.+?)}", 159 | "name": "constant.character.format.placeholder.talon", 160 | "captures": { 161 | "1": { 162 | "patterns": [ 163 | { 164 | "include": "#action" 165 | }, 166 | { 167 | "include": "#operator" 168 | }, 169 | { 170 | "include": "#number" 171 | }, 172 | { 173 | "include": "#varname" 174 | }, 175 | { 176 | "include": "#qstring" 177 | } 178 | ] 179 | } 180 | } 181 | }, 182 | "string-body": { 183 | "patterns": [ 184 | { 185 | "match": "{{|}}", 186 | "name": "string.quoted.double.talon" 187 | }, 188 | { 189 | "match": "\\\\\\\\|\\\\n|\\\\t|\\\\r|\\\\\"|\\\\'", 190 | "name": "constant.character.escape.python" 191 | }, 192 | { 193 | "include": "#fstring" 194 | } 195 | ] 196 | }, 197 | "qstring": { 198 | "begin": "(\"|')", 199 | "end": "(\\1)|$", 200 | "name": "string.quoted.double.talon", 201 | "beginCaptures": { 202 | "1": { 203 | "name": "punctuation.definition.string.begin.talon" 204 | } 205 | }, 206 | "endCaptures": { 207 | "1": { 208 | "name": "punctuation.definition.string.end.talon" 209 | } 210 | }, 211 | "patterns": [ 212 | { 213 | "include": "#string-body" 214 | } 215 | ] 216 | }, 217 | "keystring": { 218 | "begin": "(\"|')", 219 | "end": "(\\1)|$", 220 | "name": "string.quoted.double.talon", 221 | "beginCaptures": { 222 | "1": { 223 | "name": "punctuation.definition.string.begin.talon" 224 | } 225 | }, 226 | "endCaptures": { 227 | "1": { 228 | "name": "punctuation.definition.string.end.talon" 229 | } 230 | }, 231 | "patterns": [ 232 | { 233 | "include": "#string-body" 234 | }, 235 | { 236 | "include": "#key-mods" 237 | }, 238 | { 239 | "include": "#key-prefixes" 240 | } 241 | ] 242 | }, 243 | "qstring-long": { 244 | "begin": "(\"\"\"|''')", 245 | "end": "(\\1)", 246 | "name": "string.quoted.triple.talon", 247 | "beginCaptures": { 248 | "1": { 249 | "name": "punctuation.definition.string.begin.talon" 250 | } 251 | }, 252 | "endCaptures": { 253 | "1": { 254 | "name": "punctuation.definition.string.end.talon" 255 | } 256 | }, 257 | "patterns": [ 258 | { 259 | "include": "#string-body" 260 | } 261 | ] 262 | }, 263 | "action-key": { 264 | "match": "key(\\()(.*)(\\))", 265 | "name": "entity.name.function.talon", 266 | "captures": { 267 | "1": { 268 | "name": "punctuation.definition.parameters.begin.talon" 269 | }, 270 | "2": { 271 | "name": "variable.parameter.talon", 272 | "patterns": [ 273 | { 274 | "include": "#key-prefixes" 275 | }, 276 | { 277 | "include": "#key-mods" 278 | }, 279 | { 280 | "include": "#keystring" 281 | } 282 | ] 283 | }, 284 | "3": { 285 | "name": "punctuation.definition.parameters.key.talon" 286 | } 287 | } 288 | }, 289 | "key-prefixes": { 290 | "match": "(ctrl|shift|cmd|alt|win|super)(-)", 291 | "captures": { 292 | "1": { 293 | "name": "keyword.control.talon" 294 | }, 295 | "2": { 296 | "name": "keyword.operator.talon" 297 | } 298 | } 299 | }, 300 | "key-mods": { 301 | "match": "(:)(up|down|change|repeat|start|stop|\\d+)", 302 | "captures": { 303 | "1": { 304 | "name": "keyword.operator.talon" 305 | }, 306 | "2": { 307 | "name": "keyword.control.talon" 308 | } 309 | }, 310 | "name": "keyword.operator.talon" 311 | }, 312 | "action-gamepad": { 313 | "match": "(deck|gamepad|action|face|parrot)(\\()(.*)(\\))", 314 | "name": "entity.name.function.talon", 315 | "captures": { 316 | "2": { 317 | "name": "punctuation.definition.parameters.begin.talon" 318 | }, 319 | "3": { 320 | "name": "variable.parameter.talon", 321 | "patterns": [ 322 | { 323 | "include": "#key-mods" 324 | } 325 | ] 326 | }, 327 | "4": { 328 | "name": "punctuation.definition.parameters.key.talon" 329 | } 330 | } 331 | }, 332 | "argsep": { 333 | "match": ",", 334 | "name": "punctuation.separator.talon" 335 | }, 336 | "action": { 337 | "begin": "([a-zA-Z0-9._]+)(\\()", 338 | "end": "(\\))", 339 | "beginCaptures": { 340 | "1": { 341 | "name": "entity.name.function.talon", 342 | "patterns": [ 343 | { 344 | "match": "\\.", 345 | "name": "punctuation.separator.talon" 346 | } 347 | ] 348 | }, 349 | "2": { 350 | "name": "punctuation.definition.parameters.begin.talon" 351 | } 352 | }, 353 | "endCaptures": { 354 | "1": { 355 | "name": "punctuation.definition.parameters.end.talon" 356 | } 357 | }, 358 | "patterns": [ 359 | { 360 | "include": "#action" 361 | }, 362 | { 363 | "include": "#qstring-long" 364 | }, 365 | { 366 | "include": "#qstring" 367 | }, 368 | { 369 | "include": "#argsep" 370 | }, 371 | { 372 | "include": "#number" 373 | }, 374 | { 375 | "include": "#operator" 376 | }, 377 | { 378 | "include": "#varname" 379 | } 380 | ], 381 | "name": "variable.parameter.talon" 382 | }, 383 | "speech-rule-definition": { 384 | "begin": "^(.*?):", 385 | "end": "(?=^[^\\s#])", 386 | "beginCaptures": { 387 | "1": { 388 | "name": "entity.name.tag.talon", 389 | "patterns": [ 390 | { 391 | "match": "^\\^", 392 | "name": "string.regexp.talon" 393 | }, 394 | { 395 | "match": "\\$$", 396 | "name": "string.regexp.talon" 397 | }, 398 | { 399 | "match": "\\(", 400 | "name": "punctuation.definition.parameters.begin.talon" 401 | }, 402 | { 403 | "match": "\\)", 404 | "name": "punctuation.definition.parameters.end.talon" 405 | }, 406 | { 407 | "match": "\\|", 408 | "name": "punctuation.separator.talon" 409 | }, 410 | { 411 | "include": "#capture" 412 | }, 413 | { 414 | "include": "#list" 415 | } 416 | ] 417 | } 418 | }, 419 | "patterns": [ 420 | { 421 | "include": "#statement" 422 | } 423 | ] 424 | }, 425 | "other-rule-definition": { 426 | "begin": "^([a-z]+\\(.*[^\\-]\\)|[a-z]+\\(.*--\\)|[a-z]+\\(-\\)|[a-z]+\\(\\)):", 427 | "end": "(?=^[^\\s#])", 428 | "beginCaptures": { 429 | "1": { 430 | "name": "entity.name.tag.talon", 431 | "patterns": [ 432 | { 433 | "include": "#action-key" 434 | }, 435 | { 436 | "include": "#action-gamepad" 437 | }, 438 | { 439 | "include": "#rule-specials" 440 | } 441 | ] 442 | } 443 | }, 444 | "patterns": [ 445 | { 446 | "include": "#statement" 447 | } 448 | ] 449 | }, 450 | "rule-specials": { 451 | "match": "(settings|tag)(\\()(\\))", 452 | "captures": { 453 | "1": { 454 | "name": "entity.name.function.talon" 455 | }, 456 | "2": { 457 | "name": "punctuation.definition.parameters.begin.talon" 458 | }, 459 | "3": { 460 | "name": "punctuation.definition.parameters.end.talon" 461 | } 462 | } 463 | }, 464 | "assignment": { 465 | "begin": "(\\S*)(\\s?=\\s?)", 466 | "end": "\n", 467 | "beginCaptures": { 468 | "1": { 469 | "name": "variable.other.talon" 470 | }, 471 | "2": { 472 | "name": "keyword.operator.talon" 473 | } 474 | }, 475 | "patterns": [ 476 | { 477 | "include": "#comment" 478 | }, 479 | { 480 | "include": "#comment-invalid" 481 | }, 482 | { 483 | "include": "#expression" 484 | } 485 | ] 486 | }, 487 | "expression": { 488 | "patterns": [ 489 | { 490 | "include": "#qstring-long" 491 | }, 492 | { 493 | "include": "#action-key" 494 | }, 495 | { 496 | "include": "#action" 497 | }, 498 | { 499 | "include": "#operator" 500 | }, 501 | { 502 | "include": "#number" 503 | }, 504 | { 505 | "include": "#qstring" 506 | }, 507 | { 508 | "include": "#varname" 509 | } 510 | ] 511 | }, 512 | "statement": { 513 | "patterns": [ 514 | { 515 | "include": "#comment" 516 | }, 517 | { 518 | "include": "#comment-invalid" 519 | }, 520 | { 521 | "include": "#qstring-long" 522 | }, 523 | { 524 | "include": "#action-key" 525 | }, 526 | { 527 | "include": "#action" 528 | }, 529 | { 530 | "include": "#qstring" 531 | }, 532 | { 533 | "include": "#assignment" 534 | } 535 | ] 536 | } 537 | } 538 | } 539 | -------------------------------------------------------------------------------- /syntaxes/talon.tmLanguage.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: TalonScript 3 | scopeName: source.talon 4 | patterns: 5 | - include: "#body-header" 6 | - include: "#header" 7 | - include: "#body-noheader" 8 | - include: "#comment" 9 | - include: "#settings" 10 | repository: 11 | header: 12 | begin: (?=^app:|title:|os:|tag:|list:|language:) 13 | end: (?=^-$) 14 | patterns: 15 | - include: "#comment" 16 | - include: "#context" 17 | context: 18 | match: "(.*): (.*)" 19 | captures: 20 | "1": 21 | name: entity.name.tag.talon 22 | patterns: 23 | - match: (and |or ) 24 | name: keyword.operator.talon 25 | "2": 26 | name: entity.name.type.talon 27 | patterns: 28 | - include: "#comment" 29 | - include: "#comment-invalid" 30 | - include: "#regexp" 31 | regexp: 32 | begin: (/) 33 | end: (/) 34 | name: string.regexp.talon 35 | patterns: 36 | - match: \. 37 | name: support.other.match.any.regexp 38 | - match: \$ 39 | name: support.other.match.end.regexp 40 | - match: \^ 41 | name: support.other.match.begin.regexp 42 | - match: \\\.|\\\*|\\\^|\\\$|\\\+|\\\? 43 | name: constant.character.escape.talon 44 | - match: \[(\\\]|[^\]])*\] 45 | name: constant.other.set.regexp 46 | - match: \*|\+|\? 47 | name: keyword.operator.quantifier.regexp 48 | body-header: 49 | begin: ^-$ 50 | end: (?=not)possible 51 | patterns: 52 | - include: "#body-noheader" 53 | body-noheader: 54 | patterns: 55 | - include: "#comment" 56 | - include: "#comment-invalid" 57 | - include: "#other-rule-definition" 58 | - include: "#speech-rule-definition" 59 | # ------------------------------------------------ 60 | capture: 61 | match: (\<[a-zA-Z0-9._]+\>) 62 | name: variable.parameter.talon 63 | list: 64 | match: ({[a-zA-Z0-9._]+?}) 65 | name: string.interpolated.talon 66 | comment: 67 | match: ^\s*(#.*)$ 68 | name: comment.line.number-sign.talon 69 | comment-invalid: 70 | match: (\s*#.*)$ 71 | name: invalid.illegal 72 | operator: 73 | match: \s(\+|-|\*|/|or)\s 74 | name: keyword.operator.talon 75 | number: 76 | match: (?<=\b)\d+(\.\d+)? 77 | # (?=$|\s) 78 | name: constant.numeric.talon 79 | varname: 80 | match: ([a-zA-Z0-9._])(_(list|\d+)(?=[^a-zA-Z0-9._]))? 81 | name: variable.parameter.talon 82 | captures: 83 | "2": 84 | name: constant.numeric.talon 85 | patterns: 86 | - match: _ 87 | name: keyword.operator.talon 88 | # STRINGS ------------------------------------------------ 89 | fstring: 90 | match: "{(.+?)}" 91 | name: constant.character.format.placeholder.talon 92 | captures: 93 | "1": 94 | patterns: 95 | - include: "#action" 96 | - include: "#operator" 97 | - include: "#number" 98 | - include: "#varname" 99 | - include: "#qstring" 100 | string-body: 101 | patterns: 102 | - match: "{{|}}" 103 | name: string.quoted.double.talon 104 | - match: \\\\|\\n|\\t|\\r|\\"|\\' 105 | name: constant.character.escape.python 106 | - include: "#fstring" 107 | qstring: 108 | begin: ("|') 109 | end: (\1)|$ 110 | name: string.quoted.double.talon 111 | beginCaptures: 112 | "1": 113 | name: punctuation.definition.string.begin.talon 114 | endCaptures: 115 | "1": 116 | name: punctuation.definition.string.end.talon 117 | patterns: 118 | - include: "#string-body" 119 | # Same as above, but includes key stuff 120 | keystring: 121 | begin: ("|') 122 | end: (\1)|$ 123 | name: string.quoted.double.talon 124 | beginCaptures: 125 | "1": 126 | name: punctuation.definition.string.begin.talon 127 | endCaptures: 128 | "1": 129 | name: punctuation.definition.string.end.talon 130 | patterns: 131 | - include: "#string-body" 132 | - include: "#key-mods" 133 | - include: "#key-prefixes" 134 | qstring-long: 135 | begin: ("""|''') 136 | end: (\1) 137 | name: string.quoted.triple.talon 138 | beginCaptures: 139 | "1": 140 | name: punctuation.definition.string.begin.talon 141 | endCaptures: 142 | "1": 143 | name: punctuation.definition.string.end.talon 144 | patterns: 145 | - include: "#string-body" 146 | # KEY ------------------------------------------------ 147 | action-key: 148 | match: key(\()(.*)(\)) 149 | name: entity.name.function.talon 150 | captures: 151 | "1": 152 | name: punctuation.definition.parameters.begin.talon 153 | "2": 154 | name: variable.parameter.talon 155 | patterns: 156 | - include: "#key-prefixes" 157 | - include: "#key-mods" 158 | - include: "#keystring" 159 | "3": 160 | name: punctuation.definition.parameters.key.talon 161 | key-prefixes: 162 | match: (ctrl|shift|cmd|alt|win|super)(-) 163 | captures: 164 | "1": 165 | name: keyword.control.talon 166 | "2": 167 | name: keyword.operator.talon 168 | key-mods: 169 | match: (:)(up|down|change|repeat|start|stop|\d+) 170 | captures: 171 | "1": 172 | name: keyword.operator.talon 173 | "2": 174 | name: keyword.control.talon 175 | name: keyword.operator.talon 176 | # GAMEPAD/DECK ------------------------------------------ 177 | action-gamepad: 178 | match: (deck|gamepad|action|face|parrot)(\()(.*)(\)) 179 | name: entity.name.function.talon 180 | captures: 181 | "2": 182 | name: punctuation.definition.parameters.begin.talon 183 | "3": 184 | name: variable.parameter.talon 185 | patterns: 186 | - include: "#key-mods" 187 | "4": 188 | name: punctuation.definition.parameters.key.talon 189 | # ACTION ------------------------------------------------ 190 | argsep: 191 | match: "," 192 | name: punctuation.separator.talon 193 | action: 194 | begin: "([a-zA-Z0-9._]+)(\\()" 195 | end: (\)) 196 | beginCaptures: 197 | "1": 198 | name: entity.name.function.talon 199 | patterns: 200 | - match: "\\." 201 | name: punctuation.separator.talon 202 | "2": 203 | name: punctuation.definition.parameters.begin.talon 204 | endCaptures: 205 | "1": 206 | name: punctuation.definition.parameters.end.talon 207 | patterns: 208 | - include: "#action" 209 | - include: "#qstring-long" 210 | - include: "#qstring" 211 | - include: "#argsep" 212 | - include: "#number" 213 | - include: "#operator" 214 | - include: "#varname" 215 | name: variable.parameter.talon 216 | # RULE ------------------------------------------------ 217 | speech-rule-definition: 218 | begin: "^(.*?):" 219 | end: (?=^[^\s#]) 220 | beginCaptures: 221 | "1": 222 | name: entity.name.tag.talon 223 | patterns: 224 | - match: ^\^ 225 | name: string.regexp.talon 226 | - match: \$$ 227 | name: string.regexp.talon 228 | - match: \( 229 | name: punctuation.definition.parameters.begin.talon 230 | - match: \) 231 | name: punctuation.definition.parameters.end.talon 232 | - match: \| 233 | name: punctuation.separator.talon 234 | - include: "#capture" 235 | - include: "#list" 236 | patterns: 237 | - include: "#statement" 238 | other-rule-definition: 239 | begin: "^([a-z]+\\(.*[^\\-]\\)|[a-z]+\\(.*--\\)|[a-z]+\\(-\\)|[a-z]+\\(\\)):" 240 | end: (?=^[^\s#]) 241 | beginCaptures: 242 | "1": 243 | name: entity.name.tag.talon 244 | patterns: 245 | - include: "#action-key" 246 | - include: "#action-gamepad" 247 | - include: "#rule-specials" 248 | patterns: 249 | - include: "#statement" 250 | rule-specials: 251 | match: (settings|tag)(\()(\)) 252 | captures: 253 | "1": 254 | name: entity.name.function.talon 255 | "2": 256 | name: punctuation.definition.parameters.begin.talon 257 | "3": 258 | name: punctuation.definition.parameters.end.talon 259 | assignment: 260 | begin: (\S*)(\s?=\s?) 261 | end: "\n" 262 | beginCaptures: 263 | "1": 264 | name: variable.other.talon 265 | "2": 266 | name: keyword.operator.talon 267 | patterns: 268 | - include: "#comment" 269 | - include: "#comment-invalid" 270 | - include: "#expression" 271 | expression: 272 | patterns: 273 | - include: "#qstring-long" 274 | - include: "#action-key" 275 | - include: "#action" 276 | - include: "#operator" 277 | - include: "#number" 278 | - include: "#qstring" 279 | - include: "#varname" 280 | statement: 281 | patterns: 282 | - include: "#comment" 283 | - include: "#comment-invalid" 284 | - include: "#qstring-long" 285 | - include: "#action-key" 286 | - include: "#action" 287 | - include: "#qstring" 288 | - include: "#assignment" 289 | --------------------------------------------------------------------------------