├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── ale_linters └── teal │ └── tlcheck.vim ├── compiler └── tl.vim ├── ftdetect └── teal.vim ├── ftplugin └── teal.vim ├── indent └── teal.vim ├── plugin └── teal.vim └── syntax └── teal.vim /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at hisham@gobolinux.org. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2020 Patrick Desaulniers 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-teal 2 | 3 | This plugin provides [Teal](https://github.com/teal-language/tl) language support for Vim. 4 | 5 | ## Features 6 | 7 | - Syntax highlighting 8 | - Automatic indentation 9 | - Linting (requires [ALE](https://github.com/dense-analysis/ale)) 10 | - Automatic insertion of `end` tokens (requires [vim-endwise](https://github.com/tpope/vim-endwise)) 11 | - `:compiler` support 12 | 13 | ## Install 14 | Using [vim-plug](https://github.com/junegunn/vim-plug): 15 | ```vim 16 | " Teal language support 17 | Plug 'teal-language/vim-teal' 18 | 19 | " Optional dependencies; will be loaded on-demand when editing Teal files 20 | Plug 'dense-analysis/ale', { 'for': 'teal' } 21 | Plug 'tpope/vim-endwise', { 'for': 'teal' } 22 | ``` 23 | 24 | You should also make sure that the Teal compiler [is available in your PATH:](https://github.com/teal-language/tl#installing) 25 | ``` 26 | luarocks install tl 27 | ``` 28 | 29 | ## Contributors 30 | 31 | Contributions are greatly appreciated! Feel free to fork [this repository](https://github.com/teal-language/vim-teal) and open a pull request on GitHub. 32 | -------------------------------------------------------------------------------- /ale_linters/teal/tlcheck.vim: -------------------------------------------------------------------------------- 1 | " Description: Teal linter based on `tl check` 2 | 3 | " Based on https://github.com/dense-analysis/ale/blob/master/ale_linters/lua/luacheck.vim 4 | 5 | call ale#Set('teal_tlcheck_executable', 'tl') 6 | call ale#Set('teal_tlcheck_options', '') 7 | 8 | function! ale_linters#teal#tlcheck#GetCommand(buffer) abort 9 | return '%e' . ale#Pad(ale#Var(a:buffer, 'teal_tlcheck_options')) 10 | \ . ' check %s' 11 | endfunction 12 | 13 | function! ale_linters#teal#tlcheck#Handle(buffer, lines) abort 14 | " Matches patterns line the following: 15 | " 16 | " artal.tl:159:17: shadowing definition of loop variable 'i' on line 106 17 | " artal.tl:182:7: unused loop variable 'i' 18 | let l:pattern = '^\(.\{-}\):\(\d\+\):\(\d\+\): \(.\+\)$' 19 | let l:output = [] 20 | 21 | for l:match in ale#util#GetMatches(a:lines, l:pattern) 22 | call add(l:output, { 23 | \ 'filename': l:match[1], 24 | \ 'lnum': l:match[2] + 0, 25 | \ 'col': l:match[3] + 0, 26 | \ 'text': l:match[4], 27 | \}) 28 | endfor 29 | 30 | return l:output 31 | endfunction 32 | 33 | call ale#linter#Define('teal', { 34 | \ 'name': 'tlcheck', 35 | \ 'executable': {b -> ale#Var(b, 'teal_tlcheck_executable')}, 36 | \ 'command': function('ale_linters#teal#tlcheck#GetCommand'), 37 | \ 'callback': 'ale_linters#teal#tlcheck#Handle', 38 | \ 'output_stream': 'both' 39 | \}) 40 | -------------------------------------------------------------------------------- /compiler/tl.vim: -------------------------------------------------------------------------------- 1 | 2 | if exists("current_compiler") 3 | finish 4 | endif 5 | let current_compiler = "tl" 6 | 7 | let s:cpo_save = &cpo 8 | set cpo&vim 9 | 10 | if exists("g:teal_check_only") 11 | CompilerSet makeprg=tl\ -q\ check\ % 12 | elseif exists("g:teal_check_before_gen") 13 | CompilerSet makeprg=tl\ -q\ check\ %\ &&\ tl\ -q\ gen\ % 14 | else 15 | CompilerSet makeprg=tl\ -q\ gen\ % 16 | endif 17 | CompilerSet errorformat=%f:%l:%c:\ %m 18 | 19 | let &cpo = s:cpo_save 20 | unlet s:cpo_save 21 | -------------------------------------------------------------------------------- /ftdetect/teal.vim: -------------------------------------------------------------------------------- 1 | fun! s:DetectTL() 2 | if getline(1) =~# '^#!.*/bin/env\s\+tl\>' 3 | setfiletype teal 4 | endif 5 | endfun 6 | 7 | autocmd BufRead,BufNewFile *.tl setlocal filetype=teal 8 | autocmd BufNewFile,BufRead * call s:DetectTL() 9 | -------------------------------------------------------------------------------- /ftplugin/teal.vim: -------------------------------------------------------------------------------- 1 | if exists("b:did_ftplugin") 2 | finish 3 | endif 4 | let b:did_ftplugin = 1 5 | let s:cpo_save = &cpo 6 | 7 | setlocal comments=s:--[[,mb:\ ,ex:]],f:#,:---,:-- 8 | setlocal commentstring=--%s 9 | setlocal suffixesadd=.tl 10 | 11 | let b:undo_ftplugin = "setl com< cms< mp< sua<" 12 | 13 | let &cpo = s:cpo_save 14 | unlet s:cpo_save 15 | -------------------------------------------------------------------------------- /indent/teal.vim: -------------------------------------------------------------------------------- 1 | " Vim indent file 2 | " Language: Teal 3 | 4 | " Adapted from https://github.com/tbastos/vim-lua and the default lua file 5 | 6 | " {{{ setup 7 | if exists("b:did_indent") 8 | finish 9 | endif 10 | let b:did_indent = 1 11 | 12 | let s:cpo_save = &cpo 13 | set cpo&vim 14 | 15 | setlocal autoindent 16 | setlocal nosmartindent 17 | 18 | setlocal indentexpr=GetTealIndent(v:lnum) 19 | setlocal indentkeys+=0=end,0=until 20 | 21 | if exists("*GetTealIndent") 22 | finish 23 | endif 24 | " }}} 25 | " {{{ Patterns 26 | 27 | " [\t ] seems to be faster than \s 28 | let s:begin_block_open_patt = '\C^[\t ]*\%(if\|for\|while\|repeat\|else\|elseif\|do\|then\)\>' 29 | let s:end_block_open_patt = '\C\%((\|{\|then\|do\)[\t ]*$' 30 | let s:block_close_patt = '\C^[\t ]*\%(\%(end\|else\|elseif\|until\)\>\|}\|)\)' 31 | 32 | let s:middle_patt = '\C\<\%(function\|macroexp\|interface\|record\|enum\)\>' 33 | let s:ignore_patt = 'String$\|Comment$\|Type$' 34 | 35 | let s:starts_with_bin_op = '\C^[\t ]*\([<>=~^&|*/%+-.:]\|\%(or\|and\|is\|as\)\>\)' 36 | 37 | " }}} 38 | " {{{ Helpers 39 | function s:IsIgnorable(line_num, column) 40 | return synIDattr(synID(a:line_num, a:column, 1), 'name') =~# s:ignore_patt 41 | \ && !(getline(a:line_num) =~# '^[\t ]*\%(--\)\?\[=*\[') 42 | endfunction 43 | 44 | function s:PrevLineOfCode(line_num) 45 | let line_num = prevnonblank(a:line_num) 46 | while s:IsIgnorable(line_num, 1) 47 | let line_num = prevnonblank(line_num - 1) 48 | endwhile 49 | return line_num 50 | endfunction 51 | 52 | " strip comments 53 | function s:GetLineContent(line_num) 54 | " remove trailing -- ... 55 | let content = getline(a:line_num) 56 | return substitute(content, '--.*$', '', '') 57 | endfunction 58 | 59 | function s:MatchPatt(line_num, line_content, patt, prev_match) 60 | if a:prev_match != -1 61 | return a:prev_match 62 | endif 63 | let match_index = match(a:line_content, a:patt) 64 | if match_index != -1 && 65 | \ synIDattr(synID(a:line_num, match_index+1, 1), "name") =~# s:ignore_patt 66 | let match_index = -1 67 | endif 68 | return match_index 69 | endfunction 70 | " }}} 71 | " {{{ The Indent function 72 | function GetTealIndent(lnum) 73 | if s:IsIgnorable(a:lnum, 1) 74 | return indent(a:lnum - 1) 75 | endif 76 | let prev_line_num = s:PrevLineOfCode(a:lnum - 1) 77 | if prev_line_num == 0 78 | return 0 79 | endif 80 | 81 | let prev_line = s:GetLineContent(prev_line_num) 82 | 83 | let i = 0 84 | let match_index = s:MatchPatt(prev_line_num, prev_line, s:begin_block_open_patt, -1) 85 | let match_index = s:MatchPatt(prev_line_num, prev_line, s:end_block_open_patt, match_index) 86 | let match_index = s:MatchPatt(prev_line_num, prev_line, s:middle_patt, match_index) 87 | 88 | " If the previous line opens a block (and doesnt close it), >> 89 | if match_index != -1 && prev_line !~# '\C\<\%(end\|until\)\>' 90 | let i += 1 91 | endif 92 | 93 | " If the current line closes a block, << 94 | let curr_line = s:GetLineContent(a:lnum) 95 | let match_index = s:MatchPatt(a:lnum, curr_line, s:block_close_patt, -1) 96 | if match_index != -1 97 | let i -= 1 98 | endif 99 | 100 | " if line starts with bin op and previous line doesnt, >> 101 | let current_starts_with_bin_op = 0 102 | let prev_starts_with_bin_op = 0 103 | let match_index = s:MatchPatt(a:lnum, curr_line, s:starts_with_bin_op, -1) 104 | if match_index != -1 105 | let current_starts_with_bin_op = 1 106 | endif 107 | 108 | let match_index = s:MatchPatt(prev_line_num, prev_line, s:starts_with_bin_op, -1) 109 | if match_index != -1 110 | let prev_starts_with_bin_op = 1 111 | endif 112 | 113 | if current_starts_with_bin_op && !prev_starts_with_bin_op 114 | let i += 1 115 | elseif !current_starts_with_bin_op && prev_starts_with_bin_op 116 | let i -= 1 117 | endif 118 | 119 | if i > 1 120 | 121 | let i = 1 122 | " elseif i < -1 123 | " let i = -1 124 | 125 | endif 126 | return indent(prev_line_num) + (shiftwidth() * i) 127 | endfunction 128 | " }}} 129 | 130 | let &cpo = s:cpo_save 131 | unlet s:cpo_save 132 | -------------------------------------------------------------------------------- /plugin/teal.vim: -------------------------------------------------------------------------------- 1 | 2 | function s:LoadPlugins() 3 | if exists("g:loaded_matchit") 4 | let b:match_ignorecase = 0 5 | let b:match_words= 6 | \ '\<\%(do\|enum\|record\|function\|if\)\>:' . 7 | \ '\<\%(return\|else\|elseif\)\>:' . 8 | \ '\,' . 9 | \ '\:\' 10 | endif 11 | if exists("g:loaded_endwise") 12 | let b:endwise_addition = 'end' 13 | let b:endwise_words = 'function,do,then,enum,record' 14 | let b:endwise_pattern = '\zs\<\%(then\|do\)\|\(\%(function\|record\|enum\).*\)\ze\s*$' 15 | let b:endwise_syngroups = 'tealFunction,tealDoEnd,tealIfStatement,tealRecord,tealEnum' 16 | endif 17 | 18 | if exists("g:colors_name") && g:colors_name == "dracula" 19 | hi! link tealTable DraculaFg 20 | hi! link tealFunctionArgName DraculaOrangeItalic 21 | hi! link tealSelf DraculaPurpleItalic 22 | hi! link tealBuiltin DraculaCyan 23 | hi! link tealGeneric DraculaOrangeItalic 24 | endif 25 | endfunction 26 | 27 | autocmd FileType teal call s:LoadPlugins() 28 | -------------------------------------------------------------------------------- /syntax/teal.vim: -------------------------------------------------------------------------------- 1 | if exists("b:current_syntax") 2 | finish 3 | endif 4 | if !has("lambda") 5 | echoerr "vim-teal: Teal syntax requires lambda support, please update your vim installation" 6 | finish 7 | endif 8 | 9 | let s:cpo_save = &cpo 10 | set cpo&vim 11 | 12 | syn case match 13 | syn sync fromstart 14 | 15 | syn cluster tealBase contains= 16 | \ tealComment,tealLongComment, 17 | \ tealConstant,tealNumber,tealString,tealLongString 18 | syn cluster tealExpression contains= 19 | \ @tealBase,tealParen,tealBuiltin,tealBracket,tealBrace, 20 | \ tealOperator,tealFunctionBlock,tealFunctionCall,tealError, 21 | \ tealTableConstructor,tealInterfaceBlock,tealRecordBlock,tealEnumBlock,tealSelf, 22 | \ tealVarargs 23 | syn cluster tealStatement contains= 24 | \ @tealExpression,tealIfThen,tealThenEnd,tealBlock,tealLoop, 25 | \ tealRepeatBlock,tealWhileDo,tealForDo, 26 | \ tealGoto,tealLabel,tealBreak,tealReturn, 27 | \ tealLocal,tealGlobal 28 | 29 | " {{{ ), ], end, etc error 30 | syn match tealError "\()\|}\|\]\)" 31 | syn match tealError "\<\%(end\|else\|elseif\|until\|in\)\>" 32 | syn match tealInvalid /\S\+/ contained 33 | " }}} 34 | " {{{ Table Constructor 35 | syn region tealTableConstructor 36 | \ matchgroup=tealTable 37 | \ start=/{/ end=/}/ 38 | \ contains=@tealExpression,tealTableEntryTypeAnnotation 39 | syn match tealTableEntryTypeAnnotation /:.\{-}\ze=/ contained 40 | \ contains=@tealSingleType 41 | " }}} 42 | " {{{ Types 43 | 44 | " Programmatically generate type definitions for single types and type lists 45 | syn match tealUnion /|/ contained nextgroup=@tealType skipwhite skipempty skipnl 46 | syn match tealSingleUnion /|/ contained nextgroup=@tealSingleType skipwhite skipempty skipnl 47 | 48 | syn match tealTypeComma /,/ contained nextgroup=@tealType skipwhite skipempty skipnl 49 | syn match tealSingleTypeAnnotation /:/ contained nextgroup=@tealSingleType skipwhite skipempty skipnl 50 | syn match tealTypeAnnotation /:/ contained nextgroup=@tealType skipwhite skipempty skipnl 51 | syn match tealGeneric /\K\k*/ contained 52 | 53 | " {{{ Patterns 54 | let s:typePatterns = { 55 | \ 'tealFunctionType': { 56 | \ 'synType': 'match', 57 | \ 'patt': '\', 58 | \ 'nextgroup': ['tealFunctionGenericType', 'tealFunctionArgsType'], 59 | \ }, 60 | \ 'tealBasicType': { 61 | \ 'synType': 'match', 62 | \ 'patt': '\K\k*\(\.\K\k*\)*', 63 | \ 'nextgroup': ['tealGenericType'], 64 | \ }, 65 | \ 'tealFunctionGenericType': { 66 | \ 'synType': 'region', 67 | \ 'start': '<', 68 | \ 'end': '>', 69 | \ 'matchgroup': 'tealParens', 70 | \ 'nextgroup': ['tealFunctionArgsType'], 71 | \ 'contains': ['tealGeneric'], 72 | \ }, 73 | \ 'tealGenericType': { 74 | \ 'synType': 'region', 75 | \ 'start': '<', 76 | \ 'end': '>', 77 | \ 'matchgroup': 'tealParens', 78 | \ 'contains': ['tealGeneric'], 79 | \ }, 80 | \ 'tealFunctionArgsType': { 81 | \ 'synType': 'region', 82 | \ 'start': '(', 83 | \ 'end': ')', 84 | \ 'matchgroup': 'tealParens', 85 | \ 'contains': ['@tealType'], 86 | \ 'nextgroup': ['tealTypeAnnotation'], 87 | \ 'dontsub': 1, 88 | \ }, 89 | \ 'tealTableType': { 90 | \ 'synType': 'region', 91 | \ 'start': '{', 92 | \ 'end': '}', 93 | \ 'matchgroup': 'tealTable', 94 | \ 'contains': ['@tealType'], 95 | \ }, 96 | \ } 97 | " }}} 98 | 99 | " Add nextgroup=tealUnion,tealTypeComma and 100 | " make a second syntax item with nextgroup=tealSingleUnion 101 | " the effect of this is that we have @tealType, which is a type list 102 | " and @tealSingleType for function arguments 103 | " {{{ ToSingleName 104 | function s:ToSingleName(str) 105 | return substitute(a:str, 'Type', 'SingleType', '') 106 | endfunction 107 | " }}} 108 | " {{{ MakeSyntaxItem 109 | function s:MakeSyntaxItem(typeName, props) 110 | if exists("a:props.contains") 111 | let a:props.contains += ['tealLongComment'] 112 | endif 113 | for single in [v:true, v:false] 114 | let tname = a:typeName 115 | if single 116 | let tname = s:ToSingleName(tname) 117 | endif 118 | let cmd = 'syntax ' 119 | let cmd .= a:props.synType 120 | let cmd .= ' ' 121 | let cmd .= tname 122 | let cmd .= ' ' 123 | if a:props.synType == 'region' 124 | if exists("a:props.matchgroup") 125 | let cmd .= 'matchgroup=' . a:props.matchgroup 126 | endif 127 | let cmd .= ' start=+' . a:props.start . '+ end=+' . a:props.end 128 | else 129 | let cmd .= '+' . a:props.patt 130 | endif 131 | let cmd .= '+ ' 132 | let cmd .= 'contained ' 133 | if exists("a:props.contains") 134 | let cmd .= 'contains=' . join(a:props.contains, ",") . ' ' 135 | endif 136 | let cmd .= 'nextgroup=' 137 | if exists("a:props.nextgroup") 138 | let nextgroup = copy(a:props.nextgroup) 139 | else 140 | let nextgroup = [] 141 | endif 142 | call map(nextgroup, {-> (single && v:val =~# "Type" && !exists("a:props.dontsub")) ? s:ToSingleName(v:val) : v:val}) 143 | if single 144 | let nextgroup += ['tealSingleUnion'] 145 | else 146 | let nextgroup += ['tealUnion', 'tealTypeComma'] 147 | endif 148 | let cmd .= join(nextgroup, ',') 149 | let cmd .= ' skipwhite skipempty skipnl' 150 | exec cmd 151 | exec "syn cluster teal" . (single ? "Single" : "") . "Type add=" . tname 152 | endfor 153 | exec "highlight link " . s:ToSingleName(tname) . " " . tname 154 | endfunction 155 | " }}} 156 | call map(s:typePatterns, {tname, props -> s:MakeSyntaxItem(tname, props)}) 157 | 158 | syn cluster tealNewType contains=tealInterfaceBlock,tealRecordBlock,tealEnumBlock 159 | " }}} 160 | " {{{ Function call 161 | syn match tealFunctionCall /\K\k*\ze\s*\n*\s*\(["'({]\|\[=*\[\)/ 162 | " }}} 163 | " {{{ Operators 164 | " Symbols 165 | syn match tealOperator "[#<>=~^&|*/%+-]\|\.\." 166 | " Words 167 | syn keyword tealOperator and or not 168 | syn keyword tealOperator is as 169 | \ nextgroup=@tealSingleType 170 | \ skipempty skipnl skipwhite 171 | syn match tealVarargs /\.\.\./ 172 | " }}} 173 | " {{{ Comments 174 | syn match tealComment "\%^#!.*$" 175 | syn match tealComment /--.*$/ contains=tealTodo,@Spell 176 | syn keyword tealTodo contained TODO todo FIXME fixme TBD tbd XXX 177 | syn region tealLongComment start=/--\[\z(=*\)\[/ end=/\]\z1\]/ 178 | " }}} 179 | " {{{ local ... , global ... , local type ..., break, return, self 180 | syn keyword tealTypeDeclaration type contained 181 | \ nextgroup=tealTypeDeclarationName 182 | \ skipwhite skipempty skipnl 183 | syn match tealTypeDeclarationName /\K\k*/ contained 184 | \ nextgroup=tealTypeDeclarationEq,tealInvalid 185 | \ skipwhite skipempty skipnl 186 | syn match tealTypeDeclarationEq /=/ contained 187 | \ nextgroup=@tealSingleType,tealInterfaceBlock,tealRecordBlock,tealEnumBlock 188 | \ skipwhite skipempty skipnl 189 | syn region tealAttributeBrackets contained transparent 190 | \ matchgroup=tealParens 191 | \ start=// 192 | \ contains=tealAttribute 193 | \ nextgroup=tealVarComma,tealTypeAnnotation 194 | \ skipwhite skipempty skipnl 195 | syn match tealAttribute contained /\K\k*/ 196 | syn match tealVarName contained /\K\k*/ 197 | \ nextgroup=tealAttributeBrackets,tealVarComma,tealTypeAnnotation 198 | \ skipwhite skipempty skipnl 199 | syn match tealVarComma /,/ contained 200 | \ nextgroup=tealVarName 201 | \ skipwhite skipempty skipnl 202 | syn keyword tealLocal local 203 | \ nextgroup=tealFunctionBlock,tealMacroexpBlock,tealInterfaceBlock,tealRecordBlock,tealEnumBlock,tealVarName,tealTypeDeclaration 204 | \ skipwhite skipempty skipnl 205 | syn keyword tealGlobal global 206 | \ nextgroup=tealFunctionBlock,tealInterfaceBlock,tealRecordBlock,tealEnumBlock,tealVarName,tealTypeDeclaration 207 | \ skipwhite skipempty skipnl 208 | syn keyword tealBreak break 209 | syn keyword tealReturn return 210 | syn keyword tealSelf self 211 | " }}} 212 | " {{{ Parens 213 | syn region tealParen transparent 214 | \ matchgroup=tealParens 215 | \ start=/(/ end=/)/ 216 | \ contains=@tealExpression 217 | syn region tealBracket transparent 218 | \ matchgroup=tealBrackets 219 | \ start=/\[/ end=/\]/ 220 | \ contains=@tealExpression 221 | " }}} 222 | " {{{ function ... end 223 | syn region tealFunctionBlock transparent 224 | \ matchgroup=tealFunction 225 | \ start=/\/ end=/\/ 226 | \ contains=@tealStatement,tealFunctionStart 227 | syn region tealMacroexpBlock transparent 228 | \ matchgroup=tealFunction 229 | \ start=/\/ end=/\/ 230 | \ contains=@tealStatement,tealFunctionStart 231 | syn match tealFunctionStart /\(\\)\@8<=\s*/ contained 232 | \ nextgroup=tealFunctionName,tealFunctionGeneric,tealFunctionArgs 233 | \ skipwhite skipempty skipnl 234 | syn match tealFunctionName /\K\k*\(\.\K\k*\)*\(:\K\k*\)\?/ contained 235 | \ nextgroup=tealFunctionGeneric,tealFunctionArgs,tealInvalid 236 | \ skipwhite skipempty skipnl 237 | syn region tealFunctionGeneric contained transparent 238 | \ start=// 239 | \ contains=tealGeneric 240 | \ nextgroup=tealFunctionArgs 241 | \ skipwhite skipempty skipnl 242 | syn region tealFunctionArgs contained transparent 243 | \ matchgroup=tealParens 244 | \ start=/(/ end=/)/ 245 | \ contains=tealFunctionArgName,tealFunctionArgComma,tealSingleTypeAnnotation 246 | \ nextgroup=tealTypeAnnotation 247 | \ skipwhite skipempty skipnl 248 | syn match tealFunctionArgName contained /\K\k*/ 249 | \ nextgroup=tealSingleTypeAnnotation,tealFunctionArgComma,tealFunctionOptionalArgMark,tealInvalid 250 | \ skipwhite skipempty skipnl 251 | syn match tealFunctionArgComma contained /,/ 252 | \ nextgroup=tealFunctionArgName 253 | \ skipwhite skipempty skipnl 254 | syn match tealFunctionOptionalArgMark contained '?' 255 | \ nextgroup=tealTypeDeclaration 256 | \ skipwhite skipempty skipnl 257 | " }}} 258 | " {{{ record ... end 259 | syn match tealRecordType /\K\k*/ contained 260 | \ nextgroup=tealRecordAssign,tealInvalid 261 | \ skipwhite skipnl skipempty 262 | syn match tealRecordEntry /\K\k*/ contained 263 | \ nextgroup=tealSingleTypeAnnotation,tealInvalid 264 | \ skipwhite skipnl skipempty 265 | syn match tealRecordEntry /\[.*\]/ contained 266 | \ nextgroup=tealSingleTypeAnnotation,tealInvalid 267 | \ contains=tealString,tealLongString 268 | \ skipwhite skipnl skipempty 269 | \ transparent 270 | syn cluster tealRecordItem contains=tealRecordEntry 271 | syn region tealRecordBlock contained 272 | \ matchgroup=tealRecord transparent 273 | \ start=/\/ end=/\/ 274 | \ contains=tealInterfaceIs,tealInterfaceWhereGroup,tealRecordKeywordName,tealRecordStart,@tealRecordItem,tealTableType,tealComment,tealLongComment 275 | syn cluster tealRecordItem add=tealInterfaceBlock,tealRecordBlock,tealEnumBlock 276 | syn match tealRecordStart /\(\\)\@6<=\s*/ contained 277 | \ nextgroup=tealRecordName,tealRecordGeneric 278 | \ skipwhite skipnl skipempty 279 | syn match tealRecordName /\K\k*/ contained 280 | \ nextgroup=tealRecordGeneric 281 | \ skipwhite skipnl skipempty 282 | syn region tealRecordGeneric contained transparent 283 | \ matchgroup=tealParens 284 | \ start=// 285 | \ contains=tealGeneric 286 | \ nextgroup=@tealRecordItem,tealInterfaceIs 287 | \ skipwhite skipnl skipempty 288 | syn keyword tealRecordUserdata userdata contained 289 | \ nextgroup=@tealRecordItem 290 | \ skipwhite skipnl skipempty 291 | syn match tealRecordTypeDeclaration /type\s*\K\k*\s*=/ contained 292 | \ contains=tealRecordTypeKeyword,tealOperator 293 | \ nextgroup=@tealSingleType,@tealNewType,tealInvalid 294 | \ skipwhite skipnl skipempty 295 | syn keyword tealRecordMetamethodKeyword metamethod contained 296 | syn match tealRecordMetamethod /metamethod\s\+\K\k*/ contained 297 | \ contains=tealRecordMetamethodKeyword 298 | \ nextgroup=tealSingleTypeAnnotation 299 | \ skipwhite skipnl skipempty 300 | 301 | syn keyword tealRecordTypeKeyword type contained 302 | syn cluster tealRecordItem 303 | \ add=tealRecordTypeDeclaration,tealRecordUserdata,tealRecordMetamethod 304 | " }}} 305 | " {{{ interface ... end 306 | syn region tealInterfaceBlock contained 307 | \ matchgroup=tealInterface transparent 308 | \ start=/\/ end=/\/ 309 | \ contains=tealInterfaceIs,tealInterfaceWhereGroup,tealRecordKeywordName,tealInterfaceStart,@tealRecordItem,tealTableType,tealComment,tealLongComment 310 | syn match tealInterfaceStart /\(\\)\@9<=\s*/ contained 311 | \ nextgroup=tealInterfaceName,tealInterfaceGeneric 312 | \ skipwhite skipnl skipempty 313 | syn match tealInterfaceName /\K\k*/ contained 314 | \ nextgroup=tealInterfaceGeneric,tealInterfaceIs 315 | \ skipwhite skipnl skipempty 316 | syn region tealInterfaceGeneric contained transparent 317 | \ matchgroup=tealParens 318 | \ start=// 319 | \ contains=tealGeneric 320 | \ nextgroup=@tealRecordItem,tealInterfaceIs 321 | syn keyword tealInterfaceIs is 322 | \ contained 323 | \ nextgroup=@tealType 324 | \ skipwhite skipnl skipempty 325 | " This is a hack 326 | " Since the teal grammar is `where ` we can't determine the end of the 327 | " group without actually parsing, so we (falsely) assume that it spans the 328 | " rest of the line it's on 329 | syn region tealInterfaceWhereGroup contained transparent 330 | \ start=/\/ end=/\n/ 331 | \ contains=tealInferfaceWhere,@tealExpression 332 | syn keyword tealInterfaceWhere where 333 | \ contained containedin=tealInterfaceWhereGroup 334 | " }}} 335 | " {{{ enum ... end 336 | syn match tealEnumStart /\(\\)\@4<=\s*/ contained 337 | \ nextgroup=tealEnumName 338 | \ skipwhite skipnl skipempty 339 | syn match tealEnumName /\K\k*/ contained 340 | syn region tealEnumBlock 341 | \ matchgroup=tealEnum transparent 342 | \ start="\" end="\" 343 | \ contains=tealEnumStart,tealString,tealLongString,tealComment,tealLongComment,tealInvalid 344 | " }}} 345 | " {{{ record entries with names 'enum' and 'record' 346 | syn match tealRecordKeywordName /\(enum\|record\)\s*\ze:/ contained 347 | \ contains=tealRecordItem 348 | \ nextgroup=tealSingleTypeAnnotation,tealInvalid 349 | \ skipwhite skipnl skipempty 350 | " }}} 351 | " {{{ if ... then, elseif ... then, then ... end, else 352 | syn keyword tealError then 353 | syn region tealIfThen 354 | \ transparent matchgroup=tealIfStatement 355 | \ start=/\/ end=/\/me=e-4 356 | \ contains=@tealExpression 357 | \ nextgroup=tealThenEnd 358 | \ skipwhite skipnl skipempty 359 | syn region tealElseifThen contained 360 | \ transparent matchgroup=tealIfStatement 361 | \ start=/\/ end=/\/ 362 | \ contains=@tealExpression 363 | syn region tealThenEnd 364 | \ transparent matchgroup=tealIfStatement 365 | \ start=/\/ end=/\/ 366 | \ contains=tealElseifThen,tealElse,@tealStatement 367 | syn keyword tealElse else contained containedin=tealThenEnd 368 | " }}} 369 | " {{{ for ... do ... end, in 370 | syn region tealForDo 371 | \ matchgroup=tealFor transparent 372 | \ contains=tealIn,@tealExpression 373 | \ start=/\/ end=/\/me=e-2 374 | syn keyword tealIn in contained 375 | " }}} 376 | " {{{ while ... do ... end 377 | syn region tealWhileDo 378 | \ matchgroup=tealWhile transparent 379 | \ contains=@tealExpression 380 | \ start=/\/ end=/\/me=e-2 381 | " }}} 382 | " {{{ do ... end 383 | syn region tealBlock 384 | \ matchgroup=tealDoEnd transparent 385 | \ contains=@tealStatement 386 | \ start=/\/ end=/\/ 387 | " }}} 388 | " {{{ repeat ... until 389 | syn region tealRepeatBlock 390 | \ matchgroup=tealRepeatUntil transparent 391 | \ contains=@tealStatement 392 | \ start=/\/ end=/\/ 393 | " }}} 394 | " {{{ Goto 395 | syn keyword tealGoto goto 396 | syn match tealLabel /::\K\k*::/ 397 | " }}} 398 | " {{{ true, false, nil, etc... 399 | syn keyword tealConstant nil true false 400 | " }}} 401 | " {{{ Strings 402 | syn match tealSpecial contained #\\[\\abfnrtvz'"]\|\\x[[:xdigit:]]\{2}\|\\[[:digit:]]\{,3}# 403 | syn region tealLongString matchgroup=tealQuote start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell 404 | syn region tealString matchgroup=tealQuote start=+'+ end=+'\|$+ skip=+\\\\\|\\'+ contains=tealSpecial,@Spell 405 | syn region tealString matchgroup=tealQuote start=+"+ end=+"\|$+ skip=+\\\\\|\\"+ contains=tealSpecial,@Spell 406 | " }}} 407 | " {{{ Numbers 408 | " integer number 409 | syn match tealNumber "\<\d\+\>" 410 | " floating point number, with dot, optional exponent 411 | syn match tealNumber "\<\d\+\.\d*\%([eE][-+]\=\d\+\)\=\>" 412 | " floating point number, starting with a dot, optional exponent 413 | syn match tealNumber "\.\d\+\%([eE][-+]\=\d\+\)\=\>" 414 | " floating point number, without dot, with exponent 415 | syn match tealNumber "\<\d\+[eE][-+]\=\d\+\>" 416 | " hex numbers 417 | syn match tealNumber "\<0[xX][[:xdigit:].]\+\%([pP][-+]\=\d\+\)\=\>" 418 | " }}} 419 | " {{{ Built ins 420 | 421 | syn keyword tealBuiltIn assert error collectgarbage 422 | \ print tonumber tostring type 423 | \ getmetatable setmetatable 424 | \ ipairs pairs next 425 | \ pcall xpcall 426 | \ _G _ENV _VERSION require 427 | \ rawequal rawget rawset rawlen 428 | \ loadfile load dofile select 429 | syn match tealBuiltIn /\/ 430 | syn match tealBuiltIn /\/ 431 | syn match tealBuiltIn /\/ 432 | syn match tealBuiltIn /\/ 433 | syn match tealBuiltIn /\/ 434 | syn match tealBuiltIn /\/ 435 | syn match tealBuiltIn /\/ 436 | syn match tealBuiltIn /\/ 437 | syn match tealBuiltIn /\/ 438 | syn match tealBuiltIn /\/ 439 | syn match tealBuiltIn /\/ 440 | syn match tealBuiltIn /\/ 441 | syn match tealBuiltIn /\/ 442 | syn match tealBuiltIn /\/ 443 | syn match tealBuiltIn /\/ 444 | syn match tealBuiltIn /\/ 445 | syn match tealBuiltIn /\/ 446 | syn match tealBuiltIn /\/ 447 | syn match tealBuiltIn /\/ 448 | syn match tealBuiltIn /\/ 449 | syn match tealBuiltIn /\/ 450 | syn match tealBuiltIn /\/ 451 | syn match tealBuiltIn /\/ 452 | syn match tealBuiltIn /\/ 453 | syn match tealBuiltIn /\/ 454 | syn match tealBuiltIn /\/ 455 | syn match tealBuiltIn /\/ 456 | syn match tealBuiltIn /\/ 457 | syn match tealBuiltIn /\/ 458 | syn match tealBuiltIn /\/ 459 | syn match tealBuiltIn /\/ 460 | syn match tealBuiltIn /\/ 461 | syn match tealBuiltIn /\/ 462 | syn match tealBuiltIn /\/ 463 | syn match tealBuiltIn /\/ 464 | syn match tealBuiltIn /\/ 465 | syn match tealBuiltIn /\/ 466 | syn match tealBuiltIn /\/ 467 | syn match tealBuiltIn /\/ 468 | syn match tealBuiltIn /\/ 469 | syn match tealBuiltIn /\/ 470 | syn match tealBuiltIn /\/ 471 | syn match tealBuiltIn /\/ 472 | syn match tealBuiltIn /\/ 473 | syn match tealBuiltIn /\/ 474 | syn match tealBuiltIn /\/ 475 | syn match tealBuiltIn /\/ 476 | syn match tealBuiltIn /\/ 477 | syn match tealBuiltIn /\/ 478 | syn match tealBuiltIn /\/ 479 | syn match tealBuiltIn /\/ 480 | syn match tealBuiltIn /\/ 481 | syn match tealBuiltIn /\/ 482 | syn match tealBuiltIn /\/ 483 | syn match tealBuiltIn /\/ 484 | syn match tealBuiltIn /\/ 485 | syn match tealBuiltIn /\/ 486 | syn match tealBuiltIn /\/ 487 | syn match tealBuiltIn /\/ 488 | syn match tealBuiltIn /\/ 489 | syn match tealBuiltIn /\/ 490 | syn match tealBuiltIn /\/ 491 | syn match tealBuiltIn /\/ 492 | syn match tealBuiltIn /\/ 493 | syn match tealBuiltIn /\/ 494 | syn match tealBuiltIn /\/ 495 | syn match tealBuiltIn /\/ 496 | syn match tealBuiltIn /\/ 497 | syn match tealBuiltIn /\/ 498 | syn match tealBuiltIn /\/ 499 | syn match tealBuiltIn /\/ 500 | syn match tealBuiltIn /\/ 501 | syn match tealBuiltIn /\/ 502 | syn match tealBuiltIn /\/ 503 | syn match tealBuiltIn /\/ 504 | syn match tealBuiltIn /\/ 505 | syn match tealBuiltIn /\/ 506 | syn match tealBuiltIn /\/ 507 | syn match tealBuiltIn /\/ 508 | syn match tealBuiltIn /\/ 509 | syn match tealBuiltIn /\/ 510 | syn match tealBuiltIn /\/ 511 | syn match tealBuiltIn /\/ 512 | syn match tealBuiltIn /\/ 513 | syn match tealBuiltIn /\/ 514 | syn match tealBuiltIn /\/ 515 | syn match tealBuiltIn /\/ 516 | syn match tealBuiltIn /\/ 517 | syn match tealBuiltIn /\/ 518 | syn match tealBuiltIn /\/ 519 | syn match tealBuiltIn /\/ 520 | syn match tealBuiltIn /\/ 521 | syn match tealBuiltIn /\/ 522 | syn match tealBuiltIn /\/ 523 | syn match tealBuiltIn /\/ 524 | syn match tealBuiltIn /\/ 525 | syn match tealBuiltIn /\/ 526 | syn match tealBuiltIn /\/ 527 | syn match tealBuiltIn /\/ 528 | syn match tealBuiltIn /\/ 529 | syn match tealBuiltIn /\/ 530 | syn match tealBuiltIn /\/ 531 | syn match tealBuiltIn /\/ 532 | syn match tealBuiltIn /\/ 533 | syn match tealBuiltIn /\/ 534 | 535 | " }}} 536 | " {{{ Highlight 537 | hi def link tealAttribute StorageClass 538 | hi def link tealBasicType Type 539 | hi def link tealBreak Keyword 540 | hi def link tealBuiltin Identifier 541 | hi def link tealComma Delimiter 542 | hi def link tealComment Comment 543 | hi def link tealConstant Constant 544 | hi def link tealDoEnd Keyword 545 | hi def link tealElse Conditional 546 | hi def link tealEnum Keyword 547 | hi def link tealEnumName tealBasicType 548 | hi def link tealError Error 549 | hi def link tealFor Repeat 550 | hi def link tealFunction Keyword 551 | hi def link tealFunctionArgName Identifier 552 | hi def link tealFunctionCall Function 553 | hi def link tealFunctionName Function 554 | hi def link tealFunctionOptionalArgMark Type 555 | hi def link tealFunctionType Type 556 | hi def link tealGeneric Type 557 | hi def link tealGlobal Keyword 558 | hi def link tealGoto Keyword 559 | hi def link tealIfStatement Conditional 560 | hi def link tealIn Keyword 561 | hi def link tealInterface Keyword 562 | hi def link tealInterfaceIs Operator 563 | hi def link tealInterfaceName tealBasicType 564 | hi def link tealInterfaceWhere Operator 565 | hi def link tealInvalid Error 566 | hi def link tealKeyword Keyword 567 | hi def link tealLabel Label 568 | hi def link tealLocal Keyword 569 | hi def link tealLongComment Comment 570 | hi def link tealLongString String 571 | hi def link tealNumber Number 572 | hi def link tealOperator Operator 573 | hi def link tealParens Normal 574 | hi def link tealQuote Delimiter 575 | hi def link tealRecord Keyword 576 | hi def link tealRecordAssign tealOperator 577 | hi def link tealRecordMetamethodKeyword Keyword 578 | hi def link tealRecordName tealBasicType 579 | hi def link tealRecordType tealBasicType 580 | hi def link tealRecordTypeKeyword tealKeyword 581 | hi def link tealRecordUserdata Keyword 582 | hi def link tealRepeatUntil Repeat 583 | hi def link tealReturn Keyword 584 | hi def link tealSelf Special 585 | hi def link tealSpecial Special 586 | hi def link tealString String 587 | hi def link tealTable Structure 588 | hi def link tealTodo Todo 589 | hi def link tealTypeComma tealComma 590 | hi def link tealTypeDeclaration StorageClass 591 | hi def link tealTypeDeclarationEq tealOperator 592 | hi def link tealTypeDeclarationName tealBasicType 593 | hi def link tealWhile Repeat 594 | " }}} 595 | 596 | let b:current_syntax = "teal" 597 | 598 | let &cpo = s:cpo_save 599 | unlet s:cpo_save 600 | --------------------------------------------------------------------------------