[align] Align all occurences in the selected lines

This commit is contained in:
Thomas Kolb 2013-10-10 19:59:51 +02:00
parent 9acb8cc3d1
commit 35e14c526d
1 changed files with 34 additions and 18 deletions

View File

@ -1,3 +1,7 @@
if !exists('g:Align_StartIncrement')
let g:Align_StartIncrement = 4
endif
if !exists('g:Align_DefaultSeq') if !exists('g:Align_DefaultSeq')
let g:Align_DefaultSeq = {} let g:Align_DefaultSeq = {}
endif endif
@ -9,53 +13,65 @@ let g:Align_DefaultSeq['vhdl'] = '<=\|:\|:=\|=>'
let g:Align_DefaultSeq['vim'] = '=' let g:Align_DefaultSeq['vim'] = '='
function! s:Align(...) range function! s:Align(...) range
" If sequence is not set, find the default pattern for the current filetype " If pattern is not set, find the default pattern for the current filetype
if !exists("a:1") if !exists("a:1")
if !exists("g:Align_DefaultSeq[&filetype]") if !exists("g:Align_DefaultSeq[&filetype]")
echoerr "No Pattern was given and no default pattern could be found. Doing nothing." echoerr "No Pattern was given and no default pattern could be found. Doing nothing."
return return
endif endif
let l:sequence = g:Align_DefaultSeq[&filetype] let l:pattern = g:Align_DefaultSeq[&filetype]
else else
let l:sequence = a:1 let l:pattern = a:1
endif endif
" First, find the rightmost occurence of sequence in all lines let l:nextstart = 0
let l:index = 0 while l:nextstart >= 0
for i in range(a:firstline, a:lastline) let l:nextstart = s:AlignOnce(l:nextstart, l:pattern, a:firstline, a:lastline)
if l:nextstart != -1
let l:nextstart = l:nextstart + g:Align_StartIncrement
endif
endwhile
endfunction
function! s:AlignOnce(startpos, pattern, startline, endline)
" First, find the rightmost occurence of pattern in all lines
let l:index = -1
for i in range(a:startline, a:endline)
let l:line = getline(i) let l:line = getline(i)
let l:seqpos = match(l:line, l:sequence) let l:pos = match(l:line, a:pattern, a:startpos)
if l:seqpos > l:index if l:pos > l:index
let l:index = l:seqpos let l:index = l:pos
endif endif
endfor endfor
" Now, for each line, find the first occurrence of sequence, and insert " Now, for each line, find the first occurrence of pattern, and insert
" spaces until sequence was shifted to l:index " spaces until pattern was shifted to l:index
for i in range(a:firstline, a:lastline) for i in range(a:startline, a:endline)
let l:line = getline(i) let l:line = getline(i)
let l:seqpos = match(l:line, l:sequence) let l:pos = match(l:line, a:pattern, a:startpos)
if l:seqpos == -1 if l:pos == -1
continue continue
endif endif
" Build string of spaces " Build string of spaces
let l:spaces = "" let l:spaces = ""
for j in range(l:seqpos, l:index-1) for j in range(l:pos, l:index-1)
let l:spaces = l:spaces . ' ' let l:spaces = l:spaces . ' '
endfor endfor
" Insert spaces right before the sequence " Insert spaces right before the pattern
if l:seqpos > 0 if l:pos > 0
let l:line = l:line[: l:seqpos-1] . l:spaces . l:line[l:seqpos :] let l:line = l:line[: l:pos-1] . l:spaces . l:line[l:pos :]
else else
let l:line = l:spaces . l:line let l:line = l:spaces . l:line
endif endif
call setline(i, l:line) call setline(i, l:line)
endfor endfor
return l:index
endfunction endfunction
command! -nargs=? -range Align <line1>,<line2>call s:Align(<args>) command! -nargs=? -range Align <line1>,<line2>call s:Align(<args>)