vim-polyglot/indent/elixir.vim

98 lines
3.0 KiB
VimL
Raw Normal View History

if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'elixir') == -1
2013-09-12 11:31:56 -04:00
setlocal nosmartindent
2016-12-20 14:57:20 -05:00
setlocal indentexpr=elixir#indent()
setlocal indentkeys+=0),0],0=\|>,=->
setlocal indentkeys+=0=end,0=else,0=match,0=elsif,0=catch,0=after,0=rescue
2013-09-12 11:31:56 -04:00
2016-12-20 14:57:20 -05:00
if exists("b:did_indent") || exists("*elixir#indent")
2013-09-12 11:31:56 -04:00
finish
2016-09-11 07:24:17 -04:00
end
2016-12-20 14:57:20 -05:00
let b:did_indent = 1
2013-09-12 11:31:56 -04:00
let s:cpo_save = &cpo
set cpo&vim
2016-12-20 14:57:20 -05:00
function! elixir#indent()
" initiates the `old_ind` dictionary
let b:old_ind = get(b:, 'old_ind', {})
2017-02-02 15:16:29 -05:00
" initiates the `line` dictionary
2016-12-20 14:57:20 -05:00
let line = s:build_line(v:lnum)
2014-12-09 17:09:20 -05:00
2016-12-20 14:57:20 -05:00
if s:is_beginning_of_file(line)
" Reset `old_ind` dictionary at the beginning of the file
let b:old_ind = {}
" At the start of the file use zero indent.
return 0
elseif !s:is_indentable_line(line)
" Keep last line indentation if the current line does not have an
" indentable syntax
2017-02-02 15:16:29 -05:00
return indent(line.last_non_blank.num)
2016-09-11 07:24:17 -04:00
else
2016-12-20 14:57:20 -05:00
" Calculates the indenation level based on the rules
2017-02-02 15:16:29 -05:00
" All the rules are defined in `autoload/elixir/indent.vim`
let ind = indent(line.last_non_blank.num)
call s:debug('>>> line = ' . string(line.current))
call s:debug('>>> ind = ' . ind)
let ind = s:indent('deindent_case_arrow', ind, line)
let ind = s:indent('indent_parenthesis', ind, line)
let ind = s:indent('indent_square_brackets', ind, line)
let ind = s:indent('indent_brackets', ind, line)
let ind = s:indent('deindent_opened_symbols', ind, line)
let ind = s:indent('indent_pipeline_assignment', ind, line)
let ind = s:indent('indent_pipeline_continuation', ind, line)
let ind = s:indent('indent_after_pipeline', ind, line)
let ind = s:indent('indent_assignment', ind, line)
let ind = s:indent('indent_ending_symbols', ind, line)
let ind = s:indent('indent_keywords', ind, line)
let ind = s:indent('deindent_keywords', ind, line)
let ind = s:indent('deindent_ending_symbols', ind, line)
let ind = s:indent('indent_case_arrow', ind, line)
let ind = s:indent('indent_ecto_queries', ind, line)
call s:debug('<<< final = ' . ind)
2016-12-20 14:57:20 -05:00
return ind
2016-09-11 07:24:17 -04:00
end
endfunction
2017-02-02 15:16:29 -05:00
function s:indent(rule, ind, line)
let Fn = function('elixir#indent#'.a:rule)
let ind = Fn(a:ind, a:line)
call s:debug(a:rule . ' = ' . ind)
return ind
endfunction
function s:debug(message)
if get(g:, 'elixir_indent_debug', 0)
echom a:message
end
endfunction
2016-12-20 14:57:20 -05:00
function! s:is_beginning_of_file(line)
2017-02-02 15:16:29 -05:00
return a:line.last_non_blank.num == 0
2016-09-11 07:24:17 -04:00
endfunction
2016-12-20 14:57:20 -05:00
function! s:is_indentable_line(line)
return elixir#util#is_indentable_at(a:line.current.num, 1)
2016-09-11 07:24:17 -04:00
endfunction
2014-01-09 05:59:09 -05:00
2016-12-20 14:57:20 -05:00
function! s:build_line(line)
2017-02-02 15:16:29 -05:00
let line = { 'current': {}, 'last': {}, 'last_non_blank': {} }
let line.current = s:new_line(a:line)
let line.last = s:new_line(line.current.num - 1)
let line.last_non_blank = s:new_line(prevnonblank(line.current.num - 1))
2016-09-11 07:24:17 -04:00
2016-12-20 14:57:20 -05:00
return line
2013-09-12 11:31:56 -04:00
endfunction
2017-02-02 15:16:29 -05:00
function! s:new_line(num)
return {
\ "num": a:num,
\ "text": getline(a:num)
\ }
endfunction
2013-09-12 11:31:56 -04:00
let &cpo = s:cpo_save
unlet s:cpo_save
endif