summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--autoload/pony.vim536
-rwxr-xr-xbuild1
-rw-r--r--ftdetect/polyglot.vim7
-rw-r--r--ftplugin/pony.vim44
-rw-r--r--indent/pony.vim41
-rw-r--r--syntax/pony.vim231
7 files changed, 862 insertions, 1 deletions
diff --git a/README.md b/README.md
index b88c54ed..2e9b1013 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ A collection of language packs for Vim.
> One to rule them all, one to find them, one to bring them all and in the darkness bind them.
- It **won't affect your startup time**, as scripts are loaded only on demand\*.
-- It **installs and updates 100+ times faster** than the <!--Package Count-->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)
diff --git a/autoload/pony.vim b/autoload/pony.vim
new file mode 100644
index 00000000..51568aa4
--- /dev/null
+++ b/autoload/pony.vim
@@ -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
diff --git a/build b/build
index 8346a913..9b5d6f1b 100755
--- a/build
+++ b/build
@@ -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
diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim
index 62aaf3ab..888f78eb 100644
--- a/ftdetect/polyglot.vim
+++ b/ftdetect/polyglot.vim
@@ -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
diff --git a/ftplugin/pony.vim b/ftplugin/pony.vim
new file mode 100644
index 00000000..eef6824e
--- /dev/null
+++ b/ftplugin/pony.vim
@@ -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
diff --git a/indent/pony.vim b/indent/pony.vim
new file mode 100644
index 00000000..613dae6e
--- /dev/null
+++ b/indent/pony.vim
@@ -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
diff --git a/syntax/pony.vim b/syntax/pony.vim
new file mode 100644
index 00000000..56899f8f
--- /dev/null
+++ b/syntax/pony.vim
@@ -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