| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | " Vim indent file | 
					
						
							|  |  |  | " Language:     Erlang | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  | " 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 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | if exists("b:did_indent") | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     finish | 
					
						
							|  |  |  | else | 
					
						
							|  |  |  |     let b:did_indent = 1 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | setlocal indentexpr=ErlangIndent() | 
					
						
							|  |  |  | setlocal indentkeys+==after,=end,=catch,=),=],=} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  | " Only define the functions once | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | if exists("*ErlangIndent") | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     finish | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  | " 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 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     " The missing guard from the split function head | 
					
						
							|  |  |  |     if a:line =~# '^\s*when\s\+.*->' | 
					
						
							|  |  |  |         return -1 | 
					
						
							|  |  |  |     endif | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     while 0<=i && i<linelen | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |         " m: the next value of the i | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                 let ind = ind - 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |                 let last_fun = 0 | 
					
						
							|  |  |  |                 let last_receive = 0 | 
					
						
							|  |  |  |             elseif a:line[(i):(m-1)] =~# '^\%(case\|if\|try\)$' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                 let ind = ind + 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             elseif a:line[(i):(m-1)] =~# '^receive$' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                 let ind = ind + 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |                 let last_receive = 1 | 
					
						
							|  |  |  |             elseif a:line[(i):(m-1)] =~# '^begin$' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                 let ind = ind + 2 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |                 let last_receive = 0 | 
					
						
							|  |  |  |             elseif a:line[(i):(m-1)] =~# '^end$' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                 let ind = ind - 2 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |                 let last_receive = 0 | 
					
						
							|  |  |  |             elseif a:line[(i):(m-1)] =~# '^after$' | 
					
						
							|  |  |  |                 if last_receive == 0 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                     let ind = ind - 1 | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     let ind = ind + 0 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |                 endif | 
					
						
							|  |  |  |                 let last_receive = 0 | 
					
						
							|  |  |  |             elseif a:line[(i):(m-1)] =~# '^fun$' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |                 let ind = ind + 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |                 let last_fun = 1 | 
					
						
							|  |  |  |                 let last_receive = 0 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             endif | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |         elseif a:line[i] =~# "[A-Z_]" | 
					
						
							|  |  |  |             let m = matchend(a:line,".[[:alnum:]_]*",i) | 
					
						
							|  |  |  |             let last_receive = 0 | 
					
						
							|  |  |  |         elseif a:line[i] == '$' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+2 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let last_receive = 0 | 
					
						
							|  |  |  |         elseif a:line[i] == "." && (i+1>=linelen || a:line[i+1]!~ "[0-9]") | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             if last_hash_sym | 
					
						
							|  |  |  |                 let last_hash_sym = 0 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             else | 
					
						
							|  |  |  |                 let ind = ind - 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             endif | 
					
						
							|  |  |  |             let last_receive = 0 | 
					
						
							|  |  |  |         elseif a:line[i] == '-' && (i+1<linelen && a:line[i+1]=='>') | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+2 | 
					
						
							|  |  |  |             let ind = ind + 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let last_receive = 0 | 
					
						
							|  |  |  |         elseif a:line[i] == ';' && a:line[(i):(linelen)] !~# '.*->.*' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+1 | 
					
						
							|  |  |  |             let ind = ind - 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let last_receive = 0 | 
					
						
							|  |  |  |         elseif a:line[i] == '#' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let last_hash_sym = 1 | 
					
						
							|  |  |  |         elseif a:line[i] =~# '[({[]' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+1 | 
					
						
							|  |  |  |             let ind = ind + 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let last_fun = 0 | 
					
						
							|  |  |  |             let last_receive = 0 | 
					
						
							|  |  |  |             let last_hash_sym = 0 | 
					
						
							|  |  |  |         elseif a:line[i] =~# '[)}\]]' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |             let m = i+1 | 
					
						
							|  |  |  |             let ind = ind - 1 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let last_receive = 0 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     " Continue to search above if the current line begins with a '%' | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |     while line =~# '^\s*%.*$' | 
					
						
							|  |  |  |         let lnum = prevnonblank(lnum - 1) | 
					
						
							|  |  |  |         if 0 == lnum | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |         endif | 
					
						
							|  |  |  |         let line = getline(lnum) | 
					
						
							|  |  |  |     endwhile | 
					
						
							|  |  |  |     return lnum | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  | " 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 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  | function ErlangIndent() | 
					
						
							|  |  |  |     " Find a non-blank line above the current line | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |     let lnum = prevnonblank(v:lnum - 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     " Hit the start of the file, use zero indent | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |     if lnum == 0 | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let prevline = getline(lnum) | 
					
						
							|  |  |  |     let currline = getline(v:lnum) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |     " Special cases: | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |     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*\%(%.*\)\=$' | 
					
						
							|  |  |  |             " If the 'receive' is not in the same line as the 'after' | 
					
						
							| 
									
										
										
										
											2012-01-20 21:08:56 +01:00
										 |  |  |             let ind = ind - 1*&sw | 
					
						
							| 
									
										
										
										
											2008-06-24 21:16:56 +00:00
										 |  |  |         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 |