Skip to content
This repository was archived by the owner on May 25, 2019. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 94 additions & 15 deletions indent/ansible.vim
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,109 @@ if exists('*GetAnsibleIndent')
finish
endif

function GetAnsibleIndent(lnum)
" Check whether the user has set g:ansible_options["ignore_blank_lines"].
let ignore_blanks = !exists('g:ansible_options["ignore_blank_lines"]')
\ || g:ansible_options["ignore_blank_lines"]
" Check whether the user has set g:ansible_options["ignore_blank_lines"].
let s:ignore_blanks = !exists('g:ansible_options["ignore_blank_lines"]')
\ || g:ansible_options["ignore_blank_lines"]

" Indent list entries with extra &sw?
let s:indent_list_entries = get(g:ansible_options, 'indent_list_entries', 1)


" Patterns used internally.
let s:pat_comment = '\v^\s*#'
let s:pat_dict_start = '\v^\s*[^:-]+:\s*[>|]?$'
let s:pat_dict_item = '\v^\s*[^:-]+:\s*\S'
let s:pat_list_item = '\v^\s*-(\s|$)'


function s:get_prev_with_min_indent(lnum, pattern, ...)
let lnum = a:lnum
let minindent = a:0 ? a:1 : indent(a:lnum)
while 1
" XXX: does it make sense to handle s:ignore_blanks here?
let lnum = s:ignore_blanks ? prevnonblank(lnum - 1) : lnum - 1
if lnum == 0
return 0
endif
if indent(lnum) > minindent
continue
endif
if getline(lnum) =~ a:pattern
return lnum
endif
" Decrease min indent, when there was a non-matching/-empty line.
if getline(lnum) != ''
let minindent -= &sw
endif
endwhile
return 0
endfunction


" Get the start of the previous/current list.
function s:get_indent_for_li(lnum)
let prevlnum = s:get_prev_with_min_indent(a:lnum, s:pat_list_item.'|'.s:pat_dict_start)
if prevlnum > 0
if getline(prevlnum) =~ s:pat_dict_start
" Found the start of a (possible) list.
return indent(prevlnum) + (s:indent_list_entries * &sw)
endif
" Found a list entry point.
return indent(prevlnum)
endif
return -1
endfunction


let prevlnum = ignore_blanks ? prevnonblank(a:lnum - 1) : a:lnum - 1
function GetAnsibleIndent(lnum)
let prevlnum = s:ignore_blanks ? prevnonblank(a:lnum - 1) : a:lnum - 1
if prevlnum == 0
return 0
endif

let curline = getline(a:lnum)
let prevline = getline(prevlnum)
let previndent = indent(prevlnum)
let increase = previndent + &sw

let indent = indent(prevlnum)
let increase = indent + &sw
" Do not align comments.
if prevline =~ s:pat_comment
return previndent

" Do not adjust indentation for comments
if prevline =~ '\%(^\|\s\)#'
return indent
elseif prevline =~ ':\s*[>|]?$'
return increase
elseif prevline =~ '^\s*-\s*$'
" Handle "dict:".
elseif prevline =~ s:pat_dict_start
if getline(a:lnum) =~ s:pat_list_item && !s:indent_list_entries
return previndent
endif
return increase
elseif prevline =~ '^\s*-\s\+[^:]\+:\s*\S'

" Handle list-items.
elseif getline(a:lnum) =~ s:pat_list_item
return s:get_indent_for_li(a:lnum)

" Align "foo:".
" elseif getline(a:lnum) =~ '\v^\s*[^:-]+:\s*\S'
elseif curline =~ '\v^\s*[^:-]+:(\s|$)'
let l = s:get_prev_with_min_indent(a:lnum, s:pat_dict_item.'|'.s:pat_list_item.'|'.s:pat_dict_start)
if l > 0
let indent = indent(l)
if getline(l) =~ s:pat_list_item
" Special case: aligned to list item, needs to be indented.
let indent += &sw
endif
return indent
endif
" Fallback
return previndent

elseif prevline =~ s:pat_list_item
return increase

elseif curline =~ s:pat_comment
return -1

" Fallback: align to previous line.
else
return indent
return previndent
endif
endfunction