diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2016-05-02 10:42:37 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2016-05-02 10:42:37 +0200 |
commit | 5dd1a7e83966c92d220073185f1738dfe441f59e (patch) | |
tree | 9c4bee389a51a9bb111dcc894c9db0f6d1809d81 /indent/elixir.vim | |
parent | bc098370c1bb81840734f5764f431dee270e75ce (diff) | |
download | vim-polyglot-5dd1a7e83966c92d220073185f1738dfe441f59e.tar.gz vim-polyglot-5dd1a7e83966c92d220073185f1738dfe441f59e.zip |
Update
Diffstat (limited to 'indent/elixir.vim')
-rw-r--r-- | indent/elixir.vim | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/indent/elixir.vim b/indent/elixir.vim index 58179973..7ccaea12 100644 --- a/indent/elixir.vim +++ b/indent/elixir.vim @@ -17,16 +17,18 @@ endif let s:cpo_save = &cpo set cpo&vim -let s:no_colon_before = ':\@<!' -let s:no_colon_after = ':\@!' -let s:symbols_end = '\]\|}' -let s:arrow = '^.*->$' -let s:pipeline = '^\s*|>.*$' -let s:skip_syntax = '\%(Comment\|String\)$' -let s:block_skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '".s:skip_syntax."'" -let s:block_start = 'do\|fn' -let s:block_middle = 'else\|match\|elsif\|catch\|after\|rescue' -let s:block_end = 'end' +let s:no_colon_before = ':\@<!' +let s:no_colon_after = ':\@!' +let s:symbols_end = '\]\|}\|)' +let s:symbols_start = '\[\|{\|(' +let s:arrow = '^.*->$' +let s:skip_syntax = '\%(Comment\|String\)$' +let s:block_skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '".s:skip_syntax."'" +let s:block_start = '\<\%(do\|fn\)\>' +let s:block_middle = 'else\|match\|elsif\|catch\|after\|rescue' +let s:block_end = 'end' +let s:starts_with_pipeline = '^\s*|>.*$' +let s:ending_with_assignment = '=\s*$' let s:indent_keywords = '\<'.s:no_colon_before.'\%('.s:block_start.'\|'.s:block_middle.'\)$'.'\|'.s:arrow let s:deindent_keywords = '^\s*\<\%('.s:block_end.'\|'.s:block_middle.'\)\>'.'\|'.s:arrow @@ -35,15 +37,21 @@ let s:pair_start = '\<\%('.s:no_colon_before.s:block_start.'\)\>'.s:no_colon_af let s:pair_middle = '\<\%('.s:block_middle.'\)\>'.s:no_colon_after.'\zs' let s:pair_end = '\<\%('.s:no_colon_before.s:block_end.'\)\>\zs' +let s:inside_block = 0 + function! GetElixirIndent() let lnum = prevnonblank(v:lnum - 1) - let ind = indent(lnum) " At the start of the file use zero indent. if lnum == 0 return 0 endif + let opened_symbol = 0 + let current_line = getline(v:lnum) + let last_line = getline(lnum) + let ind = indent(lnum) + " TODO: Remove these 2 lines " I don't know why, but for the test on spec/indent/lists_spec.rb:24. " Vim is making some mess on parsing the syntax of 'end', it is being @@ -53,15 +61,22 @@ function! GetElixirIndent() syntax sync fromstart if synIDattr(synID(v:lnum, 1, 1), "name") !~ s:skip_syntax - let current_line = getline(v:lnum) - let last_line = getline(lnum) - let splited_line = split(last_line, '\zs') - let opened_symbol = 0 - let opened_symbol += count(splited_line, '[') - count(splited_line, ']') - let opened_symbol += count(splited_line, '{') - count(splited_line, '}') - - let ind += (opened_symbol * &sw) + if last_line !~ s:arrow + let split_line = split(last_line, '\zs') + let opened_symbol += count(split_line, '(') - count(split_line, ')') + let opened_symbol += count(split_line, '[') - count(split_line, ']') + let opened_symbol += count(split_line, '{') - count(split_line, '}') + end + + " if start symbol is followed by a character, indent based on the + " whitespace after the symbol, otherwise use the default shiftwidth + if last_line =~ '\('.s:symbols_start.'\).' + let opened_prefix = matchlist(last_line, '\('.s:symbols_start.'\)\s*')[0] + let ind += (opened_symbol * strlen(opened_prefix)) + else + let ind += (opened_symbol * &sw) + endif if last_line =~ '^\s*\('.s:symbols_end.'\)' || last_line =~ s:indent_keywords let ind += &sw @@ -71,27 +86,35 @@ function! GetElixirIndent() let ind -= &sw endif + if last_line =~ s:ending_with_assignment && opened_symbol == 0 + let b:old_ind = indent(lnum) + let ind += &sw + end + " if line starts with pipeline - " and last line contains pipeline(s) + " and last line ends with a pipeline, " align them if last_line =~ '|>.*$' && - \ current_line =~ s:pipeline + \ current_line =~ s:starts_with_pipeline let ind = float2nr(match(last_line, '|>') / &sw) * &sw " if line starts with pipeline " and last line is an attribution " indents pipeline in same level as attribution - elseif current_line =~ s:pipeline && + elseif current_line =~ s:starts_with_pipeline && \ last_line =~ '^[^=]\+=.\+$' - let b:old_ind = ind + + if !exists('b:old_ind') || b:old_ind == 0 + let b:old_ind = indent(lnum) + end let ind = float2nr(matchend(last_line, '=\s*[^ ]') / &sw) * &sw endif " if last line starts with pipeline " and current line doesn't start with pipeline " returns the indentation before the pipeline - if last_line =~ s:pipeline && - \ current_line !~ s:pipeline + if last_line =~ s:starts_with_pipeline && + \ current_line !~ s:starts_with_pipeline let ind = b:old_ind endif |