summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Stankiewicz <sheerun@sher.pl>2018-12-26 20:15:18 +0100
committerAdam Stankiewicz <sheerun@sher.pl>2018-12-26 20:15:18 +0100
commit0d5f661cfda484860fca89fb4701797cd56e6833 (patch)
tree9a7a46a186da5bd99f9928c53d735c6c7f397061
parente99f88ff0089ba78346143eaffaa7c8bf728dca2 (diff)
downloadvim-polyglot-0d5f661cfda484860fca89fb4701797cd56e6833.tar.gz
vim-polyglot-0d5f661cfda484860fca89fb4701797cd56e6833.zip
Add moonscript support
-rw-r--r--README.md3
-rwxr-xr-xbuild1
-rw-r--r--ftdetect/polyglot.vim21
-rw-r--r--ftplugin/moon.vim20
-rw-r--r--indent/moon.vim327
-rw-r--r--syntax/moon.vim321
6 files changed, 692 insertions, 1 deletions
diff --git a/README.md b/README.md
index 517246c7..7271e6c8 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ A collection of language packs for Vim.
> One to rule them all, one to find them, one to bring them all and in the darkness bind them.
- It **won't affect your startup time**, as scripts are loaded only on demand\*.
-- It **installs and updates 100+ times faster** than the <!--Package Count-->116<!--/Package Count--> packages it consists of.
+- It **installs and updates 100+ times faster** than the <!--Package Count-->117<!--/Package Count--> packages it consists of.
- Solid syntax and indentation support (other features skipped). Only the best language packs.
- All unnecessary files are ignored (like enormous documentation from php support).
- No support for esoteric languages, only most popular ones (modern too, like `slim`).
@@ -103,6 +103,7 @@ If you need full functionality of any plugin, please use it directly with your p
- [mako](https://github.com/sophacles/vim-bundle-mako) (syntax, indent, ftplugin)
- [markdown](https://github.com/plasticboy/vim-markdown) (syntax, indent)
- [mathematica](https://github.com/rsmenon/vim-mathematica) (syntax, ftplugin)
+- [moonscript](https://github.com/leafo/moonscript-vim) (syntax, indent, ftplugin)
- [nginx](https://github.com/chr4/nginx.vim) (syntax, indent, ftplugin)
- [nim](https://github.com/zah/nim.vim) (syntax, compiler, indent)
- [nix](https://github.com/LnL7/vim-nix) (syntax, indent, compiler, ftplugin)
diff --git a/build b/build
index ace41208..7ebb2899 100755
--- a/build
+++ b/build
@@ -212,6 +212,7 @@ PACKS="
mako:sophacles/vim-bundle-mako
markdown:plasticboy/vim-markdown:_SYNTAX
mathematica:rsmenon/vim-mathematica
+ moonscript:leafo/moonscript-vim
nginx:chr4/nginx.vim
nim:zah/nim.vim:_BASIC
nix:LnL7/vim-nix
diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim
index a63014d8..5eaa9325 100644
--- a/ftdetect/polyglot.vim
+++ b/ftdetect/polyglot.vim
@@ -650,6 +650,27 @@ au BufRead,BufNewFile *.{md,mdown,mkd,mkdn,markdown,mdwn}.{des3,des,bf,bfa,aes,i
augroup end
endif
+if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'moonscript') == -1
+ augroup filetypedetect
+ " moonscript, from moon.vim in leafo/moonscript-vim
+" Language: MoonScript
+" Maintainer: leafo <leafot@gmail.com>
+" Based On: CoffeeScript by Mick Koch <kchmck@gmail.com>
+" URL: http://github.com/leafo/moonscript-vim
+" License: WTFPL
+
+autocmd BufNewFile,BufRead *.moon set filetype=moon
+
+function! s:DetectMoon()
+ if getline(1) =~ '^#!.*\<moon\>'
+ set filetype=moon
+ endif
+endfunction
+
+autocmd BufNewFile,BufRead * call s:DetectMoon()
+ augroup end
+endif
+
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nginx') == -1
augroup filetypedetect
" nginx, from nginx.vim in chr4/nginx.vim
diff --git a/ftplugin/moon.vim b/ftplugin/moon.vim
new file mode 100644
index 00000000..4dc259fe
--- /dev/null
+++ b/ftplugin/moon.vim
@@ -0,0 +1,20 @@
+if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'moonscript') == -1
+
+" Language: MoonScript
+" Maintainer: leafo <leafot@gmail.com>
+" Based On: CoffeeScript by Mick Koch <kchmck@gmail.com>
+" URL: http://github.com/leafo/moonscript-vim
+" License: WTFPL
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+setlocal formatoptions-=t
+setlocal comments=:--
+setlocal commentstring=--\ %s
+
+let b:undo_ftplugin = "setlocal commentstring< comments< formatoptions<"
+
+endif
diff --git a/indent/moon.vim b/indent/moon.vim
new file mode 100644
index 00000000..85d5ce3f
--- /dev/null
+++ b/indent/moon.vim
@@ -0,0 +1,327 @@
+if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'moonscript') == -1
+
+" Language: MoonScript
+" Maintainer: leafo <leafot@gmail.com>
+" Based On: CoffeeScript by Mick Koch <kchmck@gmail.com>
+" URL: http://github.com/leafo/moonscript-vim
+" License: WTFPL
+
+if exists("b:did_indent")
+ finish
+endif
+
+let b:did_indent = 1
+
+setlocal autoindent
+setlocal indentexpr=GetMoonIndent(v:lnum)
+" Make sure GetMoonIndent is run when these are typed so they can be
+" indented or outdented.
+setlocal indentkeys+=0],0),0.,=else,=elseif
+
+" Only define the function once.
+if exists("*GetMoonIndent")
+ finish
+endif
+
+" Keywords to indent after
+let s:INDENT_AFTER_KEYWORD = '^\%(if\|unless\|else\|for\|while\|with\|elseif\|'
+\ . 'class\|switch\|when\)\>'
+
+" Operators to indent after
+let s:INDENT_AFTER_OPERATOR = '\%([([{:=]\|[-=]>\)$'
+
+" Keywords and operators that continue a line
+let s:CONTINUATION = '\<\%(is\|isnt\|and\|or\)\>$'
+\ . '\|'
+\ . '\%(-\@<!-\|+\@<!+\|<\|[-=]\@<!>\|\%(export \)\@<!\*\|/\@<!/\|%\||\|'
+\ . '&\|,\|\.\@<!\.\)$'
+
+" Operators that block continuation indenting
+let s:CONTINUATION_BLOCK = '[([{:=]$'
+
+" A continuation dot access
+let s:DOT_ACCESS = '^\.'
+
+" Keywords to outdent after
+let s:OUTDENT_AFTER = '^\%(return\|break\)\>'
+
+" A compound assignment like `... = if ...`
+let s:COMPOUND_ASSIGNMENT = '[:=]\s*\%(if\|unless\|for\|while\|'
+\ . 'with\|class\)\>'
+
+" A postfix condition like `return ... if ...`.
+let s:POSTFIX_CONDITION = '\S\s\+\zs\<\%(if\|unless\)\>'
+
+" A single-line else statement like `else ...` but not `else if ...
+let s:SINGLE_LINE_ELSE = '^else\s\+\%(\<\%(if\)\>\)\@!'
+
+" Max lines to look back for a match
+let s:MAX_LOOKBACK = 50
+
+" Syntax names for strings
+let s:SYNTAX_STRING = 'moon\%(String\|AssignString\|Embed\|Regex\|Heregex\|'
+\ . 'Heredoc\)'
+
+" Syntax names for comments
+let s:SYNTAX_COMMENT = 'moon\%(Comment\|BlockComment\|HeregexComment\)'
+
+" Syntax names for strings and comments
+let s:SYNTAX_STRING_COMMENT = s:SYNTAX_STRING . '\|' . s:SYNTAX_COMMENT
+
+" Get the linked syntax name of a character.
+function! s:SyntaxName(linenum, col)
+ return synIDattr(synID(a:linenum, a:col, 1), 'name')
+endfunction
+
+" Check if a character is in a comment.
+function! s:IsComment(linenum, col)
+ return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_COMMENT
+endfunction
+
+" Check if a character is in a string.
+function! s:IsString(linenum, col)
+ return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING
+endfunction
+
+" Check if a character is in a comment or string.
+function! s:IsCommentOrString(linenum, col)
+ return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING_COMMENT
+endfunction
+
+" Check if a whole line is a comment.
+function! s:IsCommentLine(linenum)
+ " Check the first non-whitespace character.
+ return s:IsComment(a:linenum, indent(a:linenum) + 1)
+endfunction
+
+" Repeatedly search a line for a regex until one is found outside a string or
+" comment.
+function! s:SmartSearch(linenum, regex)
+ " Start at the first column.
+ let col = 0
+
+ " Search until there are no more matches, unless a good match is found.
+ while 1
+ call cursor(a:linenum, col + 1)
+ let [_, col] = searchpos(a:regex, 'cn', a:linenum)
+
+ " No more matches.
+ if !col
+ break
+ endif
+
+ if !s:IsCommentOrString(a:linenum, col)
+ return 1
+ endif
+ endwhile
+
+ " No good match found.
+ return 0
+endfunction
+
+" Skip a match if it's in a comment or string, is a single-line statement that
+" isn't adjacent, or is a postfix condition.
+function! s:ShouldSkip(startlinenum, linenum, col)
+ if s:IsCommentOrString(a:linenum, a:col)
+ return 1
+ endif
+
+ " Check for a single-line statement that isn't adjacent.
+ if s:SmartSearch(a:linenum, '\<then\>') && a:startlinenum - a:linenum > 1
+ return 1
+ endif
+
+ if s:SmartSearch(a:linenum, s:POSTFIX_CONDITION) &&
+ \ !s:SmartSearch(a:linenum, s:COMPOUND_ASSIGNMENT)
+ return 1
+ endif
+
+ return 0
+endfunction
+
+" Find the farthest line to look back to, capped to line 1 (zero and negative
+" numbers cause bad things).
+function! s:MaxLookback(startlinenum)
+ return max([1, a:startlinenum - s:MAX_LOOKBACK])
+endfunction
+
+" Get the skip expression for searchpair().
+function! s:SkipExpr(startlinenum)
+ return "s:ShouldSkip(" . a:startlinenum . ", line('.'), col('.'))"
+endfunction
+
+" Search for pairs of text.
+function! s:SearchPair(start, end)
+ " The cursor must be in the first column for regexes to match.
+ call cursor(0, 1)
+
+ let startlinenum = line('.')
+
+ " Don't need the W flag since MaxLookback caps the search to line 1.
+ return searchpair(a:start, '', a:end, 'bcn',
+ \ s:SkipExpr(startlinenum),
+ \ s:MaxLookback(startlinenum))
+endfunction
+
+" Try to find a previous matching line.
+function! s:GetMatch(curline)
+ let firstchar = a:curline[0]
+
+ if firstchar == '}'
+ return s:SearchPair('{', '}')
+ elseif firstchar == ')'
+ return s:SearchPair('(', ')')
+ elseif firstchar == ']'
+ return s:SearchPair('\[', '\]')
+ elseif a:curline =~ '^else\>'
+ return s:SearchPair('\<\%(if\|unless\|when\)\>', '\<else\>')
+" elseif a:curline =~ '^catch\>'
+" return s:SearchPair('\<try\>', '\<catch\>')
+" elseif a:curline =~ '^finally\>'
+" return s:SearchPair('\<try\>', '\<finally\>')
+ endif
+
+ return 0
+endfunction
+
+" Get the nearest previous line that isn't a comment.
+function! s:GetPrevNormalLine(startlinenum)
+ let curlinenum = a:startlinenum
+
+ while curlinenum > 0
+ let curlinenum = prevnonblank(curlinenum - 1)
+
+ if !s:IsCommentLine(curlinenum)
+ return curlinenum
+ endif
+ endwhile
+
+ return 0
+endfunction
+
+" Try to find a comment in a line.
+function! s:FindComment(linenum)
+ let col = 0
+
+ while 1
+ call cursor(a:linenum, col + 1)
+ let [_, col] = searchpos('#', 'cn', a:linenum)
+
+ if !col
+ break
+ endif
+
+ if s:IsComment(a:linenum, col)
+ return col
+ endif
+ endwhile
+
+ return 0
+endfunction
+
+" Get a line without comments or surrounding whitespace.
+function! s:GetTrimmedLine(linenum)
+ let comment = 0
+ " let comment = s:FindComment(a:linenum)
+ let line = getline(a:linenum)
+
+ if comment
+ " Subtract 1 to get to the column before the comment and another 1 for
+ " zero-based indexing.
+ let line = line[:comment - 2]
+ endif
+
+ return substitute(substitute(line, '^\s\+', '', ''),
+ \ '\s\+$', '', '')
+endfunction
+
+function! s:GetMoonIndent(curlinenum)
+ let prevlinenum = s:GetPrevNormalLine(a:curlinenum)
+
+ " Don't do anything if there's no previous line.
+ if !prevlinenum
+ return -1
+ endif
+
+ let curline = s:GetTrimmedLine(a:curlinenum)
+
+ " Try to find a previous matching statement. This handles outdenting.
+ let matchlinenum = s:GetMatch(curline)
+
+ if matchlinenum
+ return indent(matchlinenum)
+ endif
+
+" " Try to find a matching `when`.
+" if curline =~ '^when\>' && !s:SmartSearch(prevlinenum, '\<switch\>')
+" let linenum = a:curlinenum
+"
+" while linenum > 0
+" let linenum = s:GetPrevNormalLine(linenum)
+"
+" if getline(linenum) =~ '^\s*when\>'
+" return indent(linenum)
+" endif
+" endwhile
+"
+" return -1
+" endif
+
+ let prevline = s:GetTrimmedLine(prevlinenum)
+ let previndent = indent(prevlinenum)
+
+ " Always indent after these operators.
+ if prevline =~ s:INDENT_AFTER_OPERATOR
+ return previndent + &shiftwidth
+ endif
+
+ " Indent after a continuation if it's the first.
+ if prevline =~ s:CONTINUATION
+ let prevprevlinenum = s:GetPrevNormalLine(prevlinenum)
+ let prevprevline = s:GetTrimmedLine(prevprevlinenum)
+
+ if prevprevline !~ s:CONTINUATION && prevprevline !~ s:CONTINUATION_BLOCK
+ return previndent + &shiftwidth
+ endif
+
+ return -1
+ endif
+
+ " Indent after these keywords and compound assignments if they aren't a
+ " single-line statement.
+ if prevline =~ s:INDENT_AFTER_KEYWORD || prevline =~ s:COMPOUND_ASSIGNMENT
+ if !s:SmartSearch(prevlinenum, '\<then\>') && prevline !~ s:SINGLE_LINE_ELSE
+ return previndent + &shiftwidth
+ endif
+
+ return -1
+ endif
+
+ " Indent a dot access if it's the first.
+ if curline =~ s:DOT_ACCESS && prevline !~ s:DOT_ACCESS
+ return previndent + &shiftwidth
+ endif
+
+ " Outdent after these keywords if they don't have a postfix condition or are
+ " a single-line statement.
+ if prevline =~ s:OUTDENT_AFTER
+ if !s:SmartSearch(prevlinenum, s:POSTFIX_CONDITION) ||
+ \ s:SmartSearch(prevlinenum, '\<then\>')
+ return previndent - &shiftwidth
+ endif
+ endif
+
+ " No indenting or outdenting is needed.
+ return -1
+endfunction
+
+" Wrap s:GetMoonIndent to keep the cursor position.
+function! GetMoonIndent(curlinenum)
+ let oldcursor = getpos('.')
+ let indent = s:GetMoonIndent(a:curlinenum)
+ call setpos('.', oldcursor)
+
+ return indent
+endfunction
+
+endif
diff --git a/syntax/moon.vim b/syntax/moon.vim
new file mode 100644
index 00000000..327e1359
--- /dev/null
+++ b/syntax/moon.vim
@@ -0,0 +1,321 @@
+if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'moonscript') == -1
+
+" Language: MoonScript
+" Maintainer: leafo <leafot@gmail.com>
+" Based On: CoffeeScript by Mick Koch <kchmck@gmail.com>
+" URL: http://github.com/leafo/moonscript-vim
+" License: WTFPL
+
+" Bail if our syntax is already loaded.
+if exists('b:current_syntax') && b:current_syntax == 'moon'
+ finish
+endif
+
+if version < 600
+ syn clear
+endif
+
+" Highlight long strings.
+syn sync minlines=100
+
+" These are `matches` instead of `keywords` because vim's highlighting
+" priority for keywords is higher than matches. This causes keywords to be
+" highlighted inside matches, even if a match says it shouldn't contain them --
+" like with moonAssign and moonDot.
+syn match moonStatement /\<\%(return\|break\|continue\)\>/ display
+hi def link moonStatement Statement
+
+syn match moonRepeat /\<\%(for\|while\)\>/ display
+hi def link moonRepeat Repeat
+
+syn match moonConditional /\<\%(if\|else\|elseif\|then\|switch\|when\|unless\)\>/
+\ display
+hi def link moonConditional Conditional
+
+" syn match moonException /\<\%(try\|catch\|finally\)\>/ display
+" hi def link moonException Exception
+
+syn match moonKeyword /\<\%(export\|local\|import\|from\|with\|in\|and\|or\|not\|class\|extends\|super\|using\|do\)\>/
+\ display
+hi def link moonKeyword Keyword
+
+" all built in funcs from Lua 5.1
+syn keyword moonLuaFunc assert collectgarbage dofile error next
+syn keyword moonLuaFunc print rawget rawset tonumber tostring type _VERSION
+syn keyword moonLuaFunc _G getfenv getmetatable ipairs loadfile
+syn keyword moonLuaFunc loadstring pairs pcall rawequal
+syn keyword moonLuaFunc require setfenv setmetatable unpack xpcall
+syn keyword moonLuaFunc load module select
+syn match moonLuaFunc /package\.cpath/
+syn match moonLuaFunc /package\.loaded/
+syn match moonLuaFunc /package\.loadlib/
+syn match moonLuaFunc /package\.path/
+syn match moonLuaFunc /package\.preload/
+syn match moonLuaFunc /package\.seeall/
+syn match moonLuaFunc /coroutine\.running/
+syn match moonLuaFunc /coroutine\.create/
+syn match moonLuaFunc /coroutine\.resume/
+syn match moonLuaFunc /coroutine\.status/
+syn match moonLuaFunc /coroutine\.wrap/
+syn match moonLuaFunc /coroutine\.yield/
+syn match moonLuaFunc /string\.byte/
+syn match moonLuaFunc /string\.char/
+syn match moonLuaFunc /string\.dump/
+syn match moonLuaFunc /string\.find/
+syn match moonLuaFunc /string\.len/
+syn match moonLuaFunc /string\.lower/
+syn match moonLuaFunc /string\.rep/
+syn match moonLuaFunc /string\.sub/
+syn match moonLuaFunc /string\.upper/
+syn match moonLuaFunc /string\.format/
+syn match moonLuaFunc /string\.gsub/
+syn match moonLuaFunc /string\.gmatch/
+syn match moonLuaFunc /string\.match/
+syn match moonLuaFunc /string\.reverse/
+syn match moonLuaFunc /table\.maxn/
+syn match moonLuaFunc /table\.concat/
+syn match moonLuaFunc /table\.sort/
+syn match moonLuaFunc /table\.insert/
+syn match moonLuaFunc /table\.remove/
+syn match moonLuaFunc /math\.abs/
+syn match moonLuaFunc /math\.acos/
+syn match moonLuaFunc /math\.asin/
+syn match moonLuaFunc /math\.atan/
+syn match moonLuaFunc /math\.atan2/
+syn match moonLuaFunc /math\.ceil/
+syn match moonLuaFunc /math\.sin/
+syn match moonLuaFunc /math\.cos/
+syn match moonLuaFunc /math\.tan/
+syn match moonLuaFunc /math\.deg/
+syn match moonLuaFunc /math\.exp/
+syn match moonLuaFunc /math\.floor/
+syn match moonLuaFunc /math\.log/
+syn match moonLuaFunc /math\.log10/
+syn match moonLuaFunc /math\.max/
+syn match moonLuaFunc /math\.min/
+syn match moonLuaFunc /math\.fmod/
+syn match moonLuaFunc /math\.modf/
+syn match moonLuaFunc /math\.cosh/
+syn match moonLuaFunc /math\.sinh/
+syn match moonLuaFunc /math\.tanh/
+syn match moonLuaFunc /math\.pow/
+syn match moonLuaFunc /math\.rad/
+syn match moonLuaFunc /math\.sqrt/
+syn match moonLuaFunc /math\.frexp/
+syn match moonLuaFunc /math\.ldexp/
+syn match moonLuaFunc /math\.random/
+syn match moonLuaFunc /math\.randomseed/
+syn match moonLuaFunc /math\.pi/
+syn match moonLuaFunc /io\.stdin/
+syn match moonLuaFunc /io\.stdout/
+syn match moonLuaFunc /io\.stderr/
+syn match moonLuaFunc /io\.close/
+syn match moonLuaFunc /io\.flush/
+syn match moonLuaFunc /io\.input/
+syn match moonLuaFunc /io\.lines/
+syn match moonLuaFunc /io\.open/
+syn match moonLuaFunc /io\.output/
+syn match moonLuaFunc /io\.popen/
+syn match moonLuaFunc /io\.read/
+syn match moonLuaFunc /io\.tmpfile/
+syn match moonLuaFunc /io\.type/
+syn match moonLuaFunc /io\.write/
+syn match moonLuaFunc /os\.clock/
+syn match moonLuaFunc /os\.date/
+syn match moonLuaFunc /os\.difftime/
+syn match moonLuaFunc /os\.execute/
+syn match moonLuaFunc /os\.exit/
+syn match moonLuaFunc /os\.getenv/
+syn match moonLuaFunc /os\.remove/
+syn match moonLuaFunc /os\.rename/
+syn match moonLuaFunc /os\.setlocale/
+syn match moonLuaFunc /os\.time/
+syn match moonLuaFunc /os\.tmpname/
+syn match moonLuaFunc /debug\.debug/
+syn match moonLuaFunc /debug\.gethook/
+syn match moonLuaFunc /debug\.getinfo/
+syn match moonLuaFunc /debug\.getlocal/
+syn match moonLuaFunc /debug\.getupvalue/
+syn match moonLuaFunc /debug\.setlocal/
+syn match moonLuaFunc /debug\.setupvalue/
+syn match moonLuaFunc /debug\.sethook/
+syn match moonLuaFunc /debug\.traceback/
+syn match moonLuaFunc /debug\.getfenv/
+syn match moonLuaFunc /debug\.getmetatable/
+syn match moonLuaFunc /debug\.getregistry/
+syn match moonLuaFunc /debug\.setfenv/
+syn match moonLuaFunc /debug\.setmetatable/
+
+hi def link moonLuaFunc Identifier
+
+" The first case matches symbol operators only if they have an operand before.
+syn match moonExtendedOp /\%(\S\s*\)\@<=[+\-*/%&|\^=!<>?#]\+\|\.\|\\/
+\ display
+hi def link moonExtendedOp moonOperator
+hi def link moonOperator Operator
+
+syntax match moonFunction /->\|=>\|)\|(\|\[\|]\|{\|}\|!/
+highlight default link moonFunction Function
+
+" This is separate from `moonExtendedOp` to help differentiate commas from
+" dots.
+syn match moonSpecialOp /[,;]/ display
+hi def link moonSpecialOp SpecialChar
+
+syn match moonBoolean /\<\%(true\|false\)\>/ display
+hi def link moonBoolean Boolean
+
+syn match moonGlobal /\<\%(nil\)\>/ display
+hi def link moonGlobal Type
+
+" A special variable
+syn match moonSpecialVar /\<\%(self\)\>/ display
+" An @-variable
+syn match moonSpecialVar /@\%(\I\i*\)\?/ display
+hi def link moonSpecialVar Structure
+
+" A class-like name that starts with a capital letter
+syn match moonObject /\<\u\w*\>/ display
+hi def link moonObject Structure
+
+" A constant-like name in SCREAMING_CAPS
+syn match moonConstant /\<\u[A-Z0-9_]\+\>/ display
+hi def link moonConstant Constant
+
+" A variable name
+syn cluster moonIdentifier contains=moonSpecialVar,moonObject,
+\ moonConstant
+
+" A non-interpolated string
+syn cluster moonBasicString contains=@Spell,moonEscape
+" An interpolated string
+syn cluster moonInterpString contains=@moonBasicString,moonInterp
+
+" Regular strings
+syn region moonString start=/"/ skip=/\\\\\|\\"/ end=/"/
+\ contains=@moonInterpString
+syn region moonString start=/'/ skip=/\\\\\|\\'/ end=/'/
+\ contains=@moonBasicString
+hi def link moonString String
+
+syn region moonString2 matchgroup=moonString start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell
+hi def link moonString2 String
+
+
+" A integer, including a leading plus or minus
+syn match moonNumber /\i\@<![-+]\?\d\+\%([eE][+-]\?\d\+\)\?/ display
+" A hex number
+syn match moonNumber /\<0[xX]\x\+\>/ display
+hi def link moonNumber Number
+
+" A floating-point number, including a leading plus or minus
+syn match moonFloat /\i\@<![-+]\?\d*\.\@<!\.\d\+\%([eE][+-]\?\d\+\)\?/
+\ display
+hi def link moonFloat Float
+
+" An error for reserved keywords
+if !exists("moon_no_reserved_words_error")
+ syn match moonReservedError /\<\%(end\|function\|repeat\)\>/
+ \ display
+ hi def link moonReservedError Error
+endif
+
+" This is separate from `moonExtendedOp` since assignments require it.
+syn match moonAssignOp /:/ contained display
+hi def link moonAssignOp moonOperator
+
+" Strings used in string assignments, which can't have interpolations
+syn region moonAssignString start=/"/ skip=/\\\\\|\\"/ end=/"/ contained
+\ contains=@moonBasicString
+syn region moonAssignString start=/'/ skip=/\\\\\|\\'/ end=/'/ contained
+\ contains=@moonBasicString
+hi def link moonAssignString String
+
+" A normal object assignment
+syn match moonObjAssign /@\?\I\i*\s*:\@<!::\@!/
+\ contains=@moonIdentifier,moonAssignOp
+hi def link moonObjAssign Identifier
+
+" Short hand table literal assign
+syn match moonShortHandAssign /:\@<!:@\?\I\i*\s*/
+\ contains=@moonIdentifier,moonAssignOp
+hi def link moonShortHandAssign Identifier
+
+" An object-string assignment
+syn match moonObjStringAssign /\("\|'\)[^\1]*\1\s*;\@<!::\@!'\@!/
+\ contains=moonAssignString,moonAssignOp
+" An object-integer assignment
+syn match moonObjNumberAssign /\d\+\%(\.\d\+\)\?\s*:\@<!::\@!/
+\ contains=moonNumber,moonAssignOp
+
+syn keyword moonTodo TODO FIXME XXX contained
+hi def link moonTodo Todo
+
+syn match moonComment "\%^#!.*"
+syn match moonComment /--.*/ contains=@Spell,moonTodo
+hi def link moonComment Comment
+
+" syn region moonBlockComment start=/####\@!/ end=/###/
+" \ contains=@Spell,moonTodo
+" hi def link moonBlockComment moonComment
+
+syn region moonInterp matchgroup=moonInterpDelim start=/#{/ end=/}/ contained
+\ contains=@moonAll
+hi def link moonInterpDelim PreProc
+
+" A string escape sequence
+syn match moonEscape /\\\d\d\d\|\\x\x\{2\}\|\\u\x\{4\}\|\\./ contained display
+hi def link moonEscape SpecialChar
+
+" Heredoc strings
+" syn region moonHeredoc start=/"""/ end=/"""/ contains=@moonInterpString
+" \ fold
+" syn region moonHeredoc start=/'''/ end=/'''/ contains=@moonBasicString
+" \ fold
+" hi def link moonHeredoc String
+
+" An error for trailing whitespace, as long as the line isn't just whitespace
+if !exists("moon_no_trailing_space_error")
+ syn match moonSpaceError /\S\@<=\s\+$/ display
+ hi def link moonSpaceError Error
+endif
+
+" An error for trailing semicolons, for help transitioning from JavaScript
+if !exists("moon_no_trailing_semicolon_error")
+ syn match moonSemicolonError /;$/ display
+ hi def link moonSemicolonError Error
+endif
+
+" Ignore reserved words in dot accesses.
+syn match moonDotAccess /\.\@<!\.\s*\I\i*/he=s+1 contains=@moonIdentifier
+hi def link moonDotAccess moonExtendedOp
+
+" This is required for interpolations to work.
+syn region moonCurlies matchgroup=moonCurly start=/{/ end=/}/
+\ contains=@moonAll contained
+
+" " These are highlighted the same as commas since they tend to go together.
+" hi def link moonBlock moonSpecialOp
+" hi def link moonBracket moonBlock
+" hi def link moonCurly moonBlock
+" hi def link moonParen moonBlock
+
+" This is used instead of TOP to keep things moon-specific for good
+" embedding. `contained` groups aren't included.
+syn cluster moonAll contains=moonStatement,moonRepeat,moonConditional,
+\ moonKeyword,moonOperator,moonFunction,
+\ moonExtendedOp,moonSpecialOp,moonBoolean,
+\ moonGlobal,moonSpecialVar,moonObject,
+\ moonConstant,moonString,moonNumber,
+\ moonFloat,moonReservedError,moonObjAssign,
+\ moonObjStringAssign,moonObjNumberAssign,
+\ moonShortHandAssign,moonComment,moonLuaFunc,
+\ moonSpaceError,moonSemicolonError,
+\ moonDotAccess,
+\ moonCurlies
+
+if !exists('b:current_syntax')
+ let b:current_syntax = 'moon'
+endif
+
+endif