xref: /vim-8.2.3635/runtime/indent/elm.vim (revision 1d59aa1f)
1" Elm indent plugin file
2" Language: Elm
3" Maintainer: Andreas Scharf <[email protected]>
4" Original Author: Joseph Hager <[email protected]>
5" Copyright: Joseph Hager <[email protected]>
6" License: BSD3
7" Latest Revision: 2020-05-29
8
9" Only load this indent file when no other was loaded.
10if exists('b:did_indent')
11	finish
12endif
13let b:did_indent = 1
14
15" Local defaults
16setlocal expandtab
17setlocal indentexpr=GetElmIndent()
18setlocal indentkeys+=0=else,0=if,0=of,0=import,0=then,0=type,0\|,0},0\],0),=-},0=in
19setlocal nolisp
20setlocal nosmartindent
21
22" Only define the function once.
23if exists('*GetElmIndent')
24	finish
25endif
26
27" Indent pairs
28function! s:FindPair(pstart, pmid, pend)
29	"call search(a:pend, 'bW')
30	return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
31endfunction
32
33function! GetElmIndent()
34	let l:lnum = v:lnum - 1
35
36	" Ident 0 if the first line of the file:
37	if l:lnum == 0
38		return 0
39	endif
40
41	let l:ind = indent(l:lnum)
42	let l:lline = getline(l:lnum)
43	let l:line = getline(v:lnum)
44
45	" Indent if current line begins with '}':
46	if l:line =~? '^\s*}'
47		return s:FindPair('{', '', '}')
48
49	" Indent if current line begins with 'else':
50	elseif l:line =~# '^\s*else\>'
51		if l:lline !~# '^\s*\(if\|then\)\>'
52			return s:FindPair('\<if\>', '', '\<else\>')
53		endif
54
55	" Indent if current line begins with 'then':
56	elseif l:line =~# '^\s*then\>'
57		if l:lline !~# '^\s*\(if\|else\)\>'
58			return s:FindPair('\<if\>', '', '\<then\>')
59		endif
60
61	" HACK: Indent lines in case with nearest case clause:
62	elseif l:line =~# '->' && l:line !~# ':' && l:line !~# '\\'
63		return indent(search('^\s*case', 'bWn')) + &shiftwidth
64
65	" HACK: Don't change the indentation if the last line is a comment.
66	elseif l:lline =~# '^\s*--'
67		return l:ind
68
69	" Align the end of block comments with the start
70	elseif l:line =~# '^\s*-}'
71		return indent(search('{-', 'bWn'))
72
73	" Indent double shift after let with an empty rhs
74	elseif l:lline =~# '\<let\>.*\s=$'
75		return l:ind + 4 + &shiftwidth
76
77	" Align 'in' with the parent let.
78	elseif l:line =~# '^\s*in\>'
79		return indent(search('^\s*let', 'bWn'))
80
81	" Align bindings with the parent let.
82	elseif l:lline =~# '\<let\>'
83		return l:ind + 4
84
85	" Align bindings with the parent in.
86	elseif l:lline =~# '^\s*in\>'
87		return l:ind
88
89	endif
90
91	" Add a 'shiftwidth' after lines ending with:
92	if l:lline =~# '\(|\|=\|->\|<-\|(\|\[\|{\|\<\(of\|else\|if\|then\)\)\s*$'
93		let l:ind = l:ind + &shiftwidth
94
95	" Add a 'shiftwidth' after lines starting with type ending with '=':
96	elseif l:lline =~# '^\s*type' && l:line =~# '^\s*='
97		let l:ind = l:ind + &shiftwidth
98
99	" Back to normal indent after comments:
100	elseif l:lline =~# '-}\s*$'
101		call search('-}', 'bW')
102		let l:ind = indent(searchpair('{-', '', '-}', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"'))
103
104	" Ident some operators if there aren't any starting the last line.
105	elseif l:line =~# '^\s*\(!\|&\|(\|`\|+\||\|{\|[\|,\)=' && l:lline !~# '^\s*\(!\|&\|(\|`\|+\||\|{\|[\|,\)=' && l:lline !~# '^\s*$'
106		let l:ind = l:ind + &shiftwidth
107
108	elseif l:lline ==# '' && getline(l:lnum - 1) !=# ''
109		let l:ind = indent(search('^\s*\S+', 'bWn'))
110
111	endif
112
113	return l:ind
114endfunc
115