├── Comments.tmPreferences ├── Indent.tmPreferences ├── License.txt ├── Lua Dev.sublime-settings ├── Lua.JSON-tmLanguage ├── Lua.sublime-build ├── Lua.tmLanguage ├── Main.sublime-menu ├── NewHighlighting.png ├── OldHighlighting.png ├── ParseLua.py ├── README.md ├── StatusBar.png └── SyntaxError.png /Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Comments 7 | scope 8 | source.lua 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | name 15 | TM_COMMENT_START 16 | value 17 | -- 18 | 19 | 20 | 21 | uuid 22 | fb35c053-d9e7-48b4-95f7-47f85d448b8e 23 | 24 | 25 | -------------------------------------------------------------------------------- /Indent.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Indent 7 | scope 8 | source.lua 9 | settings 10 | 11 | decreaseIndentPattern 12 | ^\s*(else|end|\})\s*$|^\s*elseif\b((?!end).)*$ 13 | increaseIndentPattern 14 | ^\s*(else|elseif|for|(local\s+)?function|if|repeat|until|while)\b((?!end).)*$|.*\{\s*$ 15 | 16 | uuid 17 | 411468A8-E0AC-415A-9E71-E2BD091EB571 18 | 19 | 20 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Home / Licenses 2 | MIT License 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2014 Rory Driscoll 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | -------------------------------------------------------------------------------- /Lua Dev.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "live_parser" : true, 3 | "luac_path": "luac" 4 | } 5 | -------------------------------------------------------------------------------- /Lua.JSON-tmLanguage: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Lua Dev", 3 | "scopeName": "source.lua", 4 | "fileTypes": [ 5 | "lua" 6 | ], 7 | "repository": { 8 | "general": { 9 | "patterns": [ 10 | { 11 | "include": "#linecomment" 12 | }, 13 | { 14 | "include": "#blockcomment" 15 | }, 16 | { 17 | "include": "#number" 18 | }, 19 | { 20 | "include": "#constant" 21 | }, 22 | { 23 | "include": "#singlequotestring" 24 | }, 25 | { 26 | "include": "#doublequotestring" 27 | }, 28 | { 29 | "include": "#multilinestring" 30 | }, 31 | { 32 | "include": "#function" 33 | }, 34 | { 35 | "include": "#libfunctioncall" 36 | }, 37 | { 38 | "include": "#functioncall" 39 | }, 40 | { 41 | "include": "#if" 42 | }, 43 | { 44 | "include": "#ifblock" 45 | }, 46 | { 47 | "include": "#forblock" 48 | }, 49 | { 50 | "include": "#whileblock" 51 | }, 52 | { 53 | "include": "#repeatblock" 54 | }, 55 | { 56 | "include": "#tabledecl" 57 | }, 58 | { 59 | "include": "#arrayindex" 60 | }, 61 | { 62 | "include": "#operator" 63 | }, 64 | { 65 | "include": "#keyword" 66 | }, 67 | { 68 | "include": "#variable" 69 | } 70 | ] 71 | }, 72 | "linecomment": { 73 | "name": "comment.line.double-dash.lua", 74 | "match": "(--)(?!(\\[=*\\[|\\]=*\\])).*$\n?", 75 | "captures": { 76 | "1": { 77 | "name": "punctuation.definition.comment.lua" 78 | } 79 | } 80 | }, 81 | "blockcomment": { 82 | "name": "comment.block.lua", 83 | "begin": "--\\[(=*)\\[", 84 | "beginCaptures": { 85 | "0": { 86 | "name": "punctuation.definition.comment.lua" 87 | } 88 | }, 89 | "end": "\\]\\1\\]", 90 | "endCaptures": { 91 | "0": { 92 | "name": "punctuation.definition.comment.lua" 93 | } 94 | } 95 | }, 96 | "constant": { 97 | "name": "constant.language.lua", 98 | "match": "nil|true|false|_G|_VERSION|\\.\\.\\." 99 | }, 100 | "number": { 101 | "name": "constant.numeric.lua", 102 | "match": "(?=?|(? 2 | 3 | 4 | 5 | fileTypes 6 | 7 | lua 8 | 9 | name 10 | Lua Dev 11 | patterns 12 | 13 | 14 | include 15 | #general 16 | 17 | 18 | repository 19 | 20 | arrayindex 21 | 22 | begin 23 | \[ 24 | end 25 | \] 26 | name 27 | meta.arrayindex.lua 28 | patterns 29 | 30 | 31 | include 32 | #general 33 | 34 | 35 | 36 | blockcomment 37 | 38 | begin 39 | --\[(=*)\[ 40 | beginCaptures 41 | 42 | 0 43 | 44 | name 45 | punctuation.definition.comment.lua 46 | 47 | 48 | end 49 | \]\1\] 50 | endCaptures 51 | 52 | 0 53 | 54 | name 55 | punctuation.definition.comment.lua 56 | 57 | 58 | name 59 | comment.block.lua 60 | 61 | constant 62 | 63 | match 64 | nil|true|false|_G|_VERSION|\.\.\. 65 | name 66 | constant.language.lua 67 | 68 | doublequotestring 69 | 70 | begin 71 | " 72 | beginCaptures 73 | 74 | 0 75 | 76 | name 77 | punctuation.definition.string.begin.lua 78 | 79 | 80 | end 81 | " 82 | endCaptures 83 | 84 | 0 85 | 86 | name 87 | punctuation.definition.string.end.lua 88 | 89 | 90 | name 91 | string.quoted.double.lua 92 | patterns 93 | 94 | 95 | match 96 | \\(\d{1,3}|.) 97 | name 98 | constant.character.escape.lua 99 | 100 | 101 | 102 | forblock 103 | 104 | begin 105 | \bfor\b 106 | beginCaptures 107 | 108 | 0 109 | 110 | name 111 | keyword.control.lua 112 | 113 | 114 | end 115 | \bend\b 116 | endCaptures 117 | 118 | 0 119 | 120 | name 121 | keyword.control.lua 122 | 123 | 124 | name 125 | meta.forblock.lua 126 | patterns 127 | 128 | 129 | include 130 | #general 131 | 132 | 133 | 134 | function 135 | 136 | begin 137 | \b(function)(\s+(((\w(\w|\d)*)(\.|:))*(\w(\w|\d)*)))?\s*(\()\s*((\.\.\.|\w(\w|\d)*)(,\s*(\.\.\.|\w(\w|\d)*))*)?\s*(\)) 138 | beginCaptures 139 | 140 | 1 141 | 142 | name 143 | keyword.control.lua 144 | 145 | 11 146 | 147 | name 148 | variable.parameter.function.lua 149 | 150 | 3 151 | 152 | name 153 | entity.name.function.lua 154 | 155 | 156 | end 157 | \bend\b 158 | endCaptures 159 | 160 | 0 161 | 162 | name 163 | keyword.control.lua 164 | 165 | 166 | name 167 | meta.function.lua 168 | patterns 169 | 170 | 171 | include 172 | #general 173 | 174 | 175 | 176 | functioncall 177 | 178 | begin 179 | ((\w(\w|\d)*[\.:])*\w(\w|\d)*)\( 180 | end 181 | \) 182 | name 183 | meta.functioncall.lua 184 | patterns 185 | 186 | 187 | include 188 | #general 189 | 190 | 191 | 192 | general 193 | 194 | patterns 195 | 196 | 197 | include 198 | #linecomment 199 | 200 | 201 | include 202 | #blockcomment 203 | 204 | 205 | include 206 | #number 207 | 208 | 209 | include 210 | #constant 211 | 212 | 213 | include 214 | #singlequotestring 215 | 216 | 217 | include 218 | #doublequotestring 219 | 220 | 221 | include 222 | #multilinestring 223 | 224 | 225 | include 226 | #function 227 | 228 | 229 | include 230 | #functioncall 231 | 232 | 233 | include 234 | #if 235 | 236 | 237 | include 238 | #ifblock 239 | 240 | 241 | include 242 | #forblock 243 | 244 | 245 | include 246 | #whileblock 247 | 248 | 249 | include 250 | #repeatblock 251 | 252 | 253 | include 254 | #tabledecl 255 | 256 | 257 | include 258 | #arrayindex 259 | 260 | 261 | include 262 | #operator 263 | 264 | 265 | include 266 | #keyword 267 | 268 | 269 | include 270 | #variable 271 | 272 | 273 | 274 | ifblock 275 | 276 | begin 277 | \bif\b 278 | beginCaptures 279 | 280 | 0 281 | 282 | name 283 | keyword.control.lua 284 | 285 | 286 | end 287 | \bend\b 288 | endCaptures 289 | 290 | 0 291 | 292 | name 293 | keyword.control.lua 294 | 295 | 296 | name 297 | meta.ifblock.lua 298 | patterns 299 | 300 | 301 | include 302 | #general 303 | 304 | 305 | 306 | keyword 307 | 308 | match 309 | \b(break|do|else|for|if|elseif|return|then|repeat|while|until|end|function|local|in)\b 310 | name 311 | keyword.control.lua 312 | 313 | libfunctioncall 314 | 315 | beginCaptures 316 | 317 | 1 318 | 319 | name 320 | support.function.lua 321 | 322 | 323 | end 324 | \) 325 | match 326 | (?<![^.]\.|:)\b(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall|coroutine\.(create|resume|running|status|wrap|yield)|string\.(byte|char|dump|find|format|gmatch|gsub|len|lower|match|rep|reverse|sub|upper)|table\.(concat|insert|maxn|remove|sort)|math\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|pow|rad|random|randomseed|sinh?|sqrt|tanh?)|io\.(close|flush|input|lines|open|output|popen|read|tmpfile|type|write)|os\.(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)|package\.(cpath|loaded|loadlib|path|preload|seeall)|debug\.(debug|[gs]etfenv|[gs]ethook|getinfo|[gs]etlocal|[gs]etmetatable|getregistry|[gs]etupvalue|traceback))\b(?=[( {]) 327 | name 328 | meta.functioncall.lua 329 | patterns 330 | 331 | 332 | include 333 | #general 334 | 335 | 336 | 337 | linecomment 338 | 339 | captures 340 | 341 | 1 342 | 343 | name 344 | punctuation.definition.comment.lua 345 | 346 | 347 | match 348 | (--)(?!(\[=*\[|\]=*\])).*$ 349 | ? 350 | name 351 | comment.line.double-dash.lua 352 | 353 | multilinestring 354 | 355 | begin 356 | \[(=*)\[ 357 | beginCaptures 358 | 359 | 0 360 | 361 | name 362 | punctuation.definition.string.begin.lua 363 | 364 | 365 | end 366 | \]\1\] 367 | endCaptures 368 | 369 | 0 370 | 371 | name 372 | punctuation.definition.string.end.lua 373 | 374 | 375 | name 376 | string.quoted.block.lua 377 | 378 | number 379 | 380 | match 381 | (?<![\d.])\s0x[a-fA-F\d]+|\b\d+(\.\d+)?([eE]-?\d+)?|\.\d+([eE]-?\d+)? 382 | name 383 | constant.numeric.lua 384 | 385 | operator 386 | 387 | match 388 | (\b(and|or|not)\b)|(\+|-|%|#|\*|\/|\^|==?|~=|<=?|>=?|(?<!\.)\.{2}(?!\.)) 389 | name 390 | keyword.operator.lua 391 | 392 | repeatblock 393 | 394 | begin 395 | \brepeat\b 396 | beginCaptures 397 | 398 | 0 399 | 400 | name 401 | keyword.control.lua 402 | 403 | 404 | end 405 | \buntil\b 406 | endCaptures 407 | 408 | 0 409 | 410 | name 411 | keyword.control.lua 412 | 413 | 414 | name 415 | meta.repeatblock.lua 416 | patterns 417 | 418 | 419 | include 420 | #general 421 | 422 | 423 | 424 | singlequotestring 425 | 426 | begin 427 | ' 428 | beginCaptures 429 | 430 | 0 431 | 432 | name 433 | punctuation.definition.string.begin.lua 434 | 435 | 436 | end 437 | ' 438 | endCaptures 439 | 440 | 0 441 | 442 | name 443 | punctuation.definition.string.end.lua 444 | 445 | 446 | name 447 | string.quoted.single.lua 448 | patterns 449 | 450 | 451 | match 452 | \\(\d{1,3}|.) 453 | name 454 | constant.character.escape.lua 455 | 456 | 457 | 458 | tabledecl 459 | 460 | begin 461 | { 462 | end 463 | } 464 | name 465 | meta.tabledecl.lua 466 | patterns 467 | 468 | 469 | include 470 | #general 471 | 472 | 473 | 474 | variable 475 | 476 | match 477 | ([A-Za-z_][A-Za-z0-9_\.]*) 478 | name 479 | variable.other.lua 480 | 481 | whileblock 482 | 483 | begin 484 | \bwhile\b 485 | beginCaptures 486 | 487 | 0 488 | 489 | name 490 | keyword.control.lua 491 | 492 | 493 | end 494 | \bend\b 495 | endCaptures 496 | 497 | 0 498 | 499 | name 500 | keyword.control.lua 501 | 502 | 503 | name 504 | meta.whileblock.lua 505 | patterns 506 | 507 | 508 | include 509 | #general 510 | 511 | 512 | 513 | 514 | scopeName 515 | source.lua 516 | uuid 517 | d3691eb0-1e00-4893-90fc-1a78c6c100b0 518 | 519 | 520 | -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences", 4 | "mnemonic": "n", 5 | "id": "preferences", 6 | "children": 7 | [ 8 | { 9 | "caption": "Package Settings", 10 | "mnemonic": "P", 11 | "id": "package-settings", 12 | "children": 13 | [ 14 | { 15 | "caption": "Lua Dev", 16 | "children": 17 | [ 18 | { 19 | "command": "open_file", "args": 20 | { 21 | "file": "${packages}/Lua Dev/Lua Dev.sublime-settings" 22 | }, 23 | "caption": "Settings – Default" 24 | }, 25 | { 26 | "command": "open_file", "args": 27 | { 28 | "file": "${packages}/User/Lua Dev.sublime-settings" 29 | }, 30 | "caption": "Settings – User" 31 | }, 32 | { "caption": "-" } 33 | ] 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /NewHighlighting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rorydriscoll/LuaSublime/3726a11247c0d7a1f721758e07f47333918fba47/NewHighlighting.png -------------------------------------------------------------------------------- /OldHighlighting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rorydriscoll/LuaSublime/3726a11247c0d7a1f721758e07f47333918fba47/OldHighlighting.png -------------------------------------------------------------------------------- /ParseLua.py: -------------------------------------------------------------------------------- 1 | import sublime 2 | import sublime_plugin 3 | import re 4 | from subprocess import Popen, PIPE 5 | 6 | 7 | class ParseLuaCommand(sublime_plugin.EventListener): 8 | 9 | TIMEOUT_MS = 200 10 | 11 | def __init__(self): 12 | self.pending = 0 13 | 14 | def on_modified(self, view): 15 | self.settings = sublime.load_settings("Lua Dev.sublime-settings") 16 | if not self.settings.get("live_parser"): 17 | return 18 | filename = view.file_name() 19 | if not filename or not filename.endswith('.lua'): 20 | return 21 | self.pending = self.pending + 1 22 | sublime.set_timeout(lambda: self.parse(view), self.TIMEOUT_MS) 23 | 24 | def parse(self, view): 25 | # Don't bother parsing if there's another parse command pending 26 | self.pending = self.pending - 1 27 | if self.pending > 0: 28 | return 29 | # Grab the path to luac from the settings 30 | luac_path = self.settings.get("luac_path") 31 | # Run luac with the parse option 32 | p = Popen(luac_path + ' -p -', stdin=PIPE, stderr=PIPE, shell=True) 33 | text = view.substr(sublime.Region(0, view.size())) 34 | errors = p.communicate(text.encode('utf-8'))[1] 35 | result = p.wait() 36 | # Clear out any old region markers 37 | view.erase_regions('lua') 38 | # Nothing to do if it parsed successfully 39 | if result == 0: 40 | return 41 | # Add regions and place the error message in the status bar 42 | errors = errors.decode("utf-8") 43 | sublime.status_message(errors) 44 | pattern = re.compile(r':([0-9]+):') 45 | regions = [view.full_line(view.text_point(int(match) - 1, 0)) for match in pattern.findall(errors)] 46 | view.add_regions('lua', regions, 'invalid', 'DOT', sublime.HIDDEN) 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LuaSublime 2 | ========== 3 | 4 | A collection of various different support files useful for use when programming in Lua using Sublime Text 2. 5 | 6 | Installation 7 | ------------ 8 | 9 | These files should be placed into the Lua package directory. For those on OS X, this can be found at: 10 | 11 | `/Users/[USERNAME]/Library/Application Support/Sublime Text 2/Packages/Lua` 12 | 13 | For Windows, this directory is here: 14 | 15 | `C:\\Users\\[USERNAME]\\AppData\\Roaming\\Sublime Text 2\\Packages\\Lua` 16 | 17 | Contents 18 | -------- 19 | 20 | ### Syntax Coloring 21 | 22 | `Lua.tmLanguage` 23 | `Lua.JSON-tmLanguage` 24 | 25 | These files define a language grammar for syntax highlighting lua files. Compared to the one that ships with Sublime Text, you get the following: 26 | 27 | - _More tokens_: Things like function calls and variables are now tagged, so they will show up correctly colored. 28 | - _Better scopes_: Most blocks now have some nested scoping support. This means that if the carat is on a variable in an if-block inside a function inside another function, then it knows this. This doesn't affect the coloring, but if you use the 'expand selection to scope' command then you will find that you'll get far better matches now. 29 | 30 | For comparison, here's how the old syntax-highlighting looks with the Twilight color scheme: 31 | 32 | ![Old](https://github.com/rorydriscoll/LuaSublime/raw/master/OldHighlighting.png) 33 | 34 | And here's the new one: 35 | 36 | ![New](https://github.com/rorydriscoll/LuaSublime/raw/master/NewHighlighting.png) 37 | 38 | ### Build System 39 | 40 | `Lua.sublime-build` 41 | 42 | This is a simple build system that compiles and runs the current lua file. You can jump between errors using F4. 43 | 44 | ### Live Parser 45 | 46 | `ParseLua.py` 47 | 48 | This is a small plugin that continually parses the current lua file and highlights any errors by placing a dot in the margin. 49 | 50 | ![Syntax Error](https://github.com/rorydriscoll/LuaSublime/raw/master/SyntaxError.png) 51 | 52 | Lua appears to stop at the first error, so you should only ever see one dot. The error message will be shown in the status bar. 53 | 54 | ![Status Bar](https://github.com/rorydriscoll/LuaSublime/raw/master/StatusBar.png) -------------------------------------------------------------------------------- /StatusBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rorydriscoll/LuaSublime/3726a11247c0d7a1f721758e07f47333918fba47/StatusBar.png -------------------------------------------------------------------------------- /SyntaxError.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rorydriscoll/LuaSublime/3726a11247c0d7a1f721758e07f47333918fba47/SyntaxError.png --------------------------------------------------------------------------------