diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2016-09-11 13:24:17 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2016-09-11 13:24:17 +0200 |
commit | 0244e228faf6ee71750cbca3bdcd18411a927d22 (patch) | |
tree | a72e5c9839ea593f6edc23f7f0e637e0a4a89413 /indent/haskell.vim | |
parent | ab61d2ac8eafc9c10097577736602da48ec568ca (diff) | |
download | vim-polyglot-0244e228faf6ee71750cbca3bdcd18411a927d22.tar.gz vim-polyglot-0244e228faf6ee71750cbca3bdcd18411a927d22.zip |
Update
Diffstat (limited to 'indent/haskell.vim')
-rw-r--r-- | indent/haskell.vim | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/indent/haskell.vim b/indent/haskell.vim index 7aa94367..ebdab5e7 100644 --- a/indent/haskell.vim +++ b/indent/haskell.vim @@ -63,15 +63,32 @@ setlocal indentexpr=GetHaskellIndent() setlocal indentkeys=0{,0},0(,0),0[,0],!^F,o,O,0\=,0=where,0=let,0=deriving,<space> function! s:isInBlock(hlstack) - return index(a:hlstack, 'haskellParens') > -1 || index(a:hlstack, 'haskellBrackets') > -1 || index(a:hlstack, 'haskellBlock') > -1 + return index(a:hlstack, 'haskellParens') > -1 || index(a:hlstack, 'haskellBrackets') > -1 || index(a:hlstack, 'haskellBlock') > -1 || index(a:hlstack, 'haskellBlockComment') > -1 || index(a:hlstack, 'haskellPragma') > -1 +endfunction + +function! s:stripTrailingComment(line) + if a:line =~ '^\s*--\(-\+\|\s\+\)' || a:line =~ '^\s*{-' + return a:line + else + let l:stripped = split(a:line, '-- ') + if len(l:stripped) > 1 + return substitute(l:stripped[0], '\s*$', '', '') + else + return a:line + endif + endif +endfunction + +function! s:isSYN(grp, line, col) + return index(s:getHLStack(a:line, a:col), a:grp) != -1 endfunction function! s:getNesting(hlstack) - return filter(a:hlstack, 'v:val == "haskellBlock" || v:val == "haskellBrackets" || v:val == "haskellParens"') + return filter(a:hlstack, 'v:val == "haskellBlock" || v:val == "haskellBrackets" || v:val == "haskellParens" || v:val == "haskellBlockComment" || v:val == "haskellPragma" ') endfunction -function! s:getHLStack() - return map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') +function! s:getHLStack(line, col) + return map(synstack(a:line, a:col), 'synIDattr(v:val, "name")') endfunction " indent matching character @@ -110,14 +127,14 @@ function! s:indentGuard(pos, prevline) endfunction function! GetHaskellIndent() - let l:hlstack = s:getHLStack() + let l:hlstack = s:getHLStack(line('.'), col('.')) " do not indent in strings and quasiquotes if index(l:hlstack, 'haskellQuasiQuote') > -1 || index(l:hlstack, 'haskellBlockComment') > -1 return -1 endif - let l:prevline = getline(v:lnum - 1) + let l:prevline = s:stripTrailingComment(getline(v:lnum - 1)) let l:line = getline(v:lnum) " indent multiline strings @@ -138,6 +155,9 @@ function! GetHaskellIndent() if l:line =~ '^\s*--' return match(l:prevline, '-- ') endif + if l:prevline =~ '^\s*--' + return match(l:prevline, '\S') + endif " { foo :: Int " >>, @@ -149,14 +169,18 @@ function! GetHaskellIndent() if s:isInBlock(l:hlstack) normal! 0 call search(',', 'cW') - let l:n = s:getNesting(s:getHLStack()) + let l:n = s:getNesting(s:getHLStack(line('.'), col('.'))) call search('[([{]', 'bW') + let l:cl = line('.') + let l:cc = col('.') - while l:n != s:getNesting(s:getHLStack()) + while l:n != s:getNesting(s:getHLStack(l:cl, l:cc)) || s:isSYN('haskellString', l:cl, l:cc) || s:isSYN('haskellChar', l:cl, l:cc) call search('[([{]', 'bW') + let l:cl = line('.') + let l:cc = col('.') endwhile - return col('.') - 1 + return l:cc - 1 else let l:s = s:indentGuard(match(l:line, ','), l:prevline) if l:s > -1 @@ -192,11 +216,20 @@ function! GetHaskellIndent() " >>>>y = 2 if l:prevline =~ '\C\<let\>\s\+.\+$' if l:line =~ '\C^\s*\<let\>' - return match(l:prevline, '\C\<let\>') + let l:s = match(l:prevline, '\C\<let\>') + if s:isSYN('haskellLet', v:lnum - 1, l:s + 1) + return l:s + endif elseif l:line =~ '\C^\s*\<in\>' - return match(l:prevline, '\C\<let\>') + g:haskell_indent_in + let l:s = match(l:prevline, '\C\<let\>') + if s:isSYN('haskellLet', v:lnum - 1, l:s + 1) + return l:s + g:haskell_indent_in + endif else - return match(l:prevline, '\C\<let\>') + g:haskell_indent_let + let l:s = match(l:prevline, '\C\<let\>') + if s:isSYN('haskellLet', v:lnum - 1, l:s + 1) + return l:s + g:haskell_indent_let + endif endif endif @@ -225,20 +258,13 @@ function! GetHaskellIndent() return match(l:prevline, '\S') + &shiftwidth endif - "" where foo - "" >>>>>>bar - if l:prevline =~ '\C\<where\>\s\+\S\+.*$' - if l:line =~ '^\s*[=-]>\s' && l:prevline =~ ' :: ' - return match(l:prevline, ':: ') - else - return match(l:prevline, '\C\<where\>') + g:haskell_indent_where - endif - endif - " do foo " >>>bar if l:prevline =~ '\C\<do\>\s\+\S\+.*$' - return match(l:prevline, '\C\<do\>') + g:haskell_indent_do + let l:s = match(l:prevline, '\C\<do\>') + if s:isSYN('haskellKeyword', v:lnum - 1, l:s + 1) + return l:s + g:haskell_indent_do + endif endif " case foo of @@ -247,6 +273,19 @@ function! GetHaskellIndent() return match(l:prevline, '\C\<case\>') + g:haskell_indent_case endif + "" where foo + "" >>>>>>bar + if l:prevline =~ '\C\<where\>\s\+\S\+.*$' + if l:line =~ '^\s*[=-]>\s' && l:prevline =~ ' :: ' + return match(l:prevline, ':: ') + else + let l:s = match(l:prevline, '\C\<where\>') + if s:isSYN('haskellWhere', v:lnum - 1, l:s + 1) + return l:s + g:haskell_indent_where + endif + endif + endif + " newtype Foo = Foo " >>deriving if l:prevline =~ '\C\s*\<\(newtype\|data\)\>[^{]\+' && l:line =~ '\C^\s*\<deriving\>' |