@@ -17,60 +17,44 @@ if exists("*GetElixirIndent")
1717 finish
1818endif
1919
20- let s: elixir_indent_keywords = ' \%(\<\(case\|cond\|if\|unless\|try\|loop\|receive\)\>\|' .
21- \ ' ^\s*\(defmodule\|defimpl\|defmacro\|defdelegate\|defexception\|defcallback\|defoverridable\|defp\|def\|test\|[a-z]\w*\(:\)\@=\)\|' .
22- \ ' fn(.*)\s\(do\|->\)$\)'
20+ let s: cpo_save = &cpo
21+ set cpo &vim
2322
24- let s: elixir_clauses = ' ^\s*\(else\|match\|elsif\|catch\|after\|rescue\|end\)\>'
23+ let s: skip_syntax = ' \%(Comment\|String\)$'
24+ let s: block_skip = " synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . s: skip_syntax . " '"
25+ let s: block_start = ' do\|fn'
26+ let s: block_middle = ' else\|match\|elsif\|catch\|after\|rescue'
27+ let s: block_end = ' end'
2528
26- function ! s: BlockStarter (lnum, block_start_re)
27- let lnum = a: lnum
28- let maxindent = 10000
29- while lnum > 1
30- if indent (lnum) < maxindent
31- if getline (lnum) = ~ a: block_start_re
32- return lnum
33- else
34- let maxindent = indent (lnum)
35- if maxindent == 0
36- return -1
37- endif
38- endif
39- endif
40- let lnum = prevnonblank (lnum - 1 )
41- endwhile
42- return -1
43- endfunction
29+ let s: indent_keywords = ' \<\%(' . s: block_start . ' \|' . s: block_middle . ' \)$'
30+ let s: deindent_keywords = ' ^\s*\<\%(' . s: block_end . ' \|' . s: block_middle . ' \)\>'
4431
45- function ! GetElixirIndent (line_num)
46- " don't indent if it's the first line of the file
47- if a: line_num == 0
48- return 0
49- endif
50-
51- let this_line = getline (a: line_num )
32+ function ! GetElixirIndent (... )
33+ let lnum = prevnonblank (v: lnum - 1 )
34+ let ind = indent (lnum)
5235
53- if this_line = ~ s: elixir_clauses
54- let bslnum = s: BlockStarter (a: line_num , s: elixir_indent_keywords )
55- if bslnum > 0
56- return indent (bslnum)
57- else
58- return -1
59- endif
36+ " At the start of the file use zero indent.
37+ if lnum == 0
38+ return 0
6039 endif
6140
62- let plnum = a: line_num - 1
63- let previous_line = getline (plnum)
64-
65- if previous_line = ~ ' \(do\|when\|->\)$\|^\s*\(^.*[\[{(].*[,:]$\)'
66- return indent (plnum) + &sw
41+ if getline (lnum) = ~ s: indent_keywords .
42+ \ ' \|^\s*\%(^.*[\[{(].*[,:]\|.*->\)$'
43+ let ind += &sw
6744 endif
6845
69- " blank lines are indented based on the previous not blank line"
70- if previous_line = ~ ' ^\s*$'
71- let nonblank = prevnonblank (a: line_num )
72- return indent (nonblank)
46+ if getline (v: lnum ) = ~ s: deindent_keywords
47+ let bslnum = searchpair (
48+ \ ' \<\%(' . s: block_start . ' \)\>' ,
49+ \ ' \<\%(' . s: block_middle . ' \)\>\zs' ,
50+ \ ' [^:]\<' . s: block_end . ' \>\zs' ,
51+ \ ' nbW' ,
52+ \ s: block_skip )
53+ let ind = indent (bslnum)
7354 endif
7455
75- return indent (plnum)
56+ return ind
7657endfunction
58+
59+ let &cpo = s: cpo_save
60+ unlet s: cpo_save
0 commit comments