]> git.donarmstrong.com Git - dsa-puppet.git/blob - tools/vim/ftplugin/puppet.vim
add tools directory
[dsa-puppet.git] / tools / vim / ftplugin / puppet.vim
1 " Vim filetype plugin
2 " Language:     Puppet
3 " Maintainer:   Todd Zullinger <tmz@pobox.com>
4 " Last Change:  2009 Aug 19
5 " vim: set sw=4 sts=4:
6
7 if exists("b:did_ftplugin")
8     finish
9 endif
10 let b:did_ftplugin = 1
11
12 if !exists("no_plugin_maps") && !exists("no_puppet_maps")
13     if !hasmapto("<Plug>AlignRange")
14         map <buffer> <LocalLeader>= <Plug>AlignRange
15     endif
16 endif
17
18 noremap <buffer> <unique> <script> <Plug>AlignArrows :call <SID>AlignArrows()<CR>
19 noremap <buffer> <unique> <script> <Plug>AlignRange :call <SID>AlignRange()<CR>
20
21 iabbrev => =><C-R>=<SID>AlignArrows('=>')<CR>
22 iabbrev +> +><C-R>=<SID>AlignArrows('+>')<CR>
23
24 if exists('*s:AlignArrows')
25     finish
26 endif
27
28 let s:arrow_re = '[=+]>'
29 let s:selector_re = '[=+]>\s*\$.*\s*?\s*{\s*$'
30
31 function! s:AlignArrows(op)
32     let cursor_pos = getpos('.')
33     let lnum = line('.')
34     let line = getline(lnum)
35     if line !~ s:arrow_re
36         return
37     endif
38     let pos = stridx(line, a:op)
39     let start = lnum
40     let end = lnum
41     let pnum = lnum - 1
42     while 1
43         let pline = getline(pnum)
44         if pline !~ s:arrow_re || pline =~ s:selector_re
45             break
46         endif
47         let start = pnum
48         let pnum -= 1
49     endwhile
50     let cnum = end
51     while 1
52         let cline = getline(cnum)
53         if cline !~ s:arrow_re ||
54                 \ (indent(cnum) != indent(cnum+1) && getline(cnum+1) !~ '\s*}')
55             break
56         endif
57         let end = cnum
58         let cnum += 1
59     endwhile
60     call s:AlignSection(start, end)
61     let cursor_pos[2] = stridx(getline('.'), a:op) + strlen(a:op) + 1
62     call setpos('.', cursor_pos)
63     return ''
64 endfunction
65
66 function! s:AlignRange() range
67     call s:AlignSection(a:firstline, a:lastline)
68 endfunction
69
70 " AlignSection and AlignLine are from the vim wiki:
71 " http://vim.wikia.com/wiki/Regex-based_text_alignment
72 function! s:AlignSection(start, end)
73     let extra = 1
74     let sep = s:arrow_re
75     let maxpos = 0
76     let section = getline(a:start, a:end)
77     for line in section
78         let pos = match(line, ' *'.sep)
79         if maxpos < pos
80             let maxpos = pos
81         endif
82     endfor
83     call map(section, 's:AlignLine(v:val, sep, maxpos, extra)')
84     call setline(a:start, section)
85 endfunction
86
87 function! s:AlignLine(line, sep, maxpos, extra)
88     let m = matchlist(a:line, '\(.\{-}\) \{-}\('.a:sep.'.*\)')
89     if empty(m)
90         return a:line
91     endif
92     let spaces = repeat(' ', a:maxpos - strlen(m[1]) + a:extra)
93     return m[1] . spaces . m[2]
94 endfunction