diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2013-09-17 02:02:37 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2013-09-17 02:02:37 +0200 |
commit | 0fcd056648da760f727a7296bae364ea5c4b5e98 (patch) | |
tree | b935dab5daabd233312525d6a46d0b110c971803 /indent/erlang.vim | |
parent | 78cd7e48cb05e99fb2b87abcdc2255ac84d9833e (diff) | |
download | vim-polyglot-0fcd056648da760f727a7296bae364ea5c4b5e98.tar.gz vim-polyglot-0fcd056648da760f727a7296bae364ea5c4b5e98.zip |
fix: Switch erlang to oscarh/vimerl (it doesnt use plugin dir)
Diffstat (limited to 'indent/erlang.vim')
-rw-r--r-- | indent/erlang.vim | 235 |
1 files changed, 192 insertions, 43 deletions
diff --git a/indent/erlang.vim b/indent/erlang.vim index 370a8810..61833f74 100644 --- a/indent/erlang.vim +++ b/indent/erlang.vim @@ -1,58 +1,207 @@ " Vim indent file -" Language: Erlang -" Author: Ricardo Catalinas Jiménez <jimenezrick@gmail.com> -" License: Vim license -" Version: 2013/09/11 +" Language: Erlang +" Maintainer: Csaba Hoch <csaba.hoch@gmail.com> +" Contributor: Edwin Fine <efine145_nospam01 at usa dot net> +" Contributor: Pawel 'kTT' Salata <rockplayer.pl@gmail.com> +" Last Change: 2010 Aug 30 -if !exists('g:erlang_force_use_vimerl_indent') - let g:erlang_force_use_vimerl_indent = 0 -endif - -if exists('b:did_indent') || (v:version >= 704 && !g:erlang_force_use_vimerl_indent) - finish -else - let b:did_indent = 1 +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish endif +let b:did_indent = 1 setlocal indentexpr=ErlangIndent() -setlocal indentkeys=!^F,o,O,=),=},=],=>>,=of,=catch,=after,=end +setlocal indentkeys+==after,=end,=catch,=),=],=} -if exists('*ErlangIndent') - finish +" Only define the functions once. +if exists("*ErlangIndent") + finish endif -let s:erlang_indent_file = expand('<sfile>:p:h') . '/erlang_indent.erl' -if filewritable(expand('<sfile>:p:h')) == 2 - let s:in_fifo = expand('<sfile>:p:h') . '/vimerl_in_fifo.' . getpid() - let s:out_fifo = expand('<sfile>:p:h') . '/vimerl_out_fifo.' . getpid() -else - let s:in_fifo = '/tmp/vimerl_in_fifo.' . getpid() - let s:out_fifo = '/tmp/vimerl_out_fifo.' . getpid() -endif +" The function go through the whole line, analyses it and sets the indentation +" (ind variable). +" l: the number of the line to be examined. +function s:ErlangIndentAfterLine(l) + let i = 0 " the index of the current character in the line + let length = strlen(a:l) " the length of the line + let ind = 0 " how much should be the difference between the indentation of + " the current line and the indentation of the next line? + " e.g. +1: the indentation of the next line should be equal to + " the indentation of the current line plus one shiftwidth + let lastFun = 0 " the last token was a 'fun' + let lastReceive = 0 " the last token was a 'receive'; needed for 'after' + let lastHashMark = 0 " the last token was a 'hashmark' + + " ignore type annotation lines + if a:l =~# '^\s*-type' + return 0 + endif + + while 0<= i && i < length -execute 'silent !mkfifo' s:in_fifo -execute 'silent !mkfifo' s:out_fifo -execute 'silent !' . s:erlang_indent_file s:out_fifo s:in_fifo '&' + " m: the next value of the i + if a:l[i] == '%' + break + elseif a:l[i] == '"' + let m = matchend(a:l,'"\%([^"\\]\|\\.\)*"',i) + let lastReceive = 0 + elseif a:l[i] == "'" + let m = matchend(a:l,"'[^']*'",i) + let lastReceive = 0 + elseif a:l[i] =~# "[a-z]" + let m = matchend(a:l,".[[:alnum:]_]*",i) + if lastFun + let ind = ind - 1 + let lastFun = 0 + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^\%(case\|if\|try\)$' + let ind = ind + 1 + elseif a:l[(i):(m-1)] =~# '^receive$' + let ind = ind + 1 + let lastReceive = 1 + elseif a:l[(i):(m-1)] =~# '^begin$' + let ind = ind + 2 + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^end$' + let ind = ind - 2 + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^after$' + if lastReceive == 0 + let ind = ind - 1 + else + let ind = ind + 0 + endif + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^fun$' + let ind = ind + 1 + let lastFun = 1 + let lastReceive = 0 + endif + elseif a:l[i] =~# "[A-Z_]" + let m = matchend(a:l,".[[:alnum:]_]*",i) + let lastReceive = 0 + elseif a:l[i] == '$' + let m = i+2 + let lastReceive = 0 + elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]") + let m = i+1 + if lastHashMark + let lastHashMark = 0 + else + let ind = ind - 1 + endif + let lastReceive = 0 + elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>') + let m = i+2 + let ind = ind + 1 + let lastReceive = 0 + elseif a:l[i] == ';' && a:l[(i):(length)] !~# '.*->.*' + let m = i+1 + let ind = ind - 1 + let lastReceive = 0 + elseif a:l[i] == '#' + let m = i+1 + let lastHashMark = 1 + elseif a:l[i] =~# '[({[]' + let m = i+1 + let ind = ind + 1 + let lastFun = 0 + let lastReceive = 0 + let lastHashMark = 0 + elseif a:l[i] =~# '[)}\]]' + let m = i+1 + let ind = ind - 1 + let lastReceive = 0 + else + let m = i+1 + endif -autocmd VimLeave * call <SID>StopIndenter() + let i = m + + endwhile + + return ind + +endfunction -function s:StopIndenter() - call writefile([], s:out_fifo) - call delete(s:in_fifo) - call delete(s:out_fifo) +function s:FindPrevNonBlankNonComment(lnum) + let lnum = prevnonblank(a:lnum) + let line = getline(lnum) + " continue to search above if the current line begins with a '%' + while line =~# '^\s*%.*$' + let lnum = prevnonblank(lnum - 1) + if 0 == lnum + return 0 + endif + let line = getline(lnum) + endwhile + return lnum endfunction function ErlangIndent() - if v:lnum == 1 - return 0 - else - call writefile([v:lnum] + getline(1, v:lnum), s:out_fifo) - let indent = split(readfile(s:in_fifo)[0]) - - if len(indent) == 1 || !&expandtab - return indent[0] * &shiftwidth - else - return indent[1] - endif - endif + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + let prevline = getline(lnum) + let currline = getline(v:lnum) + + let ind = indent(lnum) + &sw * s:ErlangIndentAfterLine(prevline) + + " special cases: + if prevline =~# '^\s*\%(after\|end\)\>' + let ind = ind + 2*&sw + endif + if currline =~# '^\s*end\>' + let ind = ind - 2*&sw + endif + if currline =~# '^\s*after\>' + let plnum = s:FindPrevNonBlankNonComment(v:lnum-1) + if getline(plnum) =~# '^[^%]*\<receive\>\s*\%(%.*\)\=$' + let ind = ind - 1*&sw + " If the 'receive' is not in the same line as the 'after' + else + let ind = ind - 2*&sw + endif + endif + if prevline =~# '^\s*[)}\]]' + let ind = ind + 1*&sw + endif + if currline =~# '^\s*[)}\]]' + let ind = ind - 1*&sw + endif + if prevline =~# '^\s*\%(catch\)\s*\%(%\|$\)' + let ind = ind + 1*&sw + endif + if currline =~# '^\s*\%(catch\)\s*\%(%\|$\)' + let ind = ind - 1*&sw + endif + + if ind<0 + let ind = 0 + endif + return ind + endfunction + +" TODO: +" +" f() -> +" x("foo +" bar") +" , +" bad_indent. +" +" fun +" init/0, +" bad_indent +" +" #rec +" .field, +" bad_indent |