Add option to update indent after exchange

This commit is contained in:
Jacob Niehus 2015-05-07 20:19:16 -07:00
parent e459b57740
commit aff4ade39b
2 changed files with 56 additions and 0 deletions

View File

@ -75,6 +75,14 @@ g:exchange_no_mappings ~
If this variable is defined, the default mappings will not be created. If this variable is defined, the default mappings will not be created.
*g:exchange_indent*
g:exchange_indent ~
If this variable is defined and non-zero, linewise exchanges will swap
indents. Alternatively, setting the option to '==' will re-indent the
exchanged text with |==|. This behavior can be configured per buffer by
setting b:exchange_indent.
ISSUES AND TODO *exchange-issues* ISSUES AND TODO *exchange-issues*
*exchange-todo* *exchange-todo*

View File

@ -20,6 +20,20 @@ function! s:exchange(x, y, reverse, expand)
silent exe "normal! `[" . a:x[1] . "`]\"zp" silent exe "normal! `[" . a:x[1] . "`]\"zp"
endif endif
if exists("b:exchange_indent") ? (b:exchange_indent !~ 0) :
\ (exists("g:exchange_indent") && (g:exchange_indent !~ 0))
let xlines = 1 + a:x[3][1] - a:x[2][1]
let xindent = matchstr(getline(nextnonblank(a:x[2][1])), '^\s*')
let ylines = 1 + a:y[3][1] - a:y[2][1]
let yindent = matchstr(getline(nextnonblank(a:y[2][1])), '^\s*')
if a:y[1] ==# 'V'
call s:reindent(a:x[2][1], ylines, yindent)
endif
if a:x[1] ==# 'V'
call s:reindent(a:y[2][1] - xlines + ylines, xlines, xindent)
endif
endif
if a:reverse if a:reverse
call cursor(a:x[2][1], a:x[2][2]) call cursor(a:x[2][1], a:x[2][2])
else else
@ -33,6 +47,40 @@ function! s:exchange(x, y, reverse, expand)
call s:restore_reg('+', reg_plus) call s:restore_reg('+', reg_plus)
endfunction endfunction
function! s:reindent(start, lines, new_indent)
if g:exchange_indent == '=='
let lnum = nextnonblank(a:start)
let line = getline(lnum)
execute "silent normal! " . lnum . "G=="
let new_indent = matchstr(getline(lnum), '^\s*')
call setline(a:start, line)
else
let new_indent = a:new_indent
endif
let indent = matchstr(getline(nextnonblank(a:start)), '^\s*')
if strdisplaywidth(new_indent) > strdisplaywidth(indent)
for lnum in range(a:start, a:start + a:lines - 1)
if lnum =~ '\S'
call setline(lnum, new_indent . getline(lnum)[len(indent):])
endif
endfor
elseif strdisplaywidth(new_indent) < strdisplaywidth(indent)
let can_dedent = 1
for lnum in range(a:start, a:start + a:lines - 1)
if stridx(getline(lnum), new_indent) != 0 && nextnonblank(lnum) == lnum
let can_dedent = 0
endif
endfor
if can_dedent
for lnum in range(a:start, a:start + a:lines - 1)
if stridx(getline(lnum), new_indent) == 0
call setline(lnum, new_indent . getline(lnum)[len(indent):])
endif
endfor
endif
endif
endfunction
function! s:exchange_get(type, vis) function! s:exchange_get(type, vis)
let reg = s:save_reg('"') let reg = s:save_reg('"')
let reg_star = s:save_reg('*') let reg_star = s:save_reg('*')