Skip to content

Commit e92f7b4

Browse files
committed
Merge pull request elixir-editors#47 from LnL7/fix-indent
Rewrite of indentation, now uses searchpair()
2 parents a4e9073 + 4b13b95 commit e92f7b4

File tree

1 file changed

+30
-46
lines changed

1 file changed

+30
-46
lines changed

indent/elixir.vim

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,60 +17,44 @@ if exists("*GetElixirIndent")
1717
finish
1818
endif
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
7657
endfunction
58+
59+
let &cpo = s:cpo_save
60+
unlet s:cpo_save

0 commit comments

Comments
 (0)