diff options
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | autoload/pony.vim | 536 | ||||
| -rwxr-xr-x | build | 1 | ||||
| -rw-r--r-- | ftdetect/polyglot.vim | 7 | ||||
| -rw-r--r-- | ftplugin/pony.vim | 44 | ||||
| -rw-r--r-- | indent/pony.vim | 41 | ||||
| -rw-r--r-- | syntax/pony.vim | 231 | 
7 files changed, 862 insertions, 1 deletions
| @@ -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 @@ -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 | 
