1" Vim ftplugin file 2" Language: Erlang 3" Author: Oscar Hellström <[email protected]> 4" Contributors: Ricardo Catalinas Jiménez <[email protected]> 5" Eduardo Lopez (http://github.com/tapichu) 6" License: Vim license 7" Version: 2011/11/21 8 9if exists('b:did_ftplugin') 10 finish 11else 12 let b:did_ftplugin = 1 13endif 14 15if exists('s:did_function_definitions') 16 call s:SetErlangOptions() 17 finish 18else 19 let s:did_function_definitions = 1 20endif 21 22if !exists('g:erlang_keywordprg') 23 let g:erlang_keywordprg = 'erl -man' 24endif 25 26if !exists('g:erlang_folding') 27 let g:erlang_folding = 0 28endif 29 30" Local settings 31function s:SetErlangOptions() 32 compiler erlang 33 if version >= 700 34 setlocal omnifunc=erlang_complete#Complete 35 endif 36 37 if g:erlang_folding 38 setlocal foldmethod=expr 39 setlocal foldexpr=GetErlangFold(v:lnum) 40 setlocal foldtext=ErlangFoldText() 41 endif 42 43 setlocal comments=:%%%,:%%,:% 44 setlocal commentstring=%%s 45 46 setlocal formatoptions+=ro 47 let &l:keywordprg = g:erlang_keywordprg 48endfunction 49 50" Define folding functions 51if !exists('*GetErlangFold') 52 " Folding params 53 let s:erlang_fun_begin = '^\a\w*(.*$' 54 let s:erlang_fun_end = '^[^%]*\.\s*\(%.*\)\?$' 55 let s:erlang_blank_line = '^\s*\(%.*\)\?$' 56 57 " Auxiliary fold functions 58 function s:GetNextNonBlank(lnum) 59 let lnum = nextnonblank(a:lnum + 1) 60 let line = getline(lnum) 61 while line =~ s:erlang_blank_line && 0 != lnum 62 let lnum = nextnonblank(lnum + 1) 63 let line = getline(lnum) 64 endwhile 65 return lnum 66 endfunction 67 68 function s:GetFunName(str) 69 return matchstr(a:str, '^\a\w*(\@=') 70 endfunction 71 72 function s:GetFunArgs(str, lnum) 73 let str = a:str 74 let lnum = a:lnum 75 while str !~ '->\s*\(%.*\)\?$' 76 let lnum = s:GetNextNonBlank(lnum) 77 if 0 == lnum " EOF 78 return '' 79 endif 80 let str .= getline(lnum) 81 endwhile 82 return matchstr(str, 83 \ '\(^(\s*\)\@<=.*\(\s*)\(\s\+when\s\+.*\)\?\s\+->\s*\(%.*\)\?$\)\@=') 84 endfunction 85 86 function s:CountFunArgs(arguments) 87 let pos = 0 88 let ac = 0 " arg count 89 let arguments = a:arguments 90 91 " Change list / tuples into just one A(rgument) 92 let erlang_tuple = '{\([A-Za-z_,|=\-\[\]]\|\s\)*}' 93 let erlang_list = '\[\([A-Za-z_,|=\-{}]\|\s\)*\]' 94 95 " FIXME: Use searchpair? 96 while arguments =~ erlang_tuple 97 let arguments = substitute(arguments, erlang_tuple, 'A', 'g') 98 endwhile 99 " FIXME: Use searchpair? 100 while arguments =~ erlang_list 101 let arguments = substitute(arguments, erlang_list, 'A', 'g') 102 endwhile 103 104 let len = strlen(arguments) 105 while pos < len && pos > -1 106 let ac += 1 107 let pos = matchend(arguments, ',\s*', pos) 108 endwhile 109 return ac 110 endfunction 111 112 " Main fold function 113 function GetErlangFold(lnum) 114 let lnum = a:lnum 115 let line = getline(lnum) 116 117 if line =~ s:erlang_fun_end 118 return '<1' 119 endif 120 121 if line =~ s:erlang_fun_begin && foldlevel(lnum - 1) == 1 122 return '1' 123 endif 124 125 if line =~ s:erlang_fun_begin 126 return '>1' 127 endif 128 129 return '=' 130 endfunction 131 132 " Erlang fold description (foldtext function) 133 function ErlangFoldText() 134 let foldlen = v:foldend - v:foldstart 135 if 1 < foldlen 136 let lines = 'lines' 137 else 138 let lines = 'line' 139 endif 140 let line = getline(v:foldstart) 141 let name = s:GetFunName(line) 142 let arguments = s:GetFunArgs(strpart(line, strlen(name)), v:foldstart) 143 let argcount = s:CountFunArgs(arguments) 144 let retval = '+' . v:folddashes . ' ' . name . '/' . argcount 145 let retval .= ' (' . foldlen . ' ' . lines . ')' 146 return retval 147 endfunction 148endif 149 150call s:SetErlangOptions() 151