blob: 4899020f8591ab28db79e3368ace69945364e5e2 [file] [log] [blame]
Bram Moolenaar6be7f872012-01-20 21:08:56 +01001" Vim ftplugin file
2" Language: Erlang
3" Author: Oscar Hellström <oscar@oscarh.net>
4" Contributors: Ricardo Catalinas Jiménez <jimenezrick@gmail.com>
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()