if exists("b:current_syntax") finish endif if !has("lambda") echoerr "vim-teal: Teal syntax requires lambda support, please update your vim installation" finish endif let s:cpo_save = &cpo set cpo&vim syn case match syn sync fromstart syn cluster tealBase contains= \ tealComment,tealLongComment, \ tealConstant,tealNumber,tealString,tealLongString syn cluster tealExpression contains= \ @tealBase,tealParen,tealBuiltin,tealBracket,tealBrace, \ tealOperator,tealFunctionBlock,tealFunctionCall,tealError, \ tealTableConstructor,tealRecordBlock,tealEnumBlock,tealSelf, \ tealVarargs syn cluster tealStatement contains= \ @tealExpression,tealIfThen,tealThenEnd,tealBlock,tealLoop, \ tealRepeatBlock,tealWhileDo,tealForDo, \ tealGoto,tealLabel,tealBreak,tealReturn, \ tealLocal,tealGlobal " {{{ ), ], end, etc error syn match tealError "\()\|}\|\]\)" syn match tealError "\<\%(end\|else\|elseif\|until\|in\)\>" syn match tealInvalid /\S\+/ contained " }}} " {{{ Table Constructor syn region tealTableConstructor \ matchgroup=tealTable \ start=/{/ end=/}/ \ contains=@tealExpression,tealTableEntryTypeAnnotation syn match tealTableEntryTypeAnnotation /:.\{-}\ze=/ contained \ contains=@tealSingleType " }}} " {{{ Types " Programmatically generate type definitions for single types and type lists syn match tealUnion /|/ contained nextgroup=@tealType skipwhite skipempty skipnl syn match tealSingleUnion /|/ contained nextgroup=@tealSingleType skipwhite skipempty skipnl syn match tealTypeComma /,/ contained nextgroup=@tealType skipwhite skipempty skipnl syn match tealSingleTypeAnnotation /:/ contained nextgroup=@tealSingleType skipwhite skipempty skipnl syn match tealTypeAnnotation /:/ contained nextgroup=@tealType skipwhite skipempty skipnl syn match tealGeneric /\K\k*/ contained " {{{ Patterns let s:typePatterns = { \ 'tealFunctionType': { \ 'synType': 'match', \ 'patt': '\', \ 'nextgroup': ['tealFunctionGenericType', 'tealFunctionArgsType'], \ }, \ 'tealBasicType': { \ 'synType': 'match', \ 'patt': '\K\k*\(\.\K\k*\)*', \ 'nextgroup': ['tealGenericType'], \ }, \ 'tealFunctionGenericType': { \ 'synType': 'region', \ 'start': '<', \ 'end': '>', \ 'matchgroup': 'tealParens', \ 'nextgroup': ['tealFunctionArgsType'], \ 'contains': ['tealGeneric'], \ }, \ 'tealGenericType': { \ 'synType': 'region', \ 'start': '<', \ 'end': '>', \ 'matchgroup': 'tealParens', \ 'contains': ['tealGeneric'], \ }, \ 'tealFunctionArgsType': { \ 'synType': 'region', \ 'start': '(', \ 'end': ')', \ 'matchgroup': 'tealParens', \ 'contains': ['@tealType'], \ 'nextgroup': ['tealTypeAnnotation'], \ 'dontsub': 1, \ }, \ 'tealTableType': { \ 'synType': 'region', \ 'start': '{', \ 'end': '}', \ 'matchgroup': 'tealTable', \ 'contains': ['@tealType'], \ }, \ } " }}} " Add nextgroup=tealUnion,tealTypeComma and " make a second syntax item with nextgroup=tealSingleUnion " the effect of this is that we have @tealType, which is a type list " and @tealSingleType for function arguments " {{{ ToSingleName function s:ToSingleName(str) return substitute(a:str, 'Type', 'SingleType', '') endfunction " }}} " {{{ MakeSyntaxItem function s:MakeSyntaxItem(typeName, props) if exists("a:props.contains") let a:props.contains += ['tealLongComment'] endif for single in [v:true, v:false] let tname = a:typeName if single let tname = s:ToSingleName(tname) endif let cmd = 'syntax ' let cmd .= a:props.synType let cmd .= ' ' let cmd .= tname let cmd .= ' ' if a:props.synType == 'region' if exists("a:props.matchgroup") let cmd .= 'matchgroup=' . a:props.matchgroup endif let cmd .= ' start=+' . a:props.start . '+ end=+' . a:props.end else let cmd .= '+' . a:props.patt endif let cmd .= '+ ' let cmd .= 'contained ' if exists("a:props.contains") let cmd .= 'contains=' . join(a:props.contains, ",") . ' ' endif let cmd .= 'nextgroup=' if exists("a:props.nextgroup") let nextgroup = copy(a:props.nextgroup) else let nextgroup = [] endif call map(nextgroup, {-> (single && v:val =~# "Type" && !exists("a:props.dontsub")) ? s:ToSingleName(v:val) : v:val}) if single let nextgroup += ['tealSingleUnion'] else let nextgroup += ['tealUnion', 'tealTypeComma'] endif let cmd .= join(nextgroup, ',') let cmd .= ' skipwhite skipempty skipnl' exec cmd exec "syn cluster teal" . (single ? "Single" : "") . "Type add=" . tname endfor exec "highlight link " . s:ToSingleName(tname) . " " . tname endfunction " }}} call map(s:typePatterns, {tname, props -> s:MakeSyntaxItem(tname, props)}) syn cluster tealNewType contains=tealRecordBlock,tealEnumBlock " }}} " {{{ Function call syn match tealFunctionCall /\K\k*\ze\s*\n*\s*\(["'({]\|\[=*\[\)/ " }}} " {{{ Operators " Symbols syn match tealOperator "[#<>=~^&|*/%+-]\|\.\." " Words syn keyword tealOperator and or not syn keyword tealOperator is as \ nextgroup=@tealSingleType \ skipempty skipnl skipwhite syn match tealVarargs /\.\.\./ " }}} " {{{ Comments syn match tealComment "\%^#!.*$" syn match tealComment /--.*$/ contains=tealTodo,@Spell syn keyword tealTodo contained TODO todo FIXME fixme TBD tbd XXX syn region tealLongComment start=/--\[\z(=*\)\[/ end=/\]\z1\]/ " }}} " {{{ local ... , global ... , local type ..., break, return, self syn keyword tealTypeDeclaration type contained \ nextgroup=tealTypeDeclarationName \ skipwhite skipempty skipnl syn match tealTypeDeclarationName /\K\k*/ contained \ nextgroup=tealTypeDeclarationEq,tealInvalid \ skipwhite skipempty skipnl syn match tealTypeDeclarationEq /=/ contained \ nextgroup=@tealSingleType,tealRecordBlock,tealEnumBlock \ skipwhite skipempty skipnl syn region tealAttributeBrackets contained transparent \ matchgroup=tealParens \ start=// \ contains=tealAttribute \ nextgroup=tealVarComma,tealTypeAnnotation \ skipwhite skipempty skipnl syn match tealAttribute contained /\K\k*/ syn match tealVarName contained /\K\k*/ \ nextgroup=tealAttributeBrackets,tealVarComma,tealTypeAnnotation \ skipwhite skipempty skipnl syn match tealVarComma /,/ contained \ nextgroup=tealVarName \ skipwhite skipempty skipnl syn keyword tealLocal local \ nextgroup=tealFunctionBlock,tealRecordBlock,tealEnumBlock,tealVarName,tealTypeDeclaration \ skipwhite skipempty skipnl syn keyword tealGlobal global \ nextgroup=tealFunctionBlock,tealRecordBlock,tealEnumBlock,tealVarName,tealTypeDeclaration \ skipwhite skipempty skipnl syn keyword tealBreak break syn keyword tealReturn return syn keyword tealSelf self " }}} " {{{ Parens syn region tealParen transparent \ matchgroup=tealParens \ start=/(/ end=/)/ \ contains=@tealExpression syn region tealBracket transparent \ matchgroup=tealBrackets \ start=/\[/ end=/\]/ \ contains=@tealExpression " }}} " {{{ function ... end syn region tealFunctionBlock transparent \ matchgroup=tealFunction \ start=/\/ end=/\/ \ contains=@tealStatement,tealFunctionStart syn match tealFunctionStart /\(\\)\@8<=\s*/ contained \ nextgroup=tealFunctionName,tealFunctionGeneric,tealFunctionArgs \ skipwhite skipempty skipnl syn match tealFunctionName /\K\k*\(\.\K\k*\)*\(:\K\k*\)\?/ contained \ nextgroup=tealFunctionGeneric,tealFunctionArgs,tealInvalid \ skipwhite skipempty skipnl syn region tealFunctionGeneric contained transparent \ start=// \ contains=tealGeneric \ nextgroup=tealFunctionArgs \ skipwhite skipempty skipnl syn region tealFunctionArgs contained transparent \ matchgroup=tealParens \ start=/(/ end=/)/ \ contains=tealFunctionArgName,tealFunctionArgComma,tealSingleTypeAnnotation \ nextgroup=tealTypeAnnotation \ skipwhite skipempty skipnl syn match tealFunctionArgName contained /\K\k*/ \ nextgroup=tealSingleTypeAnnotation,tealFunctionArgComma,tealInvalid \ skipwhite skipempty skipnl syn match tealFunctionArgComma contained /,/ \ nextgroup=tealFunctionArgName \ skipwhite skipempty skipnl " }}} " {{{ record ... end syn match tealRecordType /\K\k*/ contained \ nextgroup=tealRecordAssign,tealInvalid \ skipwhite skipnl skipempty syn match tealRecordEntry /\K\k*/ contained \ nextgroup=tealSingleTypeAnnotation,tealInvalid \ skipwhite skipnl skipempty syn match tealRecordEntry /\[.*\]/ contained \ nextgroup=tealSingleTypeAnnotation,tealInvalid \ contains=tealString,tealLongString \ skipwhite skipnl skipempty \ transparent syn cluster tealRecordItem contains=tealRecordEntry syn region tealRecordBlock contained \ matchgroup=tealRecord transparent \ start=/\/ end=/\/ \ contains=tealRecordKeywordName,tealRecordStart,@tealRecordItem,tealTableType,tealComment,tealLongComment syn cluster tealRecordItem add=tealRecordBlock,tealEnumBlock syn match tealRecordStart /\(\\)\@6<=\s*/ contained \ nextgroup=tealRecordName,tealRecordGeneric \ skipwhite skipnl skipempty syn match tealRecordName /\K\k*/ contained \ nextgroup=tealRecordGeneric \ skipwhite skipnl skipempty syn region tealRecordGeneric contained transparent \ matchgroup=tealParens \ start=// \ contains=tealGeneric syn keyword tealRecordUserdata userdata contained \ nextgroup=@tealRecordItem \ skipwhite skipnl skipempty syn match tealRecordTypeDeclaration /type\s*\K\k*\s*=/ contained \ contains=tealRecordTypeKeyword,tealOperator \ nextgroup=@tealSingleType,@tealNewType,tealInvalid \ skipwhite skipnl skipempty syn keyword tealRecordMetamethodKeyword metamethod contained syn match tealRecordMetamethod /metamethod\s\+\K\k*/ contained \ contains=tealRecordMetamethodKeyword \ nextgroup=tealSingleTypeAnnotation \ skipwhite skipnl skipempty syn keyword tealRecordTypeKeyword type contained syn cluster tealRecordItem \ add=tealRecordTypeDeclaration,tealRecordUserdata,tealRecordMetamethod " }}} " {{{ enum ... end syn match tealEnumStart /\(\\)\@4<=\s*/ contained \ nextgroup=tealEnumName \ skipwhite skipnl skipempty syn match tealEnumName /\K\k*/ contained syn region tealEnumBlock \ matchgroup=tealEnum transparent \ start="\" end="\" \ contains=tealEnumStart,tealString,tealLongString,tealComment,tealLongComment,tealInvalid " }}} " {{{ record entries with names 'enum' and 'record' syn match tealRecordKeywordName /\(enum\|record\)\s*\ze:/ contained \ contains=tealRecordItem \ nextgroup=tealSingleTypeAnnotation,tealInvalid \ skipwhite skipnl skipempty " }}} " {{{ if ... then, elseif ... then, then ... end, else syn keyword tealError then syn region tealIfThen \ transparent matchgroup=tealIfStatement \ start=/\/ end=/\/me=e-4 \ contains=@tealExpression \ nextgroup=tealThenEnd \ skipwhite skipnl skipempty syn region tealElseifThen contained \ transparent matchgroup=tealIfStatement \ start=/\/ end=/\/ \ contains=@tealExpression syn region tealThenEnd \ transparent matchgroup=tealIfStatement \ start=/\/ end=/\/ \ contains=tealElseifThen,tealElse,@tealStatement syn keyword tealElse else contained containedin=tealThenEnd " }}} " {{{ for ... do ... end, in syn region tealForDo \ matchgroup=tealFor transparent \ contains=tealIn,@tealExpression \ start=/\/ end=/\/me=e-2 syn keyword tealIn in contained " }}} " {{{ while ... do ... end syn region tealWhileDo \ matchgroup=tealWhile transparent \ contains=@tealExpression \ start=/\/ end=/\/me=e-2 " }}} " {{{ do ... end syn region tealBlock \ matchgroup=tealDoEnd transparent \ contains=@tealStatement \ start=/\/ end=/\/ " }}} " {{{ repeat ... until syn region tealRepeatBlock \ matchgroup=tealRepeatUntil transparent \ contains=@tealStatement \ start=/\/ end=/\/ " }}} " {{{ Goto syn keyword tealGoto goto syn match tealLabel /::\K\k*::/ " }}} " {{{ true, false, nil, etc... syn keyword tealConstant nil true false " }}} " {{{ Strings syn match tealSpecial contained #\\[\\abfnrtvz'"]\|\\x[[:xdigit:]]\{2}\|\\[[:digit:]]\{,3}# syn region tealLongString matchgroup=tealString start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell syn region tealString start=+'+ end=+'\|$+ skip=+\\\\\|\\'+ contains=tealSpecial,@Spell syn region tealString start=+"+ end=+"\|$+ skip=+\\\\\|\\"+ contains=tealSpecial,@Spell " }}} " {{{ Numbers " integer number syn match tealNumber "\<\d\+\>" " floating point number, with dot, optional exponent syn match tealNumber "\<\d\+\.\d*\%([eE][-+]\=\d\+\)\=\>" " floating point number, starting with a dot, optional exponent syn match tealNumber "\.\d\+\%([eE][-+]\=\d\+\)\=\>" " floating point number, without dot, with exponent syn match tealNumber "\<\d\+[eE][-+]\=\d\+\>" " hex numbers syn match tealNumber "\<0[xX][[:xdigit:].]\+\%([pP][-+]\=\d\+\)\=\>" " }}} " {{{ Built ins syn keyword tealBuiltIn assert error collectgarbage \ print tonumber tostring type \ getmetatable setmetatable \ ipairs pairs next \ pcall xpcall \ _G _ENV _VERSION require \ rawequal rawget rawset rawlen \ loadfile load dofile select syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ syn match tealBuiltIn /\/ " }}} " {{{ Highlight hi def link tealTypeDeclaration StorageClass hi def link tealKeyword Keyword hi def link tealFunction Keyword hi def link tealFunctionName Function hi def link tealFunctionArgName Identifier hi def link tealLocal Keyword hi def link tealGlobal Keyword hi def link tealBreak Keyword hi def link tealReturn Keyword hi def link tealIn Keyword hi def link tealSelf Special hi def link tealTable Structure hi def link tealBasicType Type hi def link tealFunctionType Type hi def link tealAttribute StorageClass hi def link tealParens Normal hi def link tealRecord Keyword hi def link tealEnum Keyword hi def link tealIfStatement Conditional hi def link tealElse Conditional hi def link tealFor Repeat hi def link tealWhile Repeat hi def link tealDoEnd Keyword hi def link tealRepeatUntil Repeat hi def link tealFunctionCall Function hi def link tealGoto Keyword hi def link tealLabel Label hi def link tealString String hi def link tealLongString String hi def link tealSpecial Special hi def link tealComment Comment hi def link tealLongComment Comment hi def link tealConstant Constant hi def link tealNumber Number hi def link tealOperator Operator hi def link tealBuiltin Identifier hi def link tealError Error hi def link tealInvalid Error hi def link tealGeneric Type hi def link tealTodo Todo hi def link tealRecordName tealBasicType hi def link tealRecordType tealBasicType hi def link tealRecordTypeKeyword tealKeyword hi def link tealRecordAssign tealOperator hi def link tealEnumName tealBasicType hi def link tealTypeDeclarationEq tealOperator hi def link tealTypeDeclarationName tealBasicType hi def link tealRecordUserdata Keyword hi def link tealRecordMetamethodKeyword Keyword " }}} let b:current_syntax = "teal" let &cpo = s:cpo_save unlet s:cpo_save