" See the License for the specific language governing permissions and
" limitations under the License.
-if exists("b:current_syntax")
- finish
+if !exists("main_syntax")
+ if version < 600
+ syntax clear
+ elseif exists("b:current_syntax")
+ finish
+ endif
+ " we define it here so that included files can test for it
+ let main_syntax='nit'
endif
" Expression Substitution and Backslash Notation
+syn match NITExprSubstError "{\|}" contained
syn match NITExprSubst "\\." contained
-syn match NITExprSubst "{[^}]*}" contained
+syn match NITExprSubst "{\([^}]\|\n\)*}" contained
-" Numbers and ASCII Codes
-syn match NITNumber "\<\(\d\+\.\d\+\|\d\+\)\>"
+syn match NITExprSubstLong "\\." contained
+syn match NITExprSubstLong "{*\zs{{{\([^}]\|\n\)*}}}\ze}*" contained
+
+" Numbers
+syn match NITNumber "\<\([0-9_]\+\|0[bB][01_]\+\|0[oO][0-7_]\+\|0[xX][0-9a-fA-F_]\+\)\([iu]\(8\|16\|32\)\)\?\>"
+syn match NITNumber "\<[0-9_]\+\.[0-9_]\+\>"
" Identifiers
-syn match NITClass "\u\w*"
+syn match NITClass "\<\u\w*"
syn match NITAttribute "\<_\h\w*"
" Literal strings
-syn region NITString matchgroup=NITStringDelimit start="\"" end="\"" skip="\\\\\|\\\"" contains=NITExprSubst
+syn region NITString matchgroup=NITStringDelimit start="\"" end="\"" skip="\\\\\|\\\"" contains=NITExprSubst,NITExprSubstError,@Spell
+syn region NITString matchgroup=NITStringDelimit start="\"\"\"" end="\"*\zs\"\"\"" skip="\\\\\|\\\"" contains=NITExprSubstLong,@Spell
syn region NITString matchgroup=NITStringDelimit start="'" end="'" skip="\\\\\|\\'"
+" Labels
+syn match NITLabel "\<label \h\w*"
+
+" Closures
+syn match NITClosure "!\h\w*"
" Fallback highlight keywords
-syn match NITBoolean "\<\(null\)\>"
-syn match NITControl "\<\(init\|end\|not null\|not\|var\|do\|then\|else\|with\)\>"
+syn match NITNull "\<\(null\)\>"
+syn match NITControl "\<\(init\|end\|not null\|not\|var\|do\|then\|else\|loop\|is\)\>"
+syn match NITKeyword "\<\(super\)\>"
" Unmatchning error
syn match Error "\<end\>"
" Declarations, definitions and blocks
-syn region NITPackageDecl matchgroup=NITDefine start="\<\(import\|package\)\>\s*" matchgroup=NONE end="\ze\(\s\|:\|(\|$\)" oneline
-syn region NITClassBlock matchgroup=NITDefine start="\<\(class\|universal\|interface\)\>" matchgroup=NITDefine end="\<end\>" contains=ALL fold
-syn region NITFunctionDecl matchgroup=NITDefine start="\<\(meth\|fun\)\>\s*" matchgroup=NONE end="\ze\(\<do\>\|\s\|:\|(\|$\)" oneline
+syn region NITModuleDecl matchgroup=NITDefine start="\<\(import\|module\|package\)\>\s*" matchgroup=NONE end="\ze\(\s\|:\|(\|$\)" oneline
+syn region NITClassBlock matchgroup=NITDefine start="\<\(class\|enum\|universal\|interface\|extern\)\>" matchgroup=NITDefine end="\<end\>" contains=ALLBUT,NITAnnotLine fold
+syn region NITFunctionDecl matchgroup=NITDefine start="\<fun\>\s*" matchgroup=NONE end="\ze\(\<do\>\|\s\|:\|(\|$\)" oneline
syn region NITTypeDecl matchgroup=NITDefine start="\<type\>\s*" matchgroup=NONE end="\ze\(\<do\>\|\s\|:\|(\|$\)" oneline contained containedin=NITClassBlock
-syn region NITAttrDecl matchgroup=NITDefine start="\<\(var\|attr\)\>\s*\ze_" matchgroup=NONE end="\ze\(\<do\>\|\s\|:\|(\|$\)" oneline contained containedin=NITClassBlock
+syn region NITAttrDecl matchgroup=NITDefine start="\<var\>\s*" matchgroup=NONE end="\ze\(\<do\>\|\s\|:\|(\|$\)" oneline contained containedin=NITClassBlock
syn region NITInitDecl matchgroup=NITDefine start="\<init\>\s*" matchgroup=NONE end="\ze\(\<do\>\|\s\|:\|(\|$\)" oneline contained containedin=NITClassBlock
+syn match NITDefine "\<\(super\)\ze\s\+[A-Z]" contained containedin=NITClassBlock
-syn region NITStmtBlock matchgroup=NITControl start="\<\(do\|then\|else\)\>\ze\s*\(#\|$\)" matchgroup=NITControl end="^\s*\<\(end\|\zeelse\|with\)\>" contains=ALLBUT,NITTypeDecl,NITAttrDecl,NITInitDecl
-syn region NITStmtBlock matchgroup=NITControl start="\<\(do\|then\|else\)\>" matchgroup=NITControl end="\<end\>" oneline
+syn region NITAnnotBlock matchgroup=NITControl start="\<is\>\ze\s*\(#\|$\)" matchgroup=NITControl end="\(\ze\<do\>\|\<end\>\)" transparent contains=ALL
+syn match NITAnnotLine "^\s*\zs\w\+" contained containedin=NITAnnotBlock
+syn region NITStmtBlock matchgroup=NITControl start="\<\(do\|then\|else\|loop\)\>\ze\s*\(#\|$\)" matchgroup=NITControl end="^\s*\<\(end\|\zeelse\|\ze!\)\>" contains=ALLBUT,NITTypeDecl,NITAttrDecl,NITInitDecl,NITAnnotLine
+syn region NITStmtBlock matchgroup=NITControl start="\<\(do\|then\|else\|loop\)\>" matchgroup=NITControl end="\<end\>" oneline
if !exists("NIT_minlines")
let NIT_minlines = 50
endif
" Comments and Documentation
syn match NITSharpBang "\%^#!.*"
-syn match NITComment "#.*" contains=NITTodo
+syn match NITComment "#.*" contains=NITTodo,@Spell
" Keywords
-syn keyword NITKeyword is abstract intern extern
+syn keyword NITKeyword abstract intern new
syn keyword NITDefine private public protected intrude readable writable redef
-syn keyword NITControl if while for assert
-syn keyword NITControl and or in as isa
-syn keyword NITControl break continue return label abort
-syn keyword NITKeyword super new nullable
+syn keyword NITControl if while for assert and or in as isa once break continue return abort
+syn keyword NITClass nullable
syn keyword NITInclude special
syn keyword NITTodo FIXME NOTE TODO XXX contained
-syn keyword NITBoolean true false self
+syn keyword NITBoolean true false
+syn keyword NITSelf self
" Define the default highlighting.
hi def link NITDefine Define
-hi def link NITPackageDecl Identifier
+hi def link NITModuleDecl Identifier
hi def link NITFunctionDecl Function
hi def link NITTypeDecl Function
hi def link NITAttrDecl Function
hi def link NITInitDecl Function
hi def link NITControl Statement
+hi def link NITAnnotLine Statement
+hi def link NITLabel PreProc
hi def link NITInclude Include
hi def link NITNumber Number
hi def link NITBoolean Boolean
+hi def link NITNull Constant
+hi def link NITSelf Constant
hi def link NITClass Type
hi def link NITAttribute Identifier
+hi def link NITClosure Function
hi def link NITSharpBang PreProc
hi def link NITKeyword Keyword
hi def link NITString String
hi def link NITStringDelimit Delimiter
hi def link NITExprSubst Special
+hi def link NITExprSubstLong Special
+hi def link NITExprSubstError Error
hi def link NITComment Comment
hi def link NITTodo Todo
+" FFI Section
+syn match NITFFIDelimiters "\<\(`{\|`}\)\>"
+hi def link NITFFIDelimiters Keyword
+
+" FFI Python
+syntax include @FFIPython syntax/python.vim
+unlet b:current_syntax
+syn match NITFFILanguage /\c"Python"\ze.*`{/ nextgroup=NITFFIBlockPython skipwhite
+syn region NITFFIBlockPython matchgroup=NITFFI start='`{' matchgroup=NITFFI end='`}' keepend fold contains=@FFIPython
+
+" FFI Java
+syntax include @FFIJava syntax/java.vim
+unlet b:current_syntax
+syn match NITFFILanguage /\c"Java\(\| inner\)"\ze.*`{/ nextgroup=NITFFIBlockJava skipwhite
+syn region NITFFIBlockJava matchgroup=NITFFI start='`{' matchgroup=NITFFI end='`}' keepend fold contains=@FFIJava
+
+" FFI C++
+syntax include @FFICpp syntax/cpp.vim
+unlet b:current_syntax
+syn match NITFFILanguage /\c"C++\(\| header\| body\)"\ze.*`{/ nextgroup=NITFFIBlockCpp skipwhite
+syn region NITFFIBlockCpp matchgroup=NITFFI start='`{' matchgroup=NITFFI end='`}' keepend fold contains=@FFICpp
+
+" FFI Objective-C
+syntax include @FFIObjC syntax/objc.vim
+unlet b:current_syntax
+syn match NITFFILanguage /\c"ObjC\(\| Header\| Body\)"\ze.*`{/ nextgroup=NITFFIBlockObjC skipwhite
+syn region NITFFIBlockObjC matchgroup=NITFFI start='`{' matchgroup=NITFFI end='`}' keepend fold contains=@FFIObjC
+
+" FFI C (the last one is the default)
+syntax include @FFIC syntax/c.vim
+unlet b:current_syntax
+syn match NITFFILanguage /\c"C\(\| header\| body\)"\ze.*`{/ nextgroup=NITFFIBlockC skipwhite
+syn region NITFFIBlockC matchgroup=NITFFI start='`{' matchgroup=NITFFI end='`}' keepend fold contains=@FFIC
+
+hi def link NITFFILanguage Define
+
let b:current_syntax = "Nit"