diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2017-09-27 19:57:29 +0200 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2017-09-27 19:57:29 +0200 | 
| commit | 8b3418cab8eb5267b3a5743e4d5fe5f698d48bc8 (patch) | |
| tree | 125734ac66307a962eeda16283355dde0d0fbd2e /indent/purescript.vim | |
| parent | 9bfde7574aa89a91b80ed9c993fc000cfc11aae7 (diff) | |
| download | vim-polyglot-8b3418cab8eb5267b3a5743e4d5fe5f698d48bc8.tar.gz vim-polyglot-8b3418cab8eb5267b3a5743e4d5fe5f698d48bc8.zip  | |
Update
Diffstat (limited to '')
| -rw-r--r-- | indent/purescript.vim | 203 | 
1 files changed, 171 insertions, 32 deletions
diff --git a/indent/purescript.vim b/indent/purescript.vim index c456c608..c22da095 100644 --- a/indent/purescript.vim +++ b/indent/purescript.vim @@ -37,9 +37,16 @@ if !exists('g:purescript_indent_let')    let g:purescript_indent_let = 4  endif +if !exists('g:purescript_indent_in') +  " let x = 0 +  " >in +  let g:purescript_indent_in = 1 +endif +  if !exists('g:purescript_indent_where') -  " where f :: Int -> Int -  " >>>>>>f x = x +  " where +  " >>f :: Int -> Int +  " >>f x = x    let g:purescript_indent_where = 6  endif @@ -49,16 +56,29 @@ if !exists('g:purescript_indent_do')    let g:purescript_indent_do = 3  endif +if !exists('g:purescript_indent_dot') +  " f +  "   :: forall a +  "   >. String +  "   -> String +  let g:purescript_indent_dot = 1 +endif +  setlocal indentexpr=GetPurescriptIndent() -setlocal indentkeys=!^F,o,O,},=where,=in +setlocal indentkeys=!^F,o,O,},=where,=in,=::,=->,=→,==>,=⇒ + +function! s:GetSynStack(lnum, col) +  return map(synstack(a:lnum, a:col), { key, val -> synIDattr(val, "name") }) +endfunction  function! GetPurescriptIndent() +  let ppline = getline(v:lnum - 2)    let prevline = getline(v:lnum - 1)    let line = getline(v:lnum)    if line =~ '^\s*\<where\>' -    let s = match(prevline, '\S') -    return s + 2 +    let s = indent(v:lnum - 1) +    return max([s, &l:shiftwidth])    endif    if line =~ '^\s*\<in\>' @@ -67,72 +87,191 @@ function! GetPurescriptIndent()      while s <= 0 && n > 0        let n = n - 1 -      let s = match(getline(n),'\<let\>') +      let s = match(getline(n), '\<let\>') +      if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') != -1 +	let s = -1 +      endif      endwhile -    return s + 1 +    return s + g:purescript_indent_in +  endif + +  let s = match(prevline, '^\s*\zs\(--\|import\)') +  if s >= 0 +    " comments +    " imports +    return s +  endif + +  if prevline =~ '^\S.*::' && line !~ '^\s*\(\.\|->\|→\|=>\|⇒\)' && !~ '^instance' +    " f :: String +    "	-> String +    return 0 +  endif + +  let s = match(prevline, '[[:alnum:][:blank:]]\@<=|[[:alnum:][:blank:]$]') +  if s >= 0 && prevline !~ '^class\>' && index(s:GetSynStack(v:lnum - 1, s), "purescriptFunctionDecl") == -1 +    " ident pattern guards but not if we are in a type declaration +    " what we detect using syntax groups +    if prevline =~ '|\s*otherwise\>' +      return indent(search('^\s*\k', 'bnW')) +      " somehow this pattern does not work :/ +      " return indent(search('^\(\s*|\)\@!', 'bnW')) +    else +      return s +    endif +  endif + +  let s = match(line, '\%(\\.\{-}\)\@<=->') +  if s >= 0 +    " inline lambda +    return indent(v:lnum) +  endif + +  " indent rules for -> (lambdas and case expressions) +  let s = match(line, '->') +  let p = match(prevline, '\\') +  " protect that we are not in a type signature +  " and not in a case expression +  if s >= 0 && index(s:GetSynStack(s == 0 ? v:lnum - 1 : v:lnum, max([1, s])), "purescriptFunctionDecl") == -1 +    \ && p >= 0 &&  index(s:GetSynStack(v:lnum - 1, p), "purescriptString") == -1 +    return p +  endif + +  if prevline =~ '^\S' +    " start typing signature, function body, data & newtype on next line +    return &l:shiftwidth    endif -  if prevline =~ '[!#$%&*+./<>?@\\^|~-]\s*$' +  if ppline =~ '^\S' && prevline =~ '^\s*$' +    return 0 +  endif + +  if line =~ '^\s*\%(::\|∷\)' +    return match(prevline, '\S') + &l:shiftwidth +  endif + +  if prevline =~ '^\s*\(::\|∷\)\s*forall' +    return match(prevline, '\S') + g:purescript_indent_dot +  endif + +  let s = match(prevline, '^\s*\zs\%(::\|∷\|=>\|⇒\|->\|→\)') +  let r = match(prevline, '^\s*\zs\.') +  if s >= 0 || r >= 0 +    if s >= 0 +      if line !~ '^\s*\%(::\|∷\|=>\|⇒\|->\|→\)' && line !~ '^\s*$' +	return s - 2 +      else +	return s +      endif +    elseif r >= 0 +      if line !~ '^\s\%(::\|∷\|=>\|⇒\|->\|→\)' +	return r - g:purescript_indent_dot +      else +	return r +      endif +    endif +  endif + +  if prevline =~ '[!#$%&*+./<>?@\\^~-]\s*$'      let s = match(prevline, '=')      if s > 0 -      return s + 2 +      return s + &l:shiftwidth      endif -    let s = match(prevline, ':') +    let s = match(prevline, '\<:\>')      if s > 0 -      return s + 3 +      return s + &l:shiftwidth      else -      return match(prevline, '\S') +      return match(prevline, '\S') + &l:shiftwidth      endif    endif    if prevline =~ '[{([][^})\]]\+$' +    echom "return 1"      return match(prevline, '[{([]')    endif -  if prevline =~ '\<let\>\s\+.\+\(\<in\>\)\?\s*$' +  let s = match(prevline, '\<let\>\s\+\zs\S') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return s +  endif + +  let s = match(prevline, '\<let\>\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return s + g:purescript_indent_let +  endif + +  let s = match(prevline, '\<let\>\s\+.\+\(\<in\>\)\?\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1      return match(prevline, '\<let\>') + g:purescript_indent_let    endif -  if prevline !~ '\<else\>' -    let s = match(prevline, '\<if\>.*\&.*\zs\<then\>') -    if s > 0 -      return s +  let s = searchpairpos('\%(--.\{-}\)\@<!\<if\>', '\<then\>', '\<else\>.*\zs$', 'bnrc')[0] +  if s > 0 +    " this rule ensures that using `=` in visual mode will correctly indent +    " `if then else`, but it does not handle lines after `then` and `else` +    if line =~ '\<\%(then\|else\)\>' +      return match(getline(s), '\<if\>') + &l:shiftwidth      endif +  endif -    let s = match(prevline, '\<if\>') -    if s > 0 -      return s + g:purescript_indent_if -    endif +  let p = match(prevline, '\<if\>\%(.\{-}\<then\>.\{-}\<else\>\)\@!') +  if p > 0 +    return p + &l:shiftwidth +  endif + +  let s = match(prevline, '=\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return match(prevline, '\S') + &l:shiftwidth +  endif + +  let s = match(prevline, '[{([]\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return match(prevline, '\S') + (line !~ '^\s*[})]]' ? 0 : &l:shiftwidth) +  endif + +  if prevline =~ '^class' +    return &l:shiftwidth +  endif + +  let s = match(prevline, '\<where\>\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return match(prevline, '\S') + g:purescript_indent_where    endif -  if prevline =~ '\(\<where\>\|\<do\>\|=\|[{([]\)\s*$' -    return match(prevline, '\S') + &shiftwidth +  let s = match(prevline, '\<where\>\s\+\zs\S\+.*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return s    endif -  if prevline =~ '\<where\>\s\+\S\+.*$' -    return match(prevline, '\<where\>') + g:purescript_indent_where +  let s = match(prevline, '\<do\>\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return match(prevline, '\S') + g:purescript_indent_do    endif -  if prevline =~ '\<do\>\s\+\S\+.*$' -    return match(prevline, '\<do\>') + g:purescript_indent_do +  let s = match(prevline, '\<do\>\s\+\zs\S\+.*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return s    endif -  if prevline =~ '^\s*\<data\>\s\+[^=]\+\s\+=\s\+\S\+.*$' +  let s = match(prevline, '^\s*\<data\>\s\+[^=]\+\s\+=\s\+\S\+.*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1      return match(prevline, '=')    endif -  if prevline =~ '\<case\>\s\+.\+\<of\>\s*$' +  let s = match(prevline, '\<case\>\s\+.\+\<of\>\s*$') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1      return match(prevline, '\<case\>') + g:purescript_indent_case    endif    if prevline =~ '^\s*\<\data\>\s\+\S\+\s*$' -    return match(prevline, '\<data\>') + &shiftwidth +    return match(prevline, '\<data\>') + &l:shiftwidth    endif -  if (line =~ '^\s*}\s*' && prevline !~ '^\s*;') -    return match(prevline, '\S') - &shiftwidth +  let s = match(prevline, '^\s*[}\]]') +  if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1 +    return match(prevline, '\S') - &l:shiftwidth    endif    return match(prevline, '\S')  | 
