" Vim indent file " Language: Erlang " Author: Csaba Hoch " Contributors: Edwin Fine " Pawel 'kTT' Salata " Ricardo Catalinas Jiménez " License: Vim license " Version: 2011/09/06 " Only load this indent file when no other was loaded if exists("b:did_indent") finish else let b:did_indent = 1 endif setlocal indentexpr=ErlangIndent() setlocal indentkeys+==after,=end,=catch,=),=],=} " Only define the functions once if exists("*ErlangIndent") finish endif " 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 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 " 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 || a:line[i+1]!~ "[0-9]") let m = i+1 if last_hash_sym let last_hash_sym = 0 else let ind = ind - 1 endif let last_receive = 0 elseif a:line[i] == '-' && (i+1') let m = i+2 let ind = ind + 1 let last_receive = 0 elseif a:line[i] == ';' && a:line[(i):(linelen)] !~# '.*->.*' let m = i+1 let ind = ind - 1 let last_receive = 0 elseif a:line[i] == '#' let m = i+1 let last_hash_sym = 1 elseif a:line[i] =~# '[({[]' let m = i+1 let ind = ind + 1 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 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 '%' while line =~# '^\s*%.*$' let lnum = prevnonblank(lnum - 1) if 0 == lnum return 0 endif let line = getline(lnum) endwhile return lnum endfunction " 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 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 if lnum == 0 return 0 endif let prevline = getline(lnum) let currline = getline(v:lnum) 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: 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) =~# '^[^%]*\\s*\%(%.*\)\=$' " If the 'receive' is not in the same line as the 'after' let ind = ind - 1*&sw 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