xref: /vim-8.2.3635/runtime/ftplugin/erlang.vim (revision 6be7f873)
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