├── .gitignore ├── CoffeeScript.py ├── CoffeeScript.sublime-build ├── CoffeeScript.sublime-commands ├── CoffeeScript.sublime-settings ├── CoffeeScript.tmLanguage ├── CoffeeScript.tmPreferences ├── Indent.tmPreferences ├── Keymaps ├── Default (Linux).sublime-keymap ├── Default (OSX).sublime-keymap └── Default (Windows).sublime-keymap ├── LICENSE ├── README.md ├── Snippets ├── Array comprehension.tmSnippet ├── Bound Function.tmSnippet ├── Class.tmSnippet ├── Console Log.tmSnippet ├── Else if.tmSnippet ├── Else.tmSnippet ├── Function.tmSnippet ├── If Else.tmSnippet ├── If.tmSnippet ├── Interpolated Code.tmSnippet ├── Object comprehension.tmSnippet ├── Range comprehension (exclusive).tmSnippet ├── Range comprehension (inclusive).tmSnippet ├── Switch.tmSnippet ├── Ternary If.tmSnippet ├── Try Catch.tmSnippet ├── Unless.tmSnippet └── require.tmSnippet ├── Symbol List.tmPreferences ├── changelogs ├── 0.5.1.txt ├── 0.5.2.txt └── 0.5.3.txt └── messages.json /.gitignore: -------------------------------------------------------------------------------- 1 | /package-metadata.json 2 | *.pyc 3 | *.cache 4 | *.sublime-project 5 | *.sublime-workspace 6 | Test.* 7 | code 8 | spec 9 | src 10 | lib 11 | -------------------------------------------------------------------------------- /CoffeeScript.py: -------------------------------------------------------------------------------- 1 | import sublime 2 | import sys 3 | from os import path 4 | from subprocess import Popen, PIPE 5 | from sublime_plugin import TextCommand, WindowCommand 6 | 7 | settings = sublime.load_settings('CoffeeScript.sublime-settings') 8 | 9 | def run(cmd, args = [], source="", cwd = None, env = None): 10 | if not type(args) is list: 11 | args = [args] 12 | if sys.platform == "win32": 13 | proc = Popen([cmd]+args, env=env, cwd=cwd, stdout=PIPE, stdin=PIPE, stderr=PIPE, shell=True) 14 | stat = proc.communicate(input=source) 15 | else: 16 | if env is None: 17 | env = {"PATH": settings.get('binDir', '/usr/local/bin')} 18 | if source == "": 19 | command = [cmd]+args 20 | else: 21 | command = [cmd]+args+[source] 22 | proc = Popen(command, env=env, cwd=cwd, stdout=PIPE, stderr=PIPE) 23 | stat = proc.communicate() 24 | okay = proc.returncode == 0 25 | return {"okay": okay, "out": stat[0], "err": stat[1]} 26 | 27 | def brew(args, source): 28 | if sys.platform == "win32": 29 | args.append("-s") 30 | else: 31 | args.append("-e") 32 | return run("coffee", args=args, source=source) 33 | 34 | def cake(task, cwd): 35 | return run("cake", args=task, cwd=cwd) 36 | 37 | def isCoffee(view = None): 38 | if view is None: 39 | view = sublime.active_window().active_view() 40 | return 'source.coffee' in view.scope_name(0) 41 | 42 | class Text(): 43 | @staticmethod 44 | def all(view): 45 | return view.substr(sublime.Region(0, view.size())) 46 | @staticmethod 47 | def sel(view): 48 | text = [] 49 | for region in view.sel(): 50 | if region.empty(): 51 | continue 52 | text.append(view.substr(region)) 53 | return "".join(text) 54 | 55 | @staticmethod 56 | def get(view): 57 | text = Text.sel(view) 58 | if len(text) > 0: 59 | return text 60 | return Text.all(view) 61 | 62 | class CompileCommand(TextCommand): 63 | def is_enabled(self): 64 | return isCoffee(self.view) 65 | 66 | def run(self, *args, **kwargs): 67 | no_wrapper = settings.get('noWrapper', True) 68 | args = ['-c', self.view.file_name()] 69 | if no_wrapper: 70 | args = ['-b'] + args 71 | result = run("coffee", args=args) 72 | 73 | if result['okay'] is True: 74 | status = 'Compilation Succeeded' 75 | else: 76 | status = 'Compilation Failed' 77 | 78 | sublime.status_message(status) 79 | 80 | class CompileAndDisplayCommand(TextCommand): 81 | def is_enabled(self): 82 | return isCoffee(self.view) 83 | 84 | def run(self, edit, **kwargs): 85 | opt = kwargs["opt"] 86 | no_wrapper = settings.get('noWrapper', True) 87 | args = [opt] 88 | if no_wrapper: 89 | args = ['-b'] + args 90 | res = brew(args, Text.get(self.view)) 91 | output = self.view.window().new_file() 92 | output.set_scratch(True) 93 | if opt == '-p': 94 | output.set_syntax_file('Packages/JavaScript/JavaScript.tmLanguage') 95 | if res["okay"] is True: 96 | output.insert(edit, 0, res["out"]) 97 | else: 98 | output.insert(edit, 0, res["err"].split("\n")[0]) 99 | 100 | class CheckSyntaxCommand(TextCommand): 101 | def is_enabled(self): 102 | return isCoffee(self.view) 103 | 104 | def run(self, edit): 105 | res = brew(['-b', '-p'], Text.get(self.view)) 106 | if res["okay"] is True: 107 | status = 'Valid' 108 | else: 109 | status = res["err"].split("\n")[0] 110 | sublime.status_message('Syntax %s' % status) 111 | 112 | class RunScriptCommand(WindowCommand): 113 | def finish(self, text): 114 | if text == '': 115 | return 116 | text = "{puts, print} = require 'util'\n" + text 117 | res = brew(['-b'], text) 118 | if res["okay"] is True: 119 | output = self.window.new_file() 120 | output.set_scratch(True) 121 | edit = output.begin_edit() 122 | output.insert(edit, 0, res["out"]) 123 | output.end_edit(edit) 124 | else: 125 | sublime.status_message('Syntax %s' % res["err"].split("\n")[0]) 126 | 127 | def run(self): 128 | sel = Text.sel(sublime.active_window().active_view()) 129 | if len(sel) > 0: 130 | if not isCoffee(): return 131 | self.finish(sel) 132 | else: 133 | self.window.show_input_panel('Coffee >', '', self.finish, None, None) 134 | 135 | class RunCakeTaskCommand(WindowCommand): 136 | def finish(self, task): 137 | if task == '': 138 | return 139 | 140 | if not self.window.folders(): 141 | cakepath = path.dirname(self.window.active_view().file_name()) 142 | else: 143 | cakepath = path.join(self.window.folders()[0], 'Cakefile') 144 | if not path.exists(cakepath): 145 | cakepath = path.dirname(self.window.active_view().file_name()) 146 | 147 | if not path.exists(cakepath): 148 | return sublime.status_message("Cakefile not found.") 149 | 150 | res = cake(task, cakepath) 151 | if res["okay"] is True: 152 | if "No such task" in res["out"]: 153 | msg = "doesn't exist" 154 | else: 155 | msg = "suceeded" 156 | else: 157 | msg = "failed" 158 | sublime.status_message("Task %s - %s." % (task, msg)) 159 | 160 | def run(self): 161 | self.window.show_input_panel('Cake >', '', self.finish, None, None) 162 | -------------------------------------------------------------------------------- /CoffeeScript.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "cmd": ["cake", "sbuild"] 3 | , "path": "/usr/local/bin:$PATH" 4 | , "selector": "source.coffee" 5 | , "working_dir": "$project_path" 6 | , "variants": 7 | [ 8 | { 9 | "name": "Run", 10 | "cmd": ["coffee", "$file"] 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /CoffeeScript.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Coffee: Check Syntax" 4 | , "command": "check_syntax" 5 | } 6 | , { 7 | "caption": "Coffee: Run Script" 8 | , "command": "run_script" 9 | } 10 | , { 11 | "caption": "Coffee: Run Cake Task" 12 | , "command": "run_cake_task" 13 | } 14 | , { 15 | "caption": "Coffee: Compile File" 16 | , "command": "compile" 17 | } 18 | , { 19 | "caption": "Coffee: Display JavaScript" 20 | , "command": "compile_and_display", "args": {"opt": "-p"} 21 | } 22 | , { 23 | "caption": "Coffee: Display Lexer Tokens" 24 | , "command": "compile_and_display", "args": {"opt": "-t"} 25 | } 26 | , { 27 | "caption": "Coffee: Display Parse Tree" 28 | , "command": "compile_and_display", "args": {"opt": "-n"} 29 | } 30 | , { 31 | "caption": "Coffee: Toggle Watch Mode" 32 | , "command": "toggle_watch" 33 | } 34 | , { 35 | "caption": "Coffee: Toggle Output Panel" 36 | , "command": "toggle_output_panel" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /CoffeeScript.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | The directory containing your coffee binary. Usually 4 | /usr/local/bin. 5 | */ 6 | "binDir": "/usr/local/bin" 7 | 8 | /* 9 | Directories where the watcher will look for .js (lib) 10 | and .coffee (src) files. 11 | */ 12 | , "libDir": "" 13 | , "srcDir": "" 14 | 15 | /* 16 | Compile without the top-level function wrapper (coffee -b). 17 | */ 18 | 19 | , "noWrapper": true 20 | 21 | /* 22 | Globally enable/disable watch mode. 23 | */ 24 | , "watchEnabled": true 25 | 26 | /* 27 | Where output from the watcher (coffee -w) will be sent to. 28 | 29 | panel - a custom, toggleable (alt+shift+z) panel 30 | status - to the status bar 31 | console - to the python console 32 | 33 | log file? probably 34 | growl? maybe 35 | */ 36 | , "watchOutputMode": "panel" 37 | 38 | , "watchAutoStart": false 39 | 40 | /* 41 | Output success (compiled) or failure (error) messages, or both, or neither... 42 | */ 43 | , "watchOutputOnSuccess": true 44 | , "watchOutputOnFailure": true 45 | 46 | /* 47 | Watched files containing errors will have their view focused 48 | and the error highlighted, regardless of watchOutputOnFailure 49 | setting above. 50 | */ 51 | , "watchHighlightErrors": true 52 | } 53 | -------------------------------------------------------------------------------- /CoffeeScript.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | comment 6 | CoffeeScript Syntax: version 1 7 | fileTypes 8 | 9 | coffee 10 | Cakefile 11 | coffee.erb 12 | cson 13 | 14 | firstLineMatch 15 | ^#!.*\bcoffee 16 | foldingStartMarker 17 | ^\s*class\s+\S.*$|.*(->|=>)\s*$|.*[\[{]\s*$ 18 | foldingStopMarker 19 | ^\s*$|^\s*[}\]]\s*$ 20 | keyEquivalent 21 | ^~C 22 | name 23 | CoffeeScript 24 | patterns 25 | 26 | 27 | captures 28 | 29 | 1 30 | 31 | name 32 | variable.parameter.function.coffee 33 | 34 | 2 35 | 36 | name 37 | storage.type.function.coffee 38 | 39 | 40 | comment 41 | match stuff like: a -> … 42 | match 43 | (\([^()]*?\))\s*([=-]>) 44 | name 45 | meta.inline.function.coffee 46 | 47 | 48 | captures 49 | 50 | 1 51 | 52 | name 53 | keyword.operator.new.coffee 54 | 55 | 2 56 | 57 | name 58 | support.class.coffee 59 | 60 | 61 | match 62 | (new)\s+(\w+(?:\.\w*)*) 63 | name 64 | meta.class.instance.constructor 65 | 66 | 67 | begin 68 | ''' 69 | beginCaptures 70 | 71 | 0 72 | 73 | name 74 | punctuation.definition.string.begin.coffee 75 | 76 | 77 | end 78 | ''' 79 | endCaptures 80 | 81 | 0 82 | 83 | name 84 | punctuation.definition.string.end.coffee 85 | 86 | 87 | name 88 | string.quoted.heredoc.coffee 89 | 90 | 91 | begin 92 | """ 93 | beginCaptures 94 | 95 | 0 96 | 97 | name 98 | punctuation.definition.string.begin.coffee 99 | 100 | 101 | end 102 | """ 103 | endCaptures 104 | 105 | 0 106 | 107 | name 108 | punctuation.definition.string.end.coffee 109 | 110 | 111 | name 112 | string.quoted.double.heredoc.coffee 113 | patterns 114 | 115 | 116 | match 117 | \\. 118 | name 119 | constant.character.escape.coffee 120 | 121 | 122 | include 123 | #interpolated_coffee 124 | 125 | 126 | 127 | 128 | begin 129 | ` 130 | beginCaptures 131 | 132 | 0 133 | 134 | name 135 | punctuation.definition.string.begin.coffee 136 | 137 | 138 | end 139 | ` 140 | endCaptures 141 | 142 | 0 143 | 144 | name 145 | punctuation.definition.string.end.coffee 146 | 147 | 148 | name 149 | string.quoted.script.coffee 150 | patterns 151 | 152 | 153 | match 154 | \\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.) 155 | name 156 | constant.character.escape.coffee 157 | 158 | 159 | 160 | 161 | begin 162 | (?<!#)###(?!#) 163 | captures 164 | 165 | 0 166 | 167 | name 168 | punctuation.definition.comment.coffee 169 | 170 | 171 | end 172 | ###(?:[ \t]*\n) 173 | name 174 | comment.block.coffee 175 | patterns 176 | 177 | 178 | match 179 | @\w* 180 | name 181 | storage.type.annotation.coffeescript 182 | 183 | 184 | 185 | 186 | captures 187 | 188 | 1 189 | 190 | name 191 | punctuation.definition.comment.coffee 192 | 193 | 194 | match 195 | (#)(?!\{).*$\n? 196 | name 197 | comment.line.number-sign.coffee 198 | 199 | 200 | begin 201 | /{3} 202 | end 203 | /{3}[imgy]{0,4} 204 | name 205 | string.regexp.coffee 206 | patterns 207 | 208 | 209 | include 210 | #interpolated_coffee 211 | 212 | 213 | include 214 | #embedded_comment 215 | 216 | 217 | 218 | 219 | match 220 | /(?![\s=/*+{}?]).*?[^\\]/[igmy]{0,4}(?![a-zA-Z0-9]) 221 | name 222 | string.regexp.coffee 223 | 224 | 225 | match 226 | (?x) 227 | \b(?<![\.\$])( 228 | break|by|catch|continue|else|finally|for|in|of|if|return|switch| 229 | then|throw|try|unless|when|while|until|loop|do|(?<=for)\s+own 230 | )(?!\s*:)\b 231 | 232 | name 233 | keyword.control.coffee 234 | 235 | 236 | match 237 | (?x) 238 | and=|or=|!|%|&|\^|\*|\/|(\-)?\-(?!>)|\+\+|\+|~|==|=(?!>)|!=|<=|>=|<<=|>>=| 239 | >>>=|<>|<|>|!|&&|\.\.(\.)?|\?|\||\|\||\:|\*=|(?<!\()/=|%=|\+=|\-=|&=| 240 | \^=|\b(?<![\.\$])(instanceof|new|delete|typeof|and|or|is|isnt|not|super)\b 241 | 242 | name 243 | keyword.operator.coffee 244 | 245 | 246 | captures 247 | 248 | 1 249 | 250 | name 251 | variable.assignment.coffee 252 | 253 | 4 254 | 255 | name 256 | punctuation.separator.key-value 257 | 258 | 5 259 | 260 | name 261 | keyword.operator.coffee 262 | 263 | 264 | match 265 | ([a-zA-Z\$_](\w|\$|\.)*\s*(?!\::)((:)|(=[^=]))(?!(\s*\(.*\))?\s*((=|-)>))) 266 | name 267 | variable.assignment.coffee 268 | 269 | 270 | begin 271 | (?<=\s|^)([\[\{])(?=.*?[\]\}]\s+[:=]) 272 | beginCaptures 273 | 274 | 0 275 | 276 | name 277 | keyword.operator.coffee 278 | 279 | 280 | end 281 | ([\]\}]\s*[:=]) 282 | endCaptures 283 | 284 | 0 285 | 286 | name 287 | keyword.operator.coffee 288 | 289 | 290 | name 291 | meta.variable.assignment.destructured.coffee 292 | patterns 293 | 294 | 295 | include 296 | #variable_name 297 | 298 | 299 | include 300 | #instance_variable 301 | 302 | 303 | include 304 | #single_quoted_string 305 | 306 | 307 | include 308 | #double_quoted_string 309 | 310 | 311 | include 312 | #numeric 313 | 314 | 315 | 316 | 317 | captures 318 | 319 | 2 320 | 321 | name 322 | entity.name.function.coffee 323 | 324 | 3 325 | 326 | name 327 | entity.name.function.coffee 328 | 329 | 4 330 | 331 | name 332 | variable.parameter.function.coffee 333 | 334 | 5 335 | 336 | name 337 | storage.type.function.coffee 338 | 339 | 340 | match 341 | (?x) 342 | (\s*) 343 | (?=[a-zA-Z\$_]) 344 | ( 345 | [a-zA-Z\$_](\w|\$|:|\.)*\s* 346 | (?=[:=](\s*\(.*\))?\s*([=-]>)) 347 | ) 348 | 349 | name 350 | meta.function.coffee 351 | 352 | 353 | comment 354 | Show well-known functions from Express and Mocha in Go To Symbol view 355 | name 356 | meta.function.symbols.coffee 357 | begin 358 | ^\s*(describe|it|app\.(get|post|put|all|del|delete)) 359 | end 360 | $ 361 | patterns 362 | 363 | 364 | include 365 | $self 366 | 367 | 368 | 369 | 370 | match 371 | [=-]> 372 | name 373 | storage.type.function.coffee 374 | 375 | 376 | match 377 | \b(?<!\.)(true|on|yes)(?!\s*[:=])\b 378 | name 379 | constant.language.boolean.true.coffee 380 | 381 | 382 | match 383 | \b(?<!\.)(false|off|no)(?!\s*[:=])\b 384 | name 385 | constant.language.boolean.false.coffee 386 | 387 | 388 | match 389 | \b(?<!\.)null(?!\s*[:=])\b 390 | name 391 | constant.language.null.coffee 392 | 393 | 394 | match 395 | \b(?<!\.)(this|extends)(?!\s*[:=])\b 396 | name 397 | variable.language.coffee 398 | 399 | 400 | captures 401 | 402 | 1 403 | 404 | name 405 | storage.type.class.coffee 406 | 407 | 2 408 | 409 | name 410 | entity.name.type.class.coffee 411 | 412 | 3 413 | 414 | name 415 | keyword.control.inheritance.coffee 416 | 417 | 4 418 | 419 | name 420 | entity.other.inherited-class.coffee 421 | 422 | 423 | match 424 | (class\b)\s+(@?[a-zA-Z\$_][\w\.]*)?(?:\s+(extends)\s+(@?[a-zA-Z\$\._][\w\.]*))? 425 | name 426 | meta.class.coffee 427 | 428 | 429 | match 430 | \b(debugger|\\)\b 431 | name 432 | keyword.other.coffee 433 | 434 | 435 | match 436 | (?x)\b( 437 | Array|ArrayBuffer|Blob|Boolean|Date|document|event|Function| 438 | Int(8|16|32|64)Array|Math|Map|Number| 439 | Object|Proxy|RegExp|Set|String|WeakMap| 440 | window|Uint(8|16|32|64)Array|XMLHttpRequest 441 | )\b 442 | name 443 | support.class.coffee 444 | 445 | 446 | match 447 | ((?<=console\.)(debug|warn|info|log|error|time|timeEnd|assert))\b 448 | name 449 | support.function.console.coffee 450 | 451 | 452 | match 453 | (?x)\b( 454 | decodeURI(Component)?|encodeURI(Component)?|eval|parse(Float|Int)|require 455 | )\b 456 | name 457 | support.function.coffee 458 | 459 | 460 | match 461 | (?x)((?<=\.)( 462 | apply|call|concat|every|filter|forEach|from|hasOwnProperty|indexOf| 463 | isPrototypeOf|join|lastIndexOf|map|of|pop|propertyIsEnumerable|push| 464 | reduce(Right)?|reverse|shift|slice|some|sort|splice|to(Locale)?String| 465 | unshift|valueOf 466 | ))\b 467 | name 468 | support.function.method.array.coffee 469 | 470 | 471 | match 472 | (?x)((?<=Array\.)( 473 | isArray 474 | ))\b 475 | name 476 | support.function.static.array.coffee 477 | 478 | 479 | match 480 | (?x)((?<=Object\.)( 481 | create|definePropert(ies|y)|freeze|getOwnProperty(Descriptors?|Names)| 482 | getProperty(Descriptor|Names)|getPrototypeOf|is(Extensible|Frozen|Sealed)?| 483 | isnt|keys|preventExtensions|seal 484 | ))\b 485 | name 486 | support.function.static.object.coffee 487 | 488 | 489 | match 490 | (?x)((?<=Math\.)( 491 | abs|acos|acosh|asin|asinh|atan|atan2|atanh|ceil|cos|cosh|exp|expm1|floor| 492 | hypot|log|log10|log1p|log2|max|min|pow|random|round|sign|sin|sinh|sqrt| 493 | tan|tanh|trunc 494 | ))\b 495 | name 496 | support.function.static.math.coffee 497 | 498 | 499 | match 500 | (?x)((?<=Number\.)( 501 | is(Finite|Integer|NaN)|toInteger 502 | ))\b 503 | name 504 | support.function.static.number.coffee 505 | 506 | 507 | match 508 | \b(Infinity|NaN|undefined)\b 509 | name 510 | constant.language.coffee 511 | 512 | 513 | match 514 | \; 515 | name 516 | punctuation.terminator.statement.coffee 517 | 518 | 519 | match 520 | ,[ |\t]* 521 | name 522 | meta.delimiter.object.comma.coffee 523 | 524 | 525 | match 526 | \. 527 | name 528 | meta.delimiter.method.period.coffee 529 | 530 | 531 | match 532 | \{|\} 533 | name 534 | meta.brace.curly.coffee 535 | 536 | 537 | match 538 | \(|\) 539 | name 540 | meta.brace.round.coffee 541 | 542 | 543 | match 544 | \[|\]\s* 545 | name 546 | meta.brace.square.coffee 547 | 548 | 549 | include 550 | #instance_variable 551 | 552 | 553 | include 554 | #single_quoted_string 555 | 556 | 557 | include 558 | #double_quoted_string 559 | 560 | 561 | include 562 | #numeric 563 | 564 | 565 | repository 566 | 567 | double_quoted_string 568 | 569 | patterns 570 | 571 | 572 | begin 573 | " 574 | beginCaptures 575 | 576 | 0 577 | 578 | name 579 | punctuation.definition.string.begin.coffee 580 | 581 | 582 | end 583 | " 584 | endCaptures 585 | 586 | 0 587 | 588 | name 589 | punctuation.definition.string.end.coffee 590 | 591 | 592 | name 593 | string.quoted.double.coffee 594 | patterns 595 | 596 | 597 | match 598 | \\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.) 599 | name 600 | constant.character.escape.coffee 601 | 602 | 603 | include 604 | #interpolated_coffee 605 | 606 | 607 | 608 | 609 | 610 | embedded_comment 611 | 612 | patterns 613 | 614 | 615 | captures 616 | 617 | 1 618 | 619 | name 620 | punctuation.definition.comment.coffee 621 | 622 | 623 | match 624 | (?<!\\)(#).*$\n? 625 | name 626 | comment.line.number-sign.coffee 627 | 628 | 629 | 630 | instance_variable 631 | 632 | patterns 633 | 634 | 635 | match 636 | (@)([a-zA-Z_\$]\w*)? 637 | name 638 | variable.other.readwrite.instance.coffee 639 | 640 | 641 | 642 | interpolated_coffee 643 | 644 | patterns 645 | 646 | 647 | begin 648 | \#\{ 649 | captures 650 | 651 | 0 652 | 653 | name 654 | punctuation.section.embedded.coffee 655 | 656 | 657 | end 658 | \} 659 | name 660 | source.coffee.embedded.source 661 | patterns 662 | 663 | 664 | include 665 | $self 666 | 667 | 668 | 669 | 670 | 671 | numeric 672 | 673 | patterns 674 | 675 | 676 | match 677 | (?<!\$)\b((0([box])[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?))\b 678 | name 679 | constant.numeric.coffee 680 | 681 | 682 | 683 | single_quoted_string 684 | 685 | patterns 686 | 687 | 688 | begin 689 | ' 690 | beginCaptures 691 | 692 | 0 693 | 694 | name 695 | punctuation.definition.string.begin.coffee 696 | 697 | 698 | end 699 | ' 700 | endCaptures 701 | 702 | 0 703 | 704 | name 705 | punctuation.definition.string.end.coffee 706 | 707 | 708 | name 709 | string.quoted.single.coffee 710 | patterns 711 | 712 | 713 | match 714 | \\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.) 715 | name 716 | constant.character.escape.coffee 717 | 718 | 719 | 720 | 721 | 722 | variable_name 723 | 724 | patterns 725 | 726 | 727 | captures 728 | 729 | 1 730 | 731 | name 732 | variable.assignment.coffee 733 | 734 | 735 | match 736 | ([a-zA-Z\$_]\w*(\.\w+)*) 737 | name 738 | variable.assignment.coffee 739 | 740 | 741 | 742 | 743 | scopeName 744 | source.coffee 745 | 746 | 747 | -------------------------------------------------------------------------------- /CoffeeScript.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Comments 7 | scope 8 | source.coffee 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | name 15 | TM_COMMENT_START 16 | value 17 | # 18 | 19 | 20 | name 21 | TM_COMMENT_START_2 22 | value 23 | ### 24 | 25 | 26 | name 27 | TM_COMMENT_END_2 28 | value 29 | ### 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Indent.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Indent 7 | scope 8 | source.coffee 9 | settings 10 | 11 | decreaseIndentPattern 12 | ^\s*(\}|\]|else|catch|finally)$ 13 | increaseIndentPattern 14 | (?x) 15 | ^\s* 16 | (.*class 17 | |[a-zA-Z\$_](\w|\$|:|\.)*\s*(?=\:(\s*\(.*\))?\s*((=|-)>\s*$)) # function that is not one line 18 | |[a-zA-Z\$_](\w|\$|\.)*\s*(:|=)\s*((if|while)(?!.*?then)|for|$) # assignment using multiline if/while/for 19 | |(if|while)\b(?!.*?then)|for\b 20 | |(try|finally|catch\s+\S.*)\s*$ 21 | |.*[-=]>$ 22 | |.*[\{\[]$) 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Keymaps/Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | {"keys": ["alt+shift+s"], "command": "check_syntax"} 3 | , {"keys": ["alt+shift+r"], "command": "run_script"} 4 | , {"keys": ["alt+shift+t"], "command": "run_cake_task"} 5 | , {"keys": ["alt+shift+c"], "command": "compile"} 6 | , {"keys": ["alt+shift+d"], "command": "compile_and_display", "args": {"opt": "-p"}} 7 | , {"keys": ["alt+shift+l"], "command": "compile_and_display", "args": {"opt": "-t"}} 8 | , {"keys": ["alt+shift+n"], "command": "compile_and_display", "args": {"opt": "-n"}} 9 | , {"keys": ["alt+shift+w"], "command": "toggle_watch"} 10 | , {"keys": ["alt+shift+z"], "command": "toggle_output_panel"} 11 | ] 12 | -------------------------------------------------------------------------------- /Keymaps/Default (OSX).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | {"keys": ["alt+shift+s"], "command": "check_syntax"} 3 | , {"keys": ["alt+shift+r"], "command": "run_script"} 4 | , {"keys": ["alt+shift+t"], "command": "run_cake_task"} 5 | , {"keys": ["alt+shift+c"], "command": "compile"} 6 | , {"keys": ["alt+shift+d"], "command": "compile_and_display", "args": {"opt": "-p"}} 7 | , {"keys": ["alt+shift+x"], "command": "compile_and_display", "args": {"opt": "-t"}} 8 | , {"keys": ["alt+shift+n"], "command": "compile_and_display", "args": {"opt": "-n"}} 9 | , {"keys": ["alt+shift+w"], "command": "toggle_watch"} 10 | , {"keys": ["alt+shift+z"], "command": "toggle_output_panel"} 11 | ] 12 | -------------------------------------------------------------------------------- /Keymaps/Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | {"keys": ["alt+shift+s"], "command": "check_syntax"} 3 | , {"keys": ["alt+shift+r"], "command": "run_script"} 4 | , {"keys": ["alt+shift+t"], "command": "run_cake_task"} 5 | , {"keys": ["alt+shift+c"], "command": "compile"} 6 | , {"keys": ["alt+shift+d"], "command": "compile_and_display", "args": {"opt": "-p"}} 7 | , {"keys": ["alt+shift+l"], "command": "compile_and_display", "args": {"opt": "-t"}} 8 | , {"keys": ["alt+shift+n"], "command": "compile_and_display", "args": {"opt": "-n"}} 9 | , {"keys": ["alt+shift+w"], "command": "toggle_watch"} 10 | , {"keys": ["alt+shift+z"], "command": "toggle_output_panel"} 11 | ] 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 sustained 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jump to Section 2 | 3 | * [Installation](#installation) 4 | * [Updating](#updating) 5 | * [Commands/Shortcuts](#commandsshortcuts) 6 | * [Snippets](#snippets) 7 | * [Building](#building) 8 | * [Settings](#settings) 9 | 10 | # Installation 11 | 12 | ## via Package Control 13 | 14 | > This is the recommended installation method. 15 | 16 | If you have Sublime Package Control, you know what to do. If not, well: it's a package manager for Sublime Text 2; it's awesome and you can [read about it here](http://wbond.net/sublime_packages/package_control). 17 | 18 | To install Package Control, open the Python Console (`ctrl+'` or ``cmd+` ``) and paste the following into it: 19 | 20 | import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation' 21 | 22 | After installing the package and restarting the editor: 23 | 24 | * Open the Command Pallete (`ctrl+shift+P` or `cmd+shift+P`). 25 | * Type "Install Package" and hit return. 26 | * Type "CoffeeScript" and hit return. 27 | 28 | ## via Source Control 29 | 30 | > If you plan to contribute, then you should install via this method. Otherwise it is recommended that you install the package via Package Control, see above. 31 | 32 | Sublime stores packages in the following locations: 33 | 34 | Nix: ~/.config/sublime-text-2/packages 35 | Mac: ~/Library/Application\ Support/Sublime\ Text\ 2/Packages 36 | Win: %APPDATA%\Sublime Text 2\Packages 37 | 38 | ### As a repository within the packages directory 39 | 40 | Open a Terminal/Console and run the following commands, replacing `PACKAGE_PATH` with the path corresponding to your OS above. 41 | 42 | cd PACKAGE_PATH 43 | git clone https://github.com/Xavura/CoffeeScript-Sublime-Plugin.git CoffeeScript 44 | 45 | ### As a repository outside of the packages directory 46 | 47 | If you use Github for Mac/Windows which store repositories in a specific location, or if you just don't want a repository in your packages directory, then instead you can use a link. 48 | 49 | If you don't yet have the repository, then grab it via your GUI program or via the command line: 50 | 51 | cd WHEREVER_YOU_WANT 52 | git clone https://github.com/Xavura/CoffeeScript-Sublime-Plugin.git 53 | 54 | Once that is done, we will create the link: 55 | 56 | #### Windows: 57 | 58 | cd PACKAGE_PATH 59 | mklink /D CoffeeScript ABSOLUTE_PATH_TO_REPOSITORY 60 | 61 | #### Nix/Mac: 62 | 63 | cd PACKAGE_PATH 64 | ln -s ABSOLUTE_PATH_TO_REPOSITORY CoffeeScript 65 | 66 | #### A note on Package Control 67 | 68 | When Package Control tries to update your packages, if you have a repository in your packages directory then it will try to pull down and merge any changes. If you don't want this to happen and would rather handle everything yourself, then you can add the following to your settings (Preferences » Package Settings » Package Control » Settings - User): 69 | 70 | "auto_upgrade_ignore": ["CoffeeScript"] 71 | 72 | # Updating 73 | 74 | If you are using Package Control, updating will be automatic and you don't have to worry about it. 75 | 76 | If using Source Control: 77 | 78 | cd PACKAGE_PATH/CoffeeScript 79 | git fetch origin 80 | git merge origin/master 81 | 82 | # Commands/Shortcuts 83 | 84 | You can access the commands either using the command palette (`ctrl+shift+P` or `cmd+shift+P`) or via shortcuts. 85 | 86 | alt+shift+t - Run a Cake task 87 | alt+shift+r - Run some CoffeeScript (puts/print is available for output) 88 | alt+shift+s - Run a syntax check 89 | alt+shift+c - Compile a file 90 | alt+shift+d - Display compiled JavaScript 91 | alt+shift+l - Display lexer tokens 92 | alt+shift+n - Display parser nodes 93 | alt+shift+w - Toggle watch mode 94 | alt+shift+p - Toggle output panel 95 | 96 | **Note:** Some of the commands use the Status Bar for output, so you'll probably want to enable it (Tools » Show Status Bar). 97 | 98 | # Snippets 99 | 100 | - Use `TAB` to run a snippet after typing the trigger. 101 | - Use `TAB` and `shift+TAB` to cycle forward/backward through fields. 102 | - Use `ESC` to exit snippet mode. 103 | 104 | ### Snippet Triggers 105 | 106 | **Comprehension** 107 | 108 | Array: forin 109 | Object: forof 110 | Range: fori (inclusive) 111 | Range: forx (exclusive) 112 | 113 | **Statements** 114 | 115 | If: if 116 | Else: el 117 | If Else: ifel 118 | Else If: elif 119 | Switch: swi 120 | Ternary: ter 121 | Try Catch: try 122 | Unless: unl 123 | 124 | **Classes** 125 | 126 | Class - cla 127 | 128 | **Other** 129 | 130 | Function: - 131 | Function: = (bound) 132 | Interpolation: # 133 | 134 | # Building 135 | 136 | > When using the build system, it is assumed that your `.sublime-project` file lives in your project's base directory (due to limitations with the build system). 137 | 138 | Hitting `F7` (Tools » Build) will run the Cake task 'sbuild'. 139 | 140 | If you're not quite sure what the point of this is then read on. 141 | 142 | Let's say before distributing your project that you would like to combine all of your `.js` files into one and then minify them them using UglifyJS or something. 143 | 144 | That's what this is for! You would create a `Cakefile` and inside it you would write a task: 145 | 146 | task 'sbuild', 'Prepare project for distribution.', -> 147 | # ... 148 | 149 | Examples coming soon. 150 | -------------------------------------------------------------------------------- /Snippets/Array comprehension.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for ${1:i} in ${2:array} 7 | ${3:# ...} 8 | $0 9 | name 10 | Array Comprehension 11 | scope 12 | source.coffee 13 | tabTrigger 14 | forin 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Bound Function.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${1:(${2:arguments}) }=> 7 | ${3:# ...} 8 | $0 9 | name 10 | Function (bound) 11 | scope 12 | source.coffee 13 | tabTrigger 14 | = 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Class.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | class ${1:Name} 7 | ${2:constructor: ${3:(${4:arguments}) }-> 8 | ${5:# ...}} 9 | $6 10 | $0 11 | name 12 | Class 13 | scope 14 | source.coffee 15 | tabTrigger 16 | cla 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/Console Log.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | console.log $0 7 | name 8 | log 9 | scope 10 | source.coffee 11 | tabTrigger 12 | log 13 | uuid 14 | FBC44B18-323A-4C00-A35B-15E41830C5AD 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Else if.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | else if ${1:condition} 7 | ${2:# ...} 8 | $0 9 | name 10 | Else if 11 | scope 12 | source.coffee 13 | tabTrigger 14 | elif 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Else.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | else 7 | ${1:# ...} 8 | $0 9 | name 10 | Else 11 | scope 12 | source.coffee 13 | tabTrigger 14 | el 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Function.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${1:(${2:arguments}) }-> 7 | ${3:# ...} 8 | $0 9 | 10 | name 11 | Function 12 | scope 13 | source.coffee 14 | tabTrigger 15 | - 16 | 17 | 18 | -------------------------------------------------------------------------------- /Snippets/If Else.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | if ${1:condition} 7 | ${2:# ...} 8 | else 9 | ${3:# ...} 10 | $0 11 | name 12 | If Else 13 | scope 14 | source.coffee 15 | tabTrigger 16 | ifel 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/If.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | if ${1:condition} 7 | ${2:# ...} 8 | $0 9 | name 10 | If 11 | scope 12 | source.coffee 13 | tabTrigger 14 | if 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Interpolated Code.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | #{${1:$TM_SELECTED_TEXT}} 7 | keyEquivalent 8 | # 9 | name 10 | Interpolated Code 11 | scope 12 | (string.quoted.double.coffee) - string source, (string.quoted.double.heredoc.coffee) - string source 13 | tabTrigger 14 | # 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Object comprehension.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for ${1:${2:k}, ${3:v}} of ${4:object} 7 | ${5:# ...} 8 | $0 9 | name 10 | Object Comprehension 11 | scope 12 | source.coffee 13 | tabTrigger 14 | forof 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Range comprehension (exclusive).tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for ${1:i} in [${2:start}...${3:finish}]${4: by ${5:step}} 7 | ${6:# ...} 8 | $0 9 | name 10 | Range Comprehension (exclusive) 11 | scope 12 | source.coffee 13 | tabTrigger 14 | forx 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Range comprehension (inclusive).tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | for ${1:i} in [${2:start}..${3:finish}]${4: by ${5:step}} 7 | ${6:# ...} 8 | $0 9 | name 10 | Range Comprehension (inclusive) 11 | scope 12 | source.coffee 13 | tabTrigger 14 | fori 15 | 16 | 17 | -------------------------------------------------------------------------------- /Snippets/Switch.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | switch ${1:object} 7 | when ${2:value} 8 | ${3:# ...} 9 | $4 10 | $0 11 | name 12 | Switch 13 | scope 14 | source.coffee 15 | tabTrigger 16 | swi 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/Ternary If.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | if ${1:condition} then ${2:...} else ${3:...} 7 | $0 8 | name 9 | Ternary If 10 | scope 11 | source.coffee 12 | tabTrigger 13 | ter 14 | 15 | 16 | -------------------------------------------------------------------------------- /Snippets/Try Catch.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | try 7 | ${1:# ...} 8 | catch ${2:e} 9 | ${3:# ...} 10 | $0 11 | name 12 | Try .. Catch 13 | scope 14 | source.coffee 15 | tabTrigger 16 | try 17 | 18 | 19 | -------------------------------------------------------------------------------- /Snippets/Unless.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${1:...} unless ${2:condition} 7 | $0 8 | name 9 | Unless 10 | scope 11 | source.coffee 12 | tabTrigger 13 | unl 14 | 15 | 16 | -------------------------------------------------------------------------------- /Snippets/require.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | ${2/^.*?([\w_]+).*$/\L$1/} = require ${2:'${1:sys}'}$3 7 | name 8 | require 9 | scope 10 | source.coffee 11 | tabTrigger 12 | req 13 | 14 | 15 | -------------------------------------------------------------------------------- /Symbol List.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Symbol List 7 | scope 8 | source.coffee meta.class.coffee, meta.function 9 | settings 10 | 11 | showInSymbolList 12 | 1 13 | 14 | uuid 15 | C02A31C1-E770-472F-A13E-358FF1C6AD89 16 | 17 | 18 | -------------------------------------------------------------------------------- /changelogs/0.5.1.txt: -------------------------------------------------------------------------------- 1 | CoffeeScript-Sublime-Plugin 0.5.1 Changelog 2 | 3 | Features 4 | 5 | - Added the missing Compile File command (alt+shift+c). This is useful if you 6 | just want to quickly compile a .coffee file to a .js file in the same directory. 7 | 8 | Enhancements 9 | 10 | - Added support for showing upgrade and installation messages, like this one. 11 | -------------------------------------------------------------------------------- /changelogs/0.5.2.txt: -------------------------------------------------------------------------------- 1 | CoffeeScript-Sublime-Plugin 0.5.2 Changelog 2 | 3 | Changes 4 | 5 | - On Mac OS, the shortcut for displaying lexer tokens has changed to alt+shift+x (for leXer tokens). This is because alt+shift+l is used to insert a pipe character on French keyboards. 6 | 7 | Enhancements 8 | 9 | - Improved the documentation. 10 | -------------------------------------------------------------------------------- /changelogs/0.5.3.txt: -------------------------------------------------------------------------------- 1 | CoffeeScript-Sublime-Plugin 0.5.2 Changelog 2 | 3 | Fixes 4 | 5 | - Several syntax highlighting issues. 6 | - Respect noWrapper setting when compiling. 7 | 8 | Enhancements 9 | 10 | - Added a build variant to quickly display the output of the current 11 | script via (ctrl+shift+B or cmd+shift+B). 12 | - CSON files are now recognised. 13 | - Go To Symbol improvements (see: http://i.stack.imgur.com/2vssw.png). 14 | -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "0.5.1": "changelogs/0.5.1.txt", 3 | "0.5.2": "changelogs/0.5.2.txt", 4 | "0.5.3": "changelogs/0.5.3.txt" 5 | } 6 | --------------------------------------------------------------------------------