├── README.md ├── indent └── lua.vim └── syntax └── lua.vim /README.md: -------------------------------------------------------------------------------- 1 | vim-lua 2 | ======= 3 | 4 | Improved Lua 5.3 syntax and indentation support for Vim. 5 | 6 | Highlighting: stock Vim (left) vs. this plugin (right): 7 | ![](http://tbastos.github.io/i/vim-lua-syntax.jpg) 8 | _(Color scheme: solarized dark; Font: Anonymous Pro)_ 9 | 10 | Configuration 11 | ------------- 12 | 13 | vim-lua supports a few options. All are boolean and off by default: set an 14 | option to 1 with `let g:lua_syntax_someoption = 1` to enable it (setting to `0` 15 | for disabling is currently not supported -- just don't set the option at all to 16 | keep it disabled). 17 | 18 | - `g:lua_syntax_nosymboloperator` disables highlighting of the Lua symbol 19 | operators (that is, all operators except for the keyword operators `and` and 20 | `or`). 21 | - `g:lua_syntax_fancynotequal` enables displaying Lua's `~=` operator with 22 | Unicode character `≠`. 23 | - `g:lua_syntax_nofold` disables code folding. If this option is set, you can 24 | selectively reenable some folds with `g:lua_syntax_fold_` where 25 | `` can be table, comment, function, control or string. You can also 26 | have even more fine-grained control by enabling specific syntax regions 27 | instead of groups. Look in the source code for the second argument of `call 28 | s:FoldableRegion` for all options, but note that the names are subject to 29 | change in later versions. 30 | - `g:lua_syntax_nostdlib` disables highlighting of all standard library names 31 | like, `io`, `print` and even `require`, `error` etc. If that is too much you 32 | can use `g:lua_syntax_noextendedstdlib` instead to keep `_G`, `module`, 33 | `require`, `assert`, `error`, `pcall` and `xpcall` highlighted. 34 | 35 | 36 | Contributing 37 | ------------ 38 | 39 | Contributions are welcome! Please follow the existing code style and in your 40 | pull request explain the reason for the proposed change and how it is valuable. 41 | 42 | Credits 43 | ------- 44 | 45 | The indent code was based off [this gist](https://gist.github.com/bonsaiviking/8845871). 46 | 47 | Various configuration options were contributed by Christian Neumüller 48 | (@Oberon00). 49 | -------------------------------------------------------------------------------- /indent/lua.vim: -------------------------------------------------------------------------------- 1 | " Vim indent file 2 | " Language: Lua 3 | " URL: https://github.com/tbastos/vim-lua 4 | 5 | " Initialization ------------------------------------------{{{1 6 | 7 | if exists("b:did_indent") 8 | finish 9 | endif 10 | let b:did_indent = 1 11 | 12 | setlocal autoindent 13 | setlocal nosmartindent 14 | 15 | setlocal indentexpr=GetLuaIndent() 16 | setlocal indentkeys+=0=end,0=until,0=elseif,0=else 17 | 18 | " Only define the function once. 19 | if exists("*GetLuaIndent") 20 | finish 21 | endif 22 | 23 | " Variables -----------------------------------------------{{{1 24 | 25 | let s:open_patt = '\C\%(\<\%(function\|if\|repeat\|do\)\>\|(\|{\)' 26 | let s:middle_patt = '\C\<\%(else\|elseif\)\>' 27 | let s:close_patt = '\C\%(\<\%(end\|until\)\>\|)\|}\)' 28 | 29 | let s:anon_func_start = '\S\+\s*[({].*\ 0 && contents_prev !~# s:anon_func_end 93 | let i -= 1 94 | endif 95 | 96 | " if this line closed a paren, indent (except with anon funcs) 97 | call cursor(prev_line, col([prev_line, '$'])) 98 | let num_cur_closed_parens = searchpair('(', '', ')', 'mr', s:skip_expr, v:lnum) 99 | if num_cur_closed_parens > 0 && contents_cur !~# s:anon_func_end 100 | let i += 1 101 | endif 102 | 103 | " if the current line chains a function call to previous unchained line 104 | if contents_prev !~# s:chained_func_call && contents_cur =~# s:chained_func_call 105 | let i += 1 106 | endif 107 | 108 | " if the current line chains a function call to previous unchained line 109 | if contents_prev =~# s:chained_func_call && contents_cur !~# s:chained_func_call 110 | let i -= 1 111 | endif 112 | 113 | " special case: call(with, {anon = function() -- should indent only once 114 | if i > 1 && contents_prev =~# s:anon_func_start 115 | let i = 1 116 | endif 117 | 118 | " special case: end}) -- end of call w/ anon func should outdent only once 119 | if i < -1 && contents_cur =~# s:anon_func_end 120 | let i = -1 121 | endif 122 | 123 | " restore cursor 124 | call setpos(".", original_cursor_pos) 125 | 126 | return indent(prev_line) + (shiftwidth() * i) 127 | 128 | endfunction 129 | -------------------------------------------------------------------------------- /syntax/lua.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Lua 3 | " URL: https://github.com/tbastos/vim-lua 4 | 5 | if !exists("main_syntax") 6 | if version < 600 7 | syntax clear 8 | elseif exists("b:current_syntax") 9 | finish 10 | endif 11 | let main_syntax = 'lua' 12 | endif 13 | 14 | if exists('g:lua_syntax_fancynotequal') && !has('conceal') 15 | unlet g:lua_syntax_fancynotequal 16 | endif 17 | 18 | 19 | syntax sync fromstart 20 | 21 | function! s:FoldableRegion(tag, name, expr) 22 | let synexpr = 'syntax region ' . a:name . ' ' . a:expr 23 | let pfx = 'g:lua_syntax_fold_' 24 | if !exists('g:lua_syntax_nofold') || exists(pfx . a:tag) || exists(pfx . a:name) 25 | let synexpr .= ' fold' 26 | end 27 | exec synexpr 28 | endfunction 29 | 30 | " Clusters 31 | syntax cluster luaBase contains=luaComment,luaCommentLong,luaConstant,luaNumber,luaString,luaStringLong,luaBuiltIn 32 | syntax cluster luaExpr contains=@luaBase,luaTable,luaParen,luaBracket,luaSpecialTable,luaSpecialValue,luaOperator,luaSymbolOperator,luaEllipsis,luaComma,luaFunc,luaFuncCall,luaError 33 | syntax cluster luaStat 34 | \ contains=@luaExpr,luaIfThen,luaBlock,luaLoop,luaGoto,luaLabel,luaLocal,luaStatement,luaSemiCol,luaErrHand 35 | 36 | syntax match luaNoise /\%(\.\|,\|:\|\;\)/ 37 | 38 | " Symbols 39 | call s:FoldableRegion('table', 'luaTable', 40 | \ 'transparent matchgroup=luaBraces start="{" end="}" contains=@luaExpr') 41 | syntax region luaParen transparent matchgroup=luaParens start='(' end=')' contains=@luaExpr 42 | syntax region luaBracket transparent matchgroup=luaBrackets start="\[" end="\]" contains=@luaExpr 43 | syntax match luaComma "," 44 | syntax match luaSemiCol ";" 45 | if !exists('g:lua_syntax_nosymboloperator') 46 | if exists('g:lua_syntax_fancynotequal') 47 | syntax match luaNotEqOperator "\V~=" conceal cchar=≠ 48 | setlocal conceallevel=2 49 | endi 50 | syntax match luaSymbolOperator "[#<>=~^&|*/%+-]\|\.\." contains=luaNotEqOperator 51 | endi 52 | syntax match luaEllipsis "\.\.\." 53 | 54 | " Catch errors caused by unbalanced brackets and keywords 55 | syntax match luaError ")" 56 | syntax match luaError "}" 57 | syntax match luaError "\]" 58 | syntax match luaError "\<\%(end\|else\|elseif\|then\|until\)\>" 59 | 60 | " Shebang at the start 61 | syntax match luaComment "\%^#!.*" 62 | 63 | " Comments 64 | syntax keyword luaCommentTodo contained TODO FIXME XXX TBD 65 | syntax match luaComment "--.*$" contains=luaCommentTodo,luaDocTag,@Spell 66 | call s:FoldableRegion('comment', 'luaCommentLong', 67 | \ 'matchgroup=luaCommentLongTag start="--\[\z(=*\)\[" end="\]\z1\]" contains=luaCommentTodo,luaDocTag,@Spell') 68 | syntax match luaDocTag contained "\s@\k\+" 69 | 70 | " Function calls 71 | syntax match luaFuncCall /\k\+\%(\s*[{('"]\)\@=/ 72 | 73 | " Functions 74 | call s:FoldableRegion('function', 'luaFunc', 75 | \ 'transparent matchgroup=luaFuncKeyword start="\" end="\" contains=@luaStat,luaFuncSig') 76 | syntax region luaFuncSig contained transparent start="\(\\)\@<=" end=")" contains=luaFuncId,luaFuncArgs keepend 77 | syntax match luaFuncId contained "[^(]*(\@=" contains=luaFuncTable,luaFuncName 78 | syntax match luaFuncTable contained /\k\+\%(\s*[.:]\)\@=/ 79 | syntax match luaFuncName contained "[^(.:]*(\@=" 80 | syntax region luaFuncArgs contained transparent matchgroup=luaFuncParens start=/(/ end=/)/ contains=@luaBase,luaFuncArgName,luaFuncArgComma,luaEllipsis 81 | syntax match luaFuncArgName contained /\k\+/ 82 | syntax match luaFuncArgComma contained /,/ 83 | 84 | " if ... then 85 | syntax region luaIfThen transparent matchgroup=luaCond start="\" end="\"me=e-4 contains=@luaExpr nextgroup=luaThenEnd skipwhite skipempty 86 | 87 | " then ... end 88 | call s:FoldableRegion('control', 'luaThenEnd', 89 | \ 'contained transparent matchgroup=luaCond start="\" end="\" contains=@luaStat,luaElseifThen,luaElse') 90 | 91 | " elseif ... then 92 | syntax region luaElseifThen contained transparent matchgroup=luaCond start="\" end="\" contains=@luaExpr 93 | 94 | " else 95 | syntax keyword luaElse contained else 96 | 97 | " do ... end 98 | call s:FoldableRegion('control', 'luaLoopBlock', 99 | \ 'transparent matchgroup=luaRepeat start="\" end="\" contains=@luaStat contained') 100 | call s:FoldableRegion('control', 'luaBlock', 101 | \ 'transparent matchgroup=luaStatement start="\" end="\" contains=@luaStat') 102 | 103 | " repeat ... until 104 | call s:FoldableRegion('control', 'luaLoop', 105 | \ 'transparent matchgroup=luaRepeat start="\" end="\" contains=@luaStat nextgroup=@luaExpr') 106 | 107 | " while ... do 108 | syntax region luaLoop transparent matchgroup=luaRepeat start="\" end="\"me=e-2 contains=@luaExpr nextgroup=luaLoopBlock skipwhite skipempty 109 | 110 | " for ... do and for ... in ... do 111 | syntax region luaLoop transparent matchgroup=luaRepeat start="\" end="\"me=e-2 contains=@luaExpr,luaIn nextgroup=luaLoopBlock skipwhite skipempty 112 | syntax keyword luaIn contained in 113 | 114 | " goto and labels 115 | syntax keyword luaGoto goto nextgroup=luaGotoLabel skipwhite 116 | syntax match luaGotoLabel "\k\+" contained 117 | syntax match luaLabel "::\k\+::" 118 | 119 | " Other Keywords 120 | syntax keyword luaConstant nil true false 121 | syntax keyword luaBuiltIn _ENV self 122 | syntax keyword luaLocal local 123 | syntax keyword luaOperator and or not 124 | syntax keyword luaStatement break return 125 | 126 | " Strings 127 | syntax match luaStringSpecial contained #\\[\\abfnrtvz'"]\|\\x[[:xdigit:]]\{2}\|\\[[:digit:]]\{,3}# 128 | call s:FoldableRegion('string', 'luaStringLong', 129 | \ 'matchgroup=luaStringLongTag start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell') 130 | syntax region luaString start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=luaStringSpecial,@Spell 131 | syntax region luaString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=luaStringSpecial,@Spell 132 | 133 | " Decimal constant 134 | syntax match luaNumber "\<\d\+\>" 135 | " Hex constant 136 | syntax match luaNumber "\<0[xX][[:xdigit:].]\+\%([pP][-+]\=\d\+\)\=\>" 137 | " Floating point constant, with dot, optional exponent 138 | syntax match luaFloat "\<\d\+\.\d*\%([eE][-+]\=\d\+\)\=\>" 139 | " Floating point constant, starting with a dot, optional exponent 140 | syntax match luaFloat "\.\d\+\%([eE][-+]\=\d\+\)\=\>" 141 | " Floating point constant, without dot, with exponent 142 | syntax match luaFloat "\<\d\+[eE][-+]\=\d\+\>" 143 | 144 | 145 | " Special names from the Standard Library 146 | if !exists('g:lua_syntax_nostdlib') 147 | syntax keyword luaSpecialValue 148 | \ module 149 | \ require 150 | 151 | syntax keyword luaSpecialTable _G 152 | 153 | syntax keyword luaErrHand 154 | \ assert 155 | \ error 156 | \ pcall 157 | \ xpcall 158 | 159 | if !exists('g:lua_syntax_noextendedstdlib') 160 | syntax keyword luaSpecialTable 161 | \ bit32 162 | \ coroutine 163 | \ debug 164 | \ io 165 | \ math 166 | \ os 167 | \ package 168 | \ string 169 | \ table 170 | \ utf8 171 | 172 | syntax keyword luaSpecialValue 173 | \ _VERSION 174 | \ collectgarbage 175 | \ dofile 176 | \ getfenv 177 | \ getmetatable 178 | \ ipairs 179 | \ load 180 | \ loadfile 181 | \ loadstring 182 | \ next 183 | \ pairs 184 | \ print 185 | \ rawequal 186 | \ rawget 187 | \ rawlen 188 | \ rawset 189 | \ select 190 | \ setfenv 191 | \ setmetatable 192 | \ tonumber 193 | \ tostring 194 | \ type 195 | \ unpack 196 | endif 197 | endif 198 | 199 | " Define the default highlighting. 200 | " For version 5.7 and earlier: only when not done already 201 | " For version 5.8 and later: only when an item doesn't have highlighting yet 202 | if version >= 508 || !exists("did_lua_syn_inits") 203 | if version < 508 204 | let did_lua_syn_inits = 1 205 | command -nargs=+ HiLink hi link 206 | else 207 | command -nargs=+ HiLink hi def link 208 | endif 209 | HiLink luaParens Noise 210 | HiLink luaBraces Structure 211 | HiLink luaBrackets Noise 212 | HiLink luaBuiltIn Special 213 | HiLink luaComment Comment 214 | HiLink luaCommentLongTag luaCommentLong 215 | HiLink luaCommentLong luaComment 216 | HiLink luaCommentTodo Todo 217 | HiLink luaCond Conditional 218 | HiLink luaConstant Constant 219 | HiLink luaDocTag Underlined 220 | HiLink luaEllipsis Special 221 | HiLink luaElse Conditional 222 | HiLink luaError Error 223 | HiLink luaFloat Float 224 | HiLink luaFuncArgName Noise 225 | HiLink luaFuncCall PreProc 226 | HiLink luaFuncId Function 227 | HiLink luaFuncName luaFuncId 228 | HiLink luaFuncTable luaFuncId 229 | HiLink luaFuncKeyword luaFunction 230 | HiLink luaFunction Structure 231 | HiLink luaFuncParens Noise 232 | HiLink luaGoto luaStatement 233 | HiLink luaGotoLabel Noise 234 | HiLink luaIn Repeat 235 | HiLink luaLabel Label 236 | HiLink luaLocal Type 237 | HiLink luaNumber Number 238 | HiLink luaSymbolOperator luaOperator 239 | HiLink luaNotEqOperator luaOperator 240 | HiLink luaOperator Operator 241 | HiLink luaRepeat Repeat 242 | HiLink luaSemiCol Delimiter 243 | HiLink luaSpecialTable Special 244 | HiLink luaSpecialValue PreProc 245 | HiLink luaStatement Statement 246 | HiLink luaString String 247 | HiLink luaStringLong luaString 248 | HiLink luaStringSpecial SpecialChar 249 | HiLink luaErrHand Exception 250 | 251 | if exists('g:lua_syntax_fancynotequal') 252 | hi! link Conceal luaOperator 253 | endi 254 | 255 | delcommand HiLink 256 | end 257 | 258 | let b:current_syntax = "lua" 259 | if main_syntax == 'lua' 260 | unlet main_syntax 261 | endif 262 | --------------------------------------------------------------------------------