Add pony support

This commit is contained in:
Adam Stankiewicz 2018-12-26 20:33:28 +01:00
parent f238378221
commit c161994e96
7 changed files with 862 additions and 1 deletions

View File

@ -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-->117<!--/Package Count--> packages it consists of.
- It **installs and updates 100+ times faster** than the <!--Package Count-->118<!--/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`).
@ -116,6 +116,7 @@ If you need full functionality of any plugin, please use it directly with your p
- [pgsql](https://github.com/exu/pgsql.vim) (syntax)
- [php](https://github.com/StanAngeloff/php.vim) (syntax)
- [plantuml](https://github.com/aklt/plantuml-syntax) (syntax, indent, ftplugin)
- [pony](https://github.com/jakwings/vim-pony) (syntax, indent, autoload, ftplugin)
- [powershell](https://github.com/PProvost/vim-ps1) (syntax, indent, ftplugin)
- [protobuf](https://github.com/uarun/vim-protobuf) (syntax, indent)
- [pug](https://github.com/digitaltoad/vim-pug) (syntax, indent, ftplugin)

536
autoload/pony.vim Normal file
View File

@ -0,0 +1,536 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pony') == -1
" Vim plugin file
" Language: Pony
" Maintainer: Jak Wings
" TODO: Make sure echomsg is off for release.
let s:cpo_save = &cpo
set cpo&vim
"let s:skip = '<SID>InCommentOrLiteral(line("."), col("."))'
let s:skip2 = '<SID>InLiteral(line("."), col(".")) || <SID>InComment(line("."), col(".")) == 1'
let s:skip3 = '!<SID>InKeyword(line("."), col("."))'
let s:skip4 = '!<SID>InBracket(line("."), col("."))'
let s:cfstart = '\v<%(ifdef|if|match|while|for|repeat|try|with|recover|object|lambda|iftype)>'
let s:cfmiddle = '\v<%(then|elseif|else|until|do|in|elseiftype)>|\|'
let s:cfend = '\v<end>'
let s:bstartp = '\v<%(ifdef|if|then|elseif|else|(match)|while|for|in|do|try|with|recover|repeat|until|(object)|lambda|iftype|elseiftype)>'
function! pony#Indent()
if v:lnum <= 1
return 0
endif
call cursor(v:lnum, 1)
let l:pnzpos = searchpos('.', 'cbnW')
if l:pnzpos == [0, 0]
return 0
endif
if s:InComment2(l:pnzpos) > 1
"echomsg 'Comment' (l:pnzpos[0] . '-' . v:lnum) -1
return cindent(v:lnum)
endif
if s:InLiteral2(l:pnzpos)
"echomsg 'String' (l:pnzpos[0] . '-' . v:lnum) -1
return -1
endif
unlet! l:pnzpos
" NOTE: Lines started in comments and strings are checked already.
let l:pnblnum = s:PrevNonblank(v:lnum - 1)
if l:pnblnum < 1
return 0
endif
let l:pnbline = getline(l:pnblnum)
let l:pnbindent = indent(l:pnblnum)
let l:line = getline(v:lnum)
let l:indent = l:pnbindent
let l:shiftwidth = shiftwidth()
" FIXME?
let l:continuing = 0
" If the previous line ends with a unary or binary operator,
if s:IsContinued(l:pnblnum)
let l:contlnum = l:pnblnum
let l:ppcontinued = 0
let l:ppnblnum = s:PrevNonblank(l:pnblnum - 1)
while s:IsContinued(l:ppnblnum)
let l:ppcontinued += 1
let l:contlnum = l:ppnblnum
let l:ppnblnum = s:PrevNonblank(l:ppnblnum - 1)
endwhile
"echomsg 'Continued1' l:pnblnum l:contlnum
" If the previous line is also continuing another line,
if l:ppcontinued
let l:continuing = 1
if getline(l:contlnum) =~# '\v^\s*%(actor|class|struct|primitive|trait|type|interface)>'
" reset the indent level.
"echomsg 'Continuing0' (l:contlnum . '-' . v:lnum) (l:shiftwidth * 2)
let l:indent = l:shiftwidth * 2
else
" keep using the previous indent.
"echomsg 'Continuing1' (l:pnblnum . '-' . v:lnum) l:pnbindent
let l:indent = l:pnbindent
endif
" if the previous line is part of the definition of a class,
elseif l:pnbline =~# '\v^\s*%(actor|class|struct|primitive|trait|type|interface)>'
" reset the indent level.
"echomsg 'Continuing2' (l:pnblnum . '-' . v:lnum) (l:shiftwidth * 2)
let l:continuing = 1
let l:indent = l:shiftwidth * 2
" if the previous line is part of the definition of a method,
elseif l:pnbline =~# '\v^\s*%(fun|new|be)>'
" reset the indent level.
"echomsg 'Continuing3' (l:pnblnum . '-' . v:lnum) (l:pnbindent + l:shiftwidth)
let l:continuing = 1
let l:indent = l:pnbindent + l:shiftwidth
" if the previous line is the start of a definition body,
elseif l:pnbline =~# '=>\s*$'
" indent this line.
"echomsg 'Continuing4' (l:pnblnum . '-' . v:lnum) (l:pnbindent + l:shiftwidth)
let l:continuing = 1
let l:indent = l:pnbindent + l:shiftwidth
else
" indent this line twice as far.
"echomsg 'Continuing5' (l:pnblnum . '-' . v:lnum) (l:pnbindent + l:shiftwidth * 2)
let l:continuing = 1
let l:indent = l:pnbindent + l:shiftwidth * 2
endif
unlet! l:contlnum l:ppnblnum l:ppcontinued
endif
" If this line starts a document string,
if !l:continuing && l:line =~# '^\s*"""'
let l:ppnblnum = s:PrevNonblank(l:pnblnum - 1)
if s:IsContinued(l:ppnblnum)
let l:contlnum = l:ppnblnum
while s:IsContinued(l:ppnblnum)
let l:contlnum = l:ppnblnum
let l:ppnblnum = s:PrevNonblank(l:ppnblnum - 1)
endwhile
if getline(l:contlnum) =~# '\v^\s*%(actor|class|struct|primitive|trait|type|interface)>'
" reset the indent level.
"echomsg 'DocString' (l:contlnum . '-' . v:lnum) l:shiftwidth
return l:shiftwidth
endif
endif
unlet! l:contlnum l:ppnblnum
endif
" If the previous line contains an unmatched opening bracket
if !l:continuing && l:pnbline =~# '[{[(]'
" if the line ends with an opening bracket,
if l:pnbline =~# '[{[(]\s*$' && !s:InCommentOrLiteral(l:pnblnum, col([l:pnblnum, '$']) - 1)
" indent this line.
let l:indent += l:shiftwidth
else
" find the unmatched opening bracket,
let l:start = [0, 0]
let l:end = col([l:pnblnum, '$']) - 1
call cursor(l:pnblnum, l:end)
while l:end > 0
let l:start = s:OuterPos(l:start, searchpairpos('(', '', ')', 'bnW', s:skip4, l:pnblnum))
let l:start = s:OuterPos(l:start, searchpairpos('\[', '', '\]', 'bnW', s:skip4, l:pnblnum))
let l:start = s:OuterPos(l:start, searchpairpos('{', '', '}', 'bnW', s:skip4, l:pnblnum))
if l:start == [0, 0]
break
endif
" find the matched closing bracket on the same line,
call cursor(l:start[0], l:start[1])
let l:c = s:CharAtCursor(l:start[0], l:start[1])
if searchpair(escape(l:c, '['), '', escape(tr(l:c, '([{', ')]}'), ']'),
\ 'znW', s:skip4, l:pnblnum) < 1
" the unmatched opening bracket is found,
break
endif
let l:end = l:start[1]
let l:start = [0, 0]
endwhile
if l:start != [0, 0]
" indent this line.
"echomsg 'Open bracket' (l:pnblnum . '-' . v:lnum) (l:indent + l:shiftwidth)
let l:indent += l:shiftwidth
endif
endif
unlet! l:start l:end l:c
endif
" If there is a matched closing bracket on the previous line,
" NOTE:
" >|[
" | (1 -
" | 1) * 2]
" | command
" ^
if !l:continuing
call cursor(l:pnblnum, 1)
" find the last closing bracket,
let l:end = [0, 0]
let l:end = s:OuterPos(l:end, searchpairpos('(', '', ')', 'zncr', s:skip4, l:pnblnum))
let l:end = s:OuterPos(l:end, searchpairpos('\[', '', '\]', 'zncr', s:skip4, l:pnblnum))
let l:end = s:OuterPos(l:end, searchpairpos('{', '', '}', 'zncr', s:skip4, l:pnblnum))
if l:end != [0, 0]
" find the matched opening bracket on another line,
let l:c = s:CharAtCursor(l:end[0], l:end[1])
let l:start = searchpairpos(escape(tr(l:c, ')]}', '([{'), '['), '', escape(l:c, ']'), 'nbW', s:skip4)
if l:start[0] != l:end[0]
" and then this line has the same indent as the line the matched bracket stays.
"echomsg 'Matched bracket' (l:start[0] . '-' . v:lnum) indent(l:start[0])
let l:indent = indent(l:start[0])
endif
endif
unlet! l:start l:end l:c
endif
" If there is a matched closing bracket on this line,
" NOTE:
" |[
" >| (1 -
" | 1) * 2
" |]
" ^ ^
if l:line =~# '^\s*[)\]}]'
" find the first closing bracket,
call cursor(v:lnum, 1)
let l:end = [0, 0]
let l:end = s:InnerPos(l:end, searchpairpos('(', '', ')', 'zncW', s:skip4, v:lnum))
let l:end = s:InnerPos(l:end, searchpairpos('\[', '', '\]', 'zncW', s:skip4, v:lnum))
let l:end = s:InnerPos(l:end, searchpairpos('{', '', '}', 'zncW', s:skip4, v:lnum))
if l:end != [0, 0]
" find the matched opening bracket on another line,
let l:c = s:CharAtCursor(l:end[0], l:end[1])
let l:start = searchpairpos(escape(tr(l:c, ')]}', '([{'), '['), '', escape(l:c, ']'), 'nbW', s:skip4)
if l:start[0] != l:end[0]
" and then this line has the same indent as the line the matched bracket stays.
"echomsg 'Closing Bracket' (l:start[0] . '-' . v:lnum) indent(l:start[0])
let l:indent = indent(l:start[0])
endif
endif
unlet! l:start l:end l:c
endif
" If this line starts the definition of a method, closure or match case,
if l:line =~# '^\s*=>'
" find the start of the definition,
call cursor(v:lnum, 1)
let l:start = searchpairpos('\v<%(new|be|fun|lambda)>|\|', '', '=>\zs', 'bnW', s:skip3)
if l:start != [0, 0]
" then this line has the same indent as the start.
"echomsg 'Method body' (l:start[0] . '-' . v:lnum) indent(l:start[0])
return indent(l:start[0])
endif
unlet! l:start
endif
" If this line starts a class definition or starts an alias,
if l:line =~# '\v^\s*%(actor|class|struct|primitive|trait|interface|use|type)>'
" reset the indent level.
return 0
endif
" If this line starts a method definition,
if l:line =~# '\v^\s*%(new|be|fun)>'
call cursor(v:lnum, 1)
let l:start = searchpairpos(s:cfstart, s:cfmiddle, s:cfend, 'bW', s:skip3)
if l:start != [0, 0]
let l:start = searchpos(s:bstartp, 'zcnpW', l:start[0])
" see if it is in an object block,
if l:start[2] == 3
"echomsg 'Method in object' (l:start[0] . '-' . v:lnum) (l:shiftwidth + indent(l:start[0]))
return l:shiftwidth + indent(l:start[0])
endif
endif
return l:shiftwidth
endif
" If this line starts a match case,
call cursor(v:lnum, 1)
if l:line =~# '^\s*|' && s:InKeyword(searchpos('|', 'znW', v:lnum))
" find the start or the previous case of the match block,
let l:start = searchpairpos(s:cfstart, s:cfmiddle, s:cfend, 'bnW', s:skip3)
if l:start != [0, 0]
" then this line has the same indent as the start.
"echomsg 'Match case' (l:start[0] . '-' . v:lnum) indent(l:start[0])
return indent(l:start[0])
endif
unlet! l:start
endif
" If this line ends (part of) a control flow,
if l:line =~# '\v^\s*%(end|elseif|else|then|in|do|until|elseiftype)>'
" find the start or middle of the control block,
call cursor(v:lnum, 1)
let l:start = searchpairpos(s:cfstart, s:cfmiddle, s:cfend, 'bnW', s:skip3)
if l:start != [0, 0]
" then this line has the same indent as the start.
"echomsg 'Block end' (l:start[0] . '-' . v:lnum) indent(l:start[0])
return indent(l:start[0])
endif
unlet! l:start
endif
" If the previous line starts a class definition,
if l:pnbline =~# '\v^\s*%(actor|class|struct|primitive|trait|type|interface)>'
" reset the indent level.
if s:IsContinued(l:pnblnum)
return l:shiftwidth * 2
else
return l:shiftwidth
endif
endif
" If the previous line starts a method definition,
if l:pnbline =~# '\v^\s*%(new|be|fun)>'
return l:pnbindent + l:shiftwidth
endif
" If the previous line starts (part of) a control flow,
call cursor(l:pnblnum, 1)
while 1
" find the start of the control block,
let l:start = searchpos(s:bstartp, 'zcepW', l:pnblnum)
if l:start[2] == 0
break
endif
if !s:InKeyword(l:start[0:1])
call cursor(l:pnblnum, l:start[1] + 3)
continue
endif
let l:index = l:start[2]
" find the end of the control block on the same line,
let l:end = searchpair(s:cfstart, '', s:cfend, 'znW', s:skip3, l:pnblnum)
" if the control block is not ended,
if l:end < 1
" if this line is a case for a match,
if l:index == 2 && l:line =~# '^\s*|'
" then this line has the same indent as the start of the match block.
return l:pnbindent
else
" then indent this line.
"echomsg 'Block start' (l:pnblnum . '-' . v:lnum) (l:pnbindent + l:shiftwidth)
return l:pnbindent + l:shiftwidth
endif
endif
endwhile
unlet! l:start l:end l:index
return l:indent
endfunction
function! s:PrevNonblank(lnum)
let l:lnum = prevnonblank(a:lnum)
while l:lnum > 0 && (s:InComment2(l:lnum, 1) || s:InLiteral2(l:lnum, 1))
let l:lnum = prevnonblank(l:lnum - 1)
endwhile
return l:lnum
endfunction
" NOTE:
" v
" |1 /* comment */
" |2
function! s:IsContinued(lnum)
let l:lnum = s:PrevNonblank(a:lnum)
if l:lnum < 1
return 0
endif
let l:line = getline(l:lnum)
let l:width = strwidth(substitute(l:line, '\s*$', '', ''))
" FIXME?
" | 1 + //
" | //
" | 2
return !s:InCommentOrLiteral(a:lnum, l:width)
\ && (l:line =~# '\v<%(and|or|xor|is|isnt|as|not|consume|addressof|digestof)\s*$'
\ || l:line =~# '\v%([=\-.]\>|[<!=>]\=\~?|\<\<\~?|\>\>\~?|\<:|[+\-*/%<>]\~?|[.,|:@~])\s*$'
\ )
endfunction
function! s:InCommentOrLiteral(...)
return call('s:InComment', a:000) || call('s:InLiteral', a:000)
endfunction
function! s:InKeyword(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
for id in s:Or(synstack(l:lnum, l:col), [])
if synIDattr(id, 'name') =~# '^ponyKw'
return 1
endif
endfor
return 0
endfunction
function! s:InBracket(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
for id in s:Or(synstack(l:lnum, l:col), [])
if synIDattr(id, 'name') ==# 'ponyBracket'
return 1
endif
endfor
return 0
endfunction
function! s:InComment(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
let l:stack = synstack(l:lnum, l:col)
let l:i = len(l:stack)
while l:i > 0
let l:sname = synIDattr(l:stack[l:i - 1], 'name')
if l:sname =~# '^ponyNestedCommentX\?$'
return 1 + l:i - (l:sname =~# 'X$')
elseif l:sname =~# '^ponyCommentX\?$'
return 1
endif
let l:i -= 1
endwhile
return 0
endfunction
function! s:InLiteral(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
let l:stack = synstack(l:lnum, l:col)
let l:i = len(l:stack)
while l:i > 0
let l:sname = synIDattr(l:stack[l:i - 1], 'name')
if l:sname =~# '^ponyDocumentStringX\?$'
return 3
elseif l:sname =~# '^ponyStringX\?$'
return 2
elseif l:sname =~# '^ponyCharacterX\?$'
return 1
endif
let l:i -= 1
endwhile
return 0
endfunction
" NOTE:
" |// //inside
" ^^^^^^^^^^
" |/* /*inside*/ */
" ^^^^^^^^^^^^^^
function! s:InComment2(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
let l:stack = synstack(l:lnum, l:col)
let l:i = len(l:stack)
while l:i > 0
let l:sname = synIDattr(l:stack[l:i - 1], 'name')
if l:sname ==# 'ponyNestedComment'
return 1 + l:i
elseif l:sname ==# 'ponyComment'
return 1
elseif l:sname =~# '\v^pony%(Nested)?CommentX$'
return 0
endif
let l:i -= 1
endwhile
return 0
endfunction
" NOTE:
" |"inside"
" ^^^^^^
" |"""inside"""""
" ^^^^^^^^^^^^
function! s:InLiteral2(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
let l:stack = synstack(l:lnum, l:col)
let l:i = len(l:stack)
while l:i > 0
let l:sname = synIDattr(l:stack[l:i - 1], 'name')
if l:sname ==# 'ponyDocumentString'
return 3
elseif l:sname ==# 'ponyString'
return 2
elseif l:sname ==# 'ponyCharacter'
return 1
elseif l:sname =~# '\v^pony%(DocumentString|String|Character)X$'
return 0
endif
let l:i -= 1
endwhile
return 0
endfunction
function! s:CharAtCursor(...)
let [l:lnum, l:col] = (type(a:1) == type([]) ? a:1 : a:000)
return matchstr(getline(l:lnum), '\%' . l:col . 'c.')
endfunction
function! s:Or(x, y)
return !empty(a:x) ? a:x : a:y
endfunction
function! s:InnerPos(x, y)
if a:x == [0, 0]
return a:y
elseif a:y == [0, 0]
return a:x
else
return a:x[1] < a:y[1] ? a:x : a:y
end
endfunction
function! s:OuterPos(x, y)
if a:x == [0, 0]
return a:y
elseif a:y == [0, 0]
return a:x
else
return a:x[1] > a:y[1] ? a:x : a:y
end
endfunction
function! pony#ClearTrailingSpace(all, alt, ...)
let l:force = (a:0 > 0 ? a:1 : 0)
if !l:force && (&readonly || !&modifiable || !&modified)
return
endif
if a:all
for lnum in range(1, line('$'))
let l:line = getline(lnum)
let l:end = col([lnum, '$']) - 1
if l:end > 0 && l:line =~# '\s$' && !s:InLiteral(lnum, l:end)
if a:alt
call setline(lnum, substitute(l:line, '\S\@<=\s\s*$', '', ''))
else
call setline(lnum, substitute(l:line, '\s\+$', '', ''))
endif
endif
endfor
else
let l:lnum = line('.')
let l:end = col('$') - 1
let l:line = getline(l:lnum)
if l:line =~# '\s$' && !s:InLiteral(l:lnum, l:end)
if a:alt
call setline(l:lnum, substitute(l:line, '\s\+$', '', ''))
else
call setline(l:lnum, substitute(l:line, '\S\@<=\s\s*$', '', ''))
endif
endif
endif
endfunction
let &cpo = s:cpo_save
unlet s:cpo_save
endif

1
build
View File

@ -225,6 +225,7 @@ PACKS="
pgsql:exu/pgsql.vim
php:StanAngeloff/php.vim
plantuml:aklt/plantuml-syntax
pony:jakwings/vim-pony
powershell:PProvost/vim-ps1
protobuf:uarun/vim-protobuf
pug:digitaltoad/vim-pug

View File

@ -795,6 +795,13 @@ au BufNewFile,BufRead *.pgsql setf pgsql
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pony') == -1
augroup filetypedetect
" pony, from pony.vim in jakwings/vim-pony
autocmd BufRead,BufNewFile *.pony setf pony
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'powershell') == -1
augroup filetypedetect
" powershell, from ps1.vim in PProvost/vim-ps1

44
ftplugin/pony.vim Normal file
View File

@ -0,0 +1,44 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pony') == -1
" Vim filetype plugin file
" Language: Pony
" Maintainer: Jak Wings
if exists('b:did_ftplugin')
finish
endif
let s:cpo_save = &cpo
set cpo&vim
setlocal comments=://,nsr:/*,mb:*,ex:*/
setlocal commentstring=/*%s*/
setlocal formatoptions-=t fo+=c fo+=r fo+=o fo+=q fo+=l fo+=j
"setlocal path=
"setlocal includeexpr=
setlocal include=\\v^\\s*use\\_s+%(\\i+\\_s*\\=\\_s*)?"\\zs[^"]*\\ze"
setlocal define=\\v^\\s*%(actor\|class\|struct\|primitive\|trait\|interface\|type\|new\|be\|fun\|let\|var\|embed\|use\|for\\_s+%(\\i+\\_s*,\\_s*)*\|with\\_s+%(\\i+\\_s*,\\_s*)*)\|(<\\i+\\_s*:\\_s*\\i+)@=
setlocal isident=@,48-57,_,39
setlocal iskeyword=@,48-57,_,39
setlocal suffixesadd=.pony
setlocal matchpairs=(:),{:},[:]
let b:match_ignorecase = 0
let b:match_skip = 's:Comment\|String\|Character\|CaseGuard'
let b:match_words = '\v<%(ifdef|if|match|while|for|repeat|try|with|recover|object|lambda|iftype)>\m:\v<%(then|elseif|else|until|do|in|elseiftype)>|\|\m:\<end\>,(:),\[:\],{:}'
" TODO: for more concise behavior
"let b:match_words = 'pony#GetMatchWords()'
source $VIMRUNTIME/macros/matchit.vim
let b:undo_ftplugin = 'set comments< commentstring< formatoptions< path< include< includeexpr< define< isident< iskeyword< suffixesadd< matchpairs<'
\ . ' | unlet! b:match_ignorecase b:match_skip b:match_words'
let &cpo = s:cpo_save
unlet s:cpo_save
let b:did_ftplugin = 1
endif

41
indent/pony.vim Normal file
View File

@ -0,0 +1,41 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pony') == -1
" Vim indent file
" Language: Pony
" Maintainer: Jak Wings
if exists('b:did_indent')
finish
endif
let s:cpo_save = &cpo
set cpo&vim
setlocal nolisp
setlocal nocindent
setlocal nosmartindent
setlocal autoindent
setlocal indentexpr=pony#Indent()
setlocal indentkeys=!^F,o,O,0\|,0(,0),0[,0],0{,0},0==>,0=\"\"\",0=end,0=then,0=else,0=in,0=do,0=until,0=actor,0=class,0=struct,0=primitive,0=trait,0=interface,0=new,0=be,0=fun,0=type,0=use
setlocal cinkeys=!^F,o,O,0\|,0(,0),0[,0],0{,0},0==>,0=\"\"\",0=end,0=then,0=else,0=in,0=do,0=until,0=actor,0=class,0=struct,0=primitive,0=trait,0=interface,0=new,0=be,0=fun,0=type,0=use
setlocal cinwords=ifdef,if,match,while,for,repeat,try,with,recover,object,lambda,then,elseif,else,until,do,actor,class,struct,primitive,trait,interface,new,be,fun,iftype,elseiftype
augroup pony
autocmd! * <buffer>
autocmd CursorHold <buffer> call pony#ClearTrailingSpace(1, 1)
"autocmd InsertEnter <buffer> call pony#ClearTrailingSpace(0, 0)
autocmd InsertLeave <buffer> call pony#ClearTrailingSpace(0, 1)
autocmd BufWritePre <buffer> call pony#ClearTrailingSpace(1, 0, 1)
augroup END
let b:undo_indent = 'set lisp< cindent< autoindent< smartindent< indentexpr< indentkeys< cinkeys< cinwords<'
\ . ' | execute("autocmd! pony * <buffer>")'
let &cpo = s:cpo_save
unlet s:cpo_save
let b:did_indent = 1
endif

231
syntax/pony.vim Normal file
View File

@ -0,0 +1,231 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pony') == -1
" Vim syntax file
" Language: Pony
" Maintainer: Jak Wings
if exists('b:current_syntax')
finish
endif
let s:cpo_save = &cpo
set cpo&vim
syn case match
syn sync match ponySync grouphere NONE /\v^\s*%(actor|class|struct|primitive|trait|interface|new|be|fun|let|var|embed|use)>/
syn match ponyErrSymbol /['^!$&\`]/
hi def link ponyErrSymbol Error
syn match ponyErrNumGroup /__\+/ contained
hi def link ponyErrNumGroup Error
syn match ponyPeriodComma /,/ nextgroup=ponyEllipsis,ponyErrOperator skipwhite
syn match ponyPeriodComma /\./ nextgroup=ponyTupleIndex,ponyErrOperator skipwhite
syn match ponyPeriodComma /;/ nextgroup=ponyErrOperator skipwhite
hi def link ponyPeriodComma Operator
syn match ponyBracket /[{[()\]}]/
syn match ponyErrNormal /\v_>|<%([^_a-z]|_[^a-z])|__+/ contained
hi def link ponyErrNormal Error
syn match ponyNormal /\v_?[_a-z]\w*'*/ contains=ponyErrNormal nextgroup=ponyGeneric skipwhite
syn match ponyInteger /\v%(\d+_*)+/ contains=ponyErrNumGroup
syn match ponyErrIntDec /\v(0[xX])@<=[_.g-zG-Z]/
syn match ponyErrIntHex /[.g-zG-Z]/ contained
syn match ponyInteger /\v0[xX]%(\x+_*)+/ contains=ponyErrNumGroup nextgroup=ponyErrIntHex
syn match ponyErrIntDec /\v(0[bB])@<=[_2-9a-zA-Z]/
syn match ponyErrIntBin /[2-9.a-zA-Z]/ contained
syn match ponyInteger /\v0[bB]%([01]+_*)+/ contains=ponyErrNumGroup nextgroup=ponyErrIntBin
hi def link ponyErrIntDec Error
hi def link ponyErrIntHex Error
hi def link ponyErrIntBin Error
hi def link ponyInteger Number
syn match ponyFloat /\v%(\d+_*)+[eE][-+]?%(\d+_*)+/ contains=ponyErrNumGroup
syn match ponyFloat /\v%(\d+_*)+\.%(\d+_*)+%([eE][-+]?%(\d+_*)+)?/ contains=ponyErrNumGroup
hi def link ponyFloat Float
syn match ponyErrUserVariable /\v_>|<%([^_a-z]|_[^a-z])|__+/ contained
hi def link ponyErrUserVariable Error
syn match ponyUserVariable /\v[_a-zA-Z]\w*'*/ contained contains=ponyErrUserVariable
hi def link ponyUserVariable Identifier
syn match ponyErrUserPackage /\<[^a-z]/ contained
hi def link ponyErrUserPackage Error
syn match ponyUserPackage /\v[_a-zA-Z]\w*/ contained contains=ponyErrUserPackage
hi def link ponyUserPackage Identifier
syn match ponyErrUserType /\v_>|\a@<=_|<%([^_A-Z]|_[^A-Z])/ contained
hi def link ponyErrUserType Error
syn match ponyUserType2 /\v[_a-zA-Z]\w*/ contained contains=ponyErrUserType nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyGeneric,ponyArgument skipwhite
syn match ponyUserType /\v_?[A-Z]\w*/ contains=ponyErrUserType nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyGeneric,ponyArgument skipwhite
syn match ponyErrUserMethod /\v_>|<%([^_a-z]|_[^a-z])|__+/ contained
hi def link ponyErrUserMethod Error
syn match ponyUserMethod /\v[_a-zA-Z]\w*/ contained contains=ponyErrUserMethod nextgroup=ponyGeneric,ponyArgument,ponyBracketT2 skipwhite
hi def link ponyUserMethod Function
syn match ponyForeignFunction /\v[_a-zA-Z]\w*/ contained nextgroup=ponyGeneric skipwhite
hi def link ponyForeignFunction Macro
syn match ponyErrTupleIndex /\v_0+>/ contained
hi def link ponyErrTupleIndex Error
syn match ponyTupleIndex /\v_\d+\w@!/ contained contains=ponyErrTupleIndex
hi def link ponyTupleIndex Normal
syn keyword ponyBoolean true false
hi def link ponyBoolean Boolean
syn region ponyBracketT1 matchgroup=ponyBracket start=/(/ end=/)/ contained contains=@ponyComments,@ponyKeyword,@ponyType,@ponyBracketT,@ponyTypeOperator,ponySymbol,ponyPeriodComma nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyArgument skipwhite
syn region ponyBracketT2 matchgroup=ponyBracket start=/\[/ end=/\]/ contained contains=@ponyComments,@ponyKeyword,@ponyType,@ponyBracketT,@ponyTypeOperator,ponySymbol,ponyPeriodComma nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyArgument skipwhite
syn region ponyBracketT3 matchgroup=ponyBracket start=/{/ end=/}/ contained contains=@ponyComments,@ponyKeyword,@ponyType,@ponyBracketT,@ponyTypeOperator,ponySymbol,ponyPeriodComma nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyArgument skipwhite
syn cluster ponyBracketT contains=ponyBracketT\d
syn region ponyGeneric matchgroup=ponyBracketT2 start=/\[/ end=/\]/ contained contains=@ponyComments,@ponyKeyword,@ponyType,@ponyBracketT,@ponyTypeOperator,ponySymbol,ponyPeriodComma nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyArgument skipwhite
syn region ponyArgument matchgroup=ponyBracket start=/(/ end=/)/ contained contains=TOP nextgroup=ponyArgument skipwhite
syn match ponyTypeSuffix /[!^]/ contained nextgroup=ponyArgument,ponyKwOperatorT skipwhite
hi def link ponyTypeSuffix StorageClass
syn match ponyTypeOperator1 /[&|]/ contained nextgroup=@ponyBracketT,@ponyKeyword,@ponyType skipwhite skipempty
hi def link ponyTypeOperator1 Operator
syn match ponyTypeOperator2 /->\|<:/ contained nextgroup=@ponyBracketT,@ponyKeyword,@ponyType skipwhite skipempty
hi def link ponyTypeOperator2 Operator
syn cluster ponyTypeOperator contains=ponyTypeOperator\d
syn match ponyErrOperator /[-.]>\|<:\|\%(==\|!=\|<<\|>>\|<=\|>=\|[+*/%<>]\)\~\?\|[~.,]/ contained nextgroup=ponyErrOperator skipwhite
hi def link ponyErrOperator Error
syn match ponyObjectOperator /\%(==\|!=\|<<\|>>\|<=\|>=\|[+\-*/%<>]\)\~\?\|\~\|\.>/ nextgroup=ponyErrOperator skipwhite
hi def link ponyObjectOperator Operator
syn keyword ponyKwOperatorT is contained nextgroup=@ponyBracketT,@ponyKeyword,@ponyType skipwhite skipempty
hi def link ponyKwOperatorT Operator
syn keyword ponyKwOperator as nextgroup=@ponyBracketT,@ponyKeyword,@ponyType skipwhite skipempty
syn keyword ponyKwOperator and or xor not is isnt consume addressof digestof
hi def link ponyKwOperator Operator
syn match ponySymbol /=>\|[?#]/
syn match ponySymbol /@/ nextgroup=ponyForeignFunction skipwhite skipempty
syn match ponySymbol /:/ nextgroup=@ponyKeyword,@ponyType,@ponyBracketT skipwhite skipempty
hi def link ponySymbol Special
syn match ponyEllipsis /\.\{3}/ contained containedin=ponyArgument
hi def link ponyEllipsis Special
syn region ponyLambda matchgroup=ponyBracketLambda start=/{/ end=/}/ contains=ponyArgument,@ponyComments,@ponyKeyword,@ponyType,@ponyTypeOperator,ponySymbol,ponyPeriodComma,ponyLambdaBody nextgroup=ponyArgument skipwhite
syn match ponyLambdaBody /=>\_.*}/me=e-1 contained contains=TOP
hi def link ponyBracketLambda Special
" $scripts/gen_id.sh $packages/builtin
syn keyword ponyBuiltinType AmbientAuth Any Array ArrayKeys ArrayPairs
\ ArrayValues AsioEvent AsioEventID
\ AsioEventNotify Bool ByteSeq ByteSeqIter
\ Comparable Compare DisposableActor
\ DoNotOptimise Env Equal Equatable F32 F64
\ Float FloatingPoint Greater HasEq I128 I16 I32
\ I64 I8 ILong ISize Int Integer Iterator Less
\ MaybePointer None Number OutStream Platform
\ Pointer ReadElement ReadSeq Real Seq Signed
\ SourceLoc StdStream Stdin StdinNotify String
\ StringBytes StringRunes Stringable U128 U16
\ U32 U64 U8 ULong USize Unsigned
\ nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyGeneric,ponyArgument skipwhite
hi def link ponyBuiltinType Type
syn keyword ponyKwControl end if else do then elseif match while for in
\ repeat until ifdef try with recover return
\ break continue error compile_intrinsic
\ compile_error iftype elseiftype
hi def link ponyKwControl Keyword
syn keyword ponyCaseGuard if contained containedin=ponyMatchCase
hi def link ponyCaseGuard Keyword
syn region ponyMatchCase matchgroup=ponyKwBranchHead start=/|/ matchgroup=ponySymbol end=/=>/ contains=TOP
hi def link ponyKwBranchHead Keyword
syn keyword ponyKwAtom this nextgroup=ponyTypeOperator2 skipwhite skipempty
syn keyword ponyKwAtom object __loc
syn keyword ponyKwAtom lambda nextgroup=ponyArgument skipwhite
hi def link ponyKwAtom Keyword
syn keyword ponyKwField let var embed nextgroup=@ponyKeyword,ponyUserVariable skipwhite skipempty
hi def link ponyKwField Keyword
syn keyword ponyKwUse use nextgroup=ponyString,@ponyKeyword,ponyUserPackage skipwhite skipempty
hi def link ponyKwUse Include
syn keyword ponyKwWhere where
hi def link ponyKwWhere Keyword
syn keyword ponyKwTypedef type nextgroup=@ponyKeyword,@ponyType2 skipwhite skipempty
hi def link ponyKwTypedef Typedef
syn match ponyKwCapability /\v#%(read|send|share|alias|any)>/ nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT skipwhite
syn keyword ponyKwCapability ref val tag iso box trn nextgroup=ponyTypeSuffix,ponyTypeOperator2,ponyKwOperatorT,ponyArgument skipwhite
hi def link ponyKwCapability StorageClass
syn keyword ponyKwClass actor class struct primitive trait interface nextgroup=@ponyKeyword,@ponyType2 skipwhite skipempty
hi def link ponyKwClass Structure
syn keyword ponyKwFnCapability ref val tag iso box trn contained nextgroup=@ponyKeyword,ponyUserMethod skipwhite skipempty
hi def link ponyKwFnCapability StorageClass
syn keyword ponyKwFunction new be fun nextgroup=ponyKwFnCapability,@ponyKeyword,ponyUserMethod skipwhite skipempty
hi def link ponyKwFunction Keyword
syn cluster ponyKeyword contains=ponyKw.*,ponyBoolean,ponyBuiltinType remove=ponyKwOperatorT,ponyKwFnCapability,ponyKwBranchHead
syn cluster ponyType contains=ponyBuiltinType,ponyUserType,ponyNormal
syn cluster ponyType2 contains=ponyBuiltinType,ponyUserType2
syn cluster ponyComments contains=ponyNestedComment,ponyComment
syn match ponyErrEscape /\\\_.\?\_s*/ contained
hi def link ponyErrEscape Error
syn match ponyEscapeSQuote /\\'/ contained
hi def link ponyEscapeSQuote SpecialChar
syn match ponyEscapeDQuote /\\"/ contained
hi def link ponyEscapeDQuote SpecialChar
syn match ponyEscape /\\[abefnrtv\\0]/ contained
syn match ponyEscape /\v\\x\x{2}/ contained
syn match ponyEscape /\v\\u\x{4}/ contained
syn match ponyEscape /\v\\U\x{6}/ contained
hi def link ponyEscape SpecialChar
syn region ponyCharacter matchgroup=ponyCharacterX start=/\w\@<!'/ skip=/\\./ end=/'/ contains=ponyEscapeSQuote,ponyEscape,ponyErrEscape
hi def link ponyCharacter Character
syn region ponyString matchgroup=ponyStringX start=/"/ skip=/\\./ end=/"/ contains=ponyEscapeDQuote,ponyEscape,ponyErrEscape
hi def link ponyString String
syn region ponyDocumentString matchgroup=ponyDocumentStringX start=/"\ze""/ end=/"""*\zs"/
hi def link ponyDocumentString String
syn keyword ponyCommentShit XXX contained
hi def link ponyCommentShit Underlined
syn keyword ponyCommentDamn FIXME contained
hi def link ponyCommentDamn Error
syn keyword ponyCommentTodo TODO contained
hi def link ponyCommentTodo Todo
syn cluster ponyCommentNote contains=ponyCommentTodo,ponyCommentDamn,ponyCommentShit
syn match ponyComment @//.*$@ contains=@ponyCommentNote,ponyCommentX
hi def link ponyComment Comment
syn region ponyNestedComment matchgroup=ponyNestedCommentX start=@/\ze\*@ end=@\/\@<!\*\zs/@ contains=ponyNestedComment,@ponyCommentNote keepend extend fold
hi def link ponyNestedComment Comment
" for indent check
syn match ponyCommentX @/\ze/.*$@ contained transparent
hi def link ponyNestedCommentX Comment
hi def link ponyCharacterX Character
hi def link ponyStringX String
hi def link ponyDocumentStringX String
let &cpo = s:cpo_save
unlet s:cpo_save
let b:current_syntax = 'pony'
endif