Mercurial > hg > RemoteEditor > vim7
diff runtime/indent/erlang.vim @ 48:67300faee616 v7-3-618
v7-3-618
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 01 Aug 2012 18:08:28 +0900 |
parents | db46d51a3939 |
children |
line wrap: on
line diff
--- a/runtime/indent/erlang.vim Wed Aug 01 18:03:06 2012 +0900 +++ b/runtime/indent/erlang.vim Wed Aug 01 18:08:28 2012 +0900 @@ -1,128 +1,144 @@ " Vim indent file " Language: Erlang -" Maintainer: Csaba Hoch <csaba.hoch@gmail.com> -" Contributor: Edwin Fine <efine145_nospam01 at usa dot net> -" Last Change: 2008 Mar 12 +" Author: Csaba Hoch <csaba.hoch@gmail.com> +" Contributors: Edwin Fine <efine145_nospam01 at usa dot net> +" Pawel 'kTT' Salata <rockplayer.pl@gmail.com> +" Ricardo Catalinas Jiménez <jimenezrick@gmail.com> +" License: Vim license +" Version: 2011/09/06 -" Only load this indent file when no other was loaded. +" Only load this indent file when no other was loaded if exists("b:did_indent") - finish + finish +else + let b:did_indent = 1 endif -let b:did_indent = 1 setlocal indentexpr=ErlangIndent() setlocal indentkeys+==after,=end,=catch,=),=],=} -" Only define the functions once. +" Only define the functions once if exists("*ErlangIndent") - finish + finish 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:ErlangIndentAtferLine(l) - let i = 0 " the index of the current character in the line - let length = strlen(a:l) " the length of the line +" The function goes through the whole line, analyses it and returns the +" indentation level. +" +" line: the line to be examined +" return: the indentation level of the examined line +function s:ErlangIndentAfterLine(line) + let linelen = strlen(a:line) " the length of the line + let i = 0 " the index of the current character in 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' + let last_fun = 0 " the last token was a 'fun' + let last_receive = 0 " the last token was a 'receive'; needed for 'after' + let last_hash_sym = 0 " the last token was a '#' + + " Ignore comments + if a:line =~# '^\s*%' + return 0 + endif - while 0<= i && i < length + " Partial function head where the guard is missing + if a:line =~# "\\(^\\l[[:alnum:]_]*\\)\\|\\(^'[^']\\+'\\)(" && a:line !~# '->' + return 2 + endif + " The missing guard from the split function head + if a:line =~# '^\s*when\s\+.*->' + return -1 + endif + + while 0<=i && i<linelen " 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 + if a:line[i] == '"' + let m = matchend(a:line,'"\%([^"\\]\|\\.\)*"',i) + let last_receive = 0 + elseif a:line[i] == "'" + let m = matchend(a:line,"'[^']*'",i) + let last_receive = 0 + elseif a:line[i] =~# "[a-z]" + let m = matchend(a:line,".[[:alnum:]_]*",i) + if last_fun let ind = ind - 1 - let lastFun = 0 - let lastReceive = 0 - elseif a:l[(i):(m-1)] =~# '^\%(case\|if\|try\)$' + let last_fun = 0 + let last_receive = 0 + elseif a:line[(i):(m-1)] =~# '^\%(case\|if\|try\)$' let ind = ind + 1 - elseif a:l[(i):(m-1)] =~# '^receive$' + elseif a:line[(i):(m-1)] =~# '^receive$' let ind = ind + 1 - let lastReceive = 1 - elseif a:l[(i):(m-1)] =~# '^begin$' + let last_receive = 1 + elseif a:line[(i):(m-1)] =~# '^begin$' let ind = ind + 2 - let lastReceive = 0 - elseif a:l[(i):(m-1)] =~# '^end$' + let last_receive = 0 + elseif a:line[(i):(m-1)] =~# '^end$' let ind = ind - 2 - let lastReceive = 0 - elseif a:l[(i):(m-1)] =~# '^after$' - if lastReceive == 0 + let last_receive = 0 + elseif a:line[(i):(m-1)] =~# '^after$' + if last_receive == 0 let ind = ind - 1 else let ind = ind + 0 - end - let lastReceive = 0 - elseif a:l[(i):(m-1)] =~# '^fun$' + endif + let last_receive = 0 + elseif a:line[(i):(m-1)] =~# '^fun$' let ind = ind + 1 - let lastFun = 1 - let lastReceive = 0 + let last_fun = 1 + let last_receive = 0 endif - elseif a:l[i] =~# "[A-Z_]" - let m = matchend(a:l,".[[:alnum:]_]*",i) - let lastReceive = 0 - elseif a:l[i] == '$' + elseif a:line[i] =~# "[A-Z_]" + let m = matchend(a:line,".[[:alnum:]_]*",i) + let last_receive = 0 + elseif a:line[i] == '$' let m = i+2 - let lastReceive = 0 - elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]") + let last_receive = 0 + elseif a:line[i] == "." && (i+1>=linelen || a:line[i+1]!~ "[0-9]") let m = i+1 - if lastHashMark - let lastHashMark = 0 + if last_hash_sym + let last_hash_sym = 0 else let ind = ind - 1 - end - let lastReceive = 0 - elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>') + endif + let last_receive = 0 + elseif a:line[i] == '-' && (i+1<linelen && a:line[i+1]=='>') let m = i+2 let ind = ind + 1 - let lastReceive = 0 - elseif a:l[i] == ';' + let last_receive = 0 + elseif a:line[i] == ';' && a:line[(i):(linelen)] !~# '.*->.*' let m = i+1 let ind = ind - 1 - let lastReceive = 0 - elseif a:l[i] == '#' + let last_receive = 0 + elseif a:line[i] == '#' let m = i+1 - let lastHashMark = 1 - elseif a:l[i] =~# '[({[]' + let last_hash_sym = 1 + elseif a:line[i] =~# '[({[]' let m = i+1 let ind = ind + 1 - let lastFun = 0 - let lastReceive = 0 - let lastHashMark = 0 - elseif a:l[i] =~# '[)}\]]' + let last_fun = 0 + let last_receive = 0 + let last_hash_sym = 0 + elseif a:line[i] =~# '[)}\]]' let m = i+1 let ind = ind - 1 - let lastReceive = 0 + let last_receive = 0 else let m = i+1 endif let i = m - endwhile return ind - endfunction function s:FindPrevNonBlankNonComment(lnum) let lnum = prevnonblank(a:lnum) let line = getline(lnum) - " continue to search above if the current line begins with a '%' + " Continue to search above if the current line begins with a '%' while line =~# '^\s*%.*$' let lnum = prevnonblank(lnum - 1) if 0 == lnum @@ -133,12 +149,20 @@ return lnum endfunction -function ErlangIndent() +" The function returns the indentation level of the line adjusted to a mutiple +" of 'shiftwidth' option. +" +" lnum: line number +" return: the indentation level of the line +function s:GetLineIndent(lnum) + return (indent(a:lnum) / &sw) * &sw +endfunction - " Find a non-blank line above the current line. +function ErlangIndent() + " Find a non-blank line above the current line let lnum = prevnonblank(v:lnum - 1) - " Hit the start of the file, use zero indent. + " Hit the start of the file, use zero indent if lnum == 0 return 0 endif @@ -146,9 +170,14 @@ let prevline = getline(lnum) let currline = getline(v:lnum) - let ind = indent(lnum) + &sw * s:ErlangIndentAtferLine(prevline) + let ind_after = s:ErlangIndentAfterLine(prevline) + if ind_after != 0 + let ind = s:GetLineIndent(lnum) + ind_after * &sw + else + let ind = indent(lnum) + ind_after * &sw + endif - " special cases: + " Special cases: if prevline =~# '^\s*\%(after\|end\)\>' let ind = ind + 2*&sw endif @@ -158,8 +187,8 @@ if currline =~# '^\s*after\>' let plnum = s:FindPrevNonBlankNonComment(v:lnum-1) if getline(plnum) =~# '^[^%]*\<receive\>\s*\%(%.*\)\=$' + " If the 'receive' is not in the same line as the 'after' let ind = ind - 1*&sw - " If the 'receive' is not in the same line as the 'after' else let ind = ind - 2*&sw endif @@ -181,26 +210,4 @@ let ind = 0 endif return ind - endfunction - -" TODO: -" -" f() -> -" x("foo -" bar") -" , -" bad_indent. -" -" fun -" init/0, -" bad_indent -" -" #rec -" .field, -" bad_indent -" -" case X of -" 1 when A; B -> -" bad_indent -