summaryrefslogblamecommitdiffstats
path: root/indent/puppet.vim
blob: 977e8606fabd8092ce172c782c1df0d293f9949c (plain) (tree)
1
2
3
4
5
6
7
8



                                                                              
                 


                                              









                                     
                                          
















                                                      
                                                               







                           

                                                                                  

           





















                                                                             



                
                              


                             
























                                                                               
                                              


                                                       
                                                             






                                             

                                                           


                                             



                                            











                                                                                 
 

              
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'puppet') != -1
  finish
endif

" Vim indent file
" Language: Puppet
" Maintainer:   Todd Zullinger <tmz@pobox.com>
" Last Change:  2009 Aug 19
" vim: set sw=4 sts=4:

if exists("b:did_indent")
    finish
endif
let b:did_indent = 1

setlocal autoindent smartindent
setlocal indentexpr=GetPuppetIndent()
setlocal indentkeys+=0],0)
setlocal formatexpr=puppet#format#Format()

if exists("*GetPuppetIndent")
    finish
endif

" Check if a line is part of an include 'block', e.g.:
"   include foo,
"       bar,
"       baz
function! s:PartOfInclude(lnum)
    let lnum = a:lnum
    while lnum
        let lnum = lnum - 1
        let line = getline(lnum)
        if line !~ ',$'
            break
        endif
        if line =~ '^\s*include\s\+[^,]\+,$' && line !~ '[=>]>'
            return 1
        endif
    endwhile
    return 0
endfunction

function! s:OpenBrace(lnum)
    call cursor(a:lnum, 1)
    return searchpair('{\|\[\|(', '', '}\|\]\|)', 'nbW',
      \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "comment\\|string"')
endfunction

function! s:InsideMultilineString(lnum)
    return synIDattr(synID(a:lnum, 1, 0), 'name') =~? 'string'
endfunction

function! s:PrevNonMultilineString(lnum)
    let l:lnum = a:lnum
    while l:lnum > 0 && s:InsideMultilineString(lnum)
        let l:lnum = l:lnum - 1
    endwhile

    return l:lnum
endfunction

""
" Get indent number for line, line can be given as params, otherwise function
" use line where cursor is
" @param a:1 (optional) line number in current buffer
" @return integer
function! GetPuppetIndent(...)
    let l:lnum = get(a:, 1, v:lnum)

    let pnum = prevnonblank(l:lnum - 1)
    if pnum == 0
       return 0
    endif

    let line = getline(l:lnum)
    let pline = getline(pnum)
    let ind = indent(pnum)

    " Avoid cases of closing braces or parens on the current line: returning
    " the same indent here would be premature since for that particular case
    " we want to instead get the indent level of the matching opening brace or
    " parenthenses.
    if pline =~ '^\s*#' && line !~ '^\s*\(}\(,\|;\)\?$\|]:\|],\|}]\|];\?$\|)\)'
        return ind
    endif

    " We are inside a multi-line string: if we interfere with indentation here
    " we're actually changing the contents of of the string!
    if s:InsideMultilineString(l:lnum)
        return indent(l:lnum)
    endif

    " Previous line was inside a multi-line string: we've lost the indent
    " level. We need to find this value from the last line that was not inside
    " of a multi-line string to restore proper alignment.
    if s:InsideMultilineString(pnum)
        if pnum - 1 == 0
            return ind
        endif

        let ind = indent(s:PrevNonMultilineString(pnum - 1))
    endif

    if pline =~ '\({\|\[\|(\|:\)\s*\(#.*\)\?$'
        let ind += &sw
    elseif pline =~ ';$' && pline !~ '[^:]\+:.*[=+]>.*'
        let ind -= &sw
    elseif pline =~ '^\s*include\s\+.*,$' && pline !~ '[=+]>'
        let ind += &sw
    endif

    if pline !~ ',$' && s:PartOfInclude(pnum)
        let ind -= &sw
    endif

    " Match } }, }; ] ]: ], ]; )
    if line =~ '^\s*\(}\(,\|;\)\?$\|]:\|],\|}]\|];\?$\|)\)'
        let ind = indent(s:OpenBrace(v:lnum))
    endif

    " Don't actually shift over for } else {
    if line =~ '^\s*}\s*els\(e\|if\).*{\s*$'
        let ind -= &sw
    endif
    " Don't indent resources that are one after another with a ->(ordering arrow)
    " file {'somefile':
    "    ...
    " } ->
    "
    " package { 'mycoolpackage':
    "    ...
    " }
    if line =~ '->$'
        let ind -= &sw
    endif


    return ind
endfunction