aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2018-08-23 12:19:49 +1200
committerTom Ryder <tom@sanctum.geek.nz>2018-08-23 12:19:49 +1200
commitd897f61790f31c71564a761c79b8839e76192d77 (patch)
tree18da54b2802be1d0dbbc197052bc5b056d453080
parentFirst version (diff)
parentBump VERSION (diff)
downloadvim-replace-operator-d897f61790f31c71564a761c79b8839e76192d77.tar.gz
vim-replace-operator-d897f61790f31c71564a761c79b8839e76192d77.zip
Merge branch 'release/v0.2.0'v0.2.0
* release/v0.2.0: Bump VERSION Overhaul completely
-rw-r--r--VERSION2
-rw-r--r--autoload/replace_operator.vim60
-rw-r--r--plugin/replace_operator.vim4
3 files changed, 56 insertions, 10 deletions
diff --git a/VERSION b/VERSION
index 6e8bf73..0ea3a94 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.0
+0.2.0
diff --git a/autoload/replace_operator.vim b/autoload/replace_operator.vim
index c152657..74711fd 100644
--- a/autoload/replace_operator.vim
+++ b/autoload/replace_operator.vim
@@ -1,13 +1,59 @@
" Replace the operated text with the contents of a register
function! replace_operator#Operatorfunc(type) abort
- let l:text = getreg()
- if a:type ==# 'v' || a:type ==# 'V' || a:type ==# "\<C-V>"
- normal! gvd
+
+ " If we're using the unnamed register, we'll need to save its current
+ " contents, because the deletion we're about to do will overwrite it
+ let l:register = g:replace_operator#register
+ if l:register ==# '"'
+ let l:text = getreg(l:register)
+ endif
+
+ " Select or re-select text depending on how we were invoked
+ if a:type ==# 'v' || a:type ==# 'V'
+ normal! gv
+ elseif a:type ==# "\<C-V>"
+ echoerr 'Visual block mode replace not supported'
+ return
elseif a:type ==# 'line'
- normal! `[V`]d
+ normal! '[V']
+ else
+ normal! `[v`]
+ endif
+
+ " Delete the text normally so it stacks up in the numbered registers, and
+ " then restore the active register's initial value if we just clobbered it
+ normal! d
+ if l:register ==# '"'
+ call setreg(l:register, l:text)
+ endif
+
+ " Are we working linewise or characterwise?
+ let l:linewise = a:type ==# 'V' || a:type ==# 'line'
+
+ " If the cursor is before the start of the last changed text, we've deleted
+ " to the end of line (characterwise) or the end of buffer (linewise) and
+ " have been forced to move back and up respectively. If this is the case,
+ " we'll need to paste after the current point, not before it.
+ if l:linewise && line('.') < line("'[")
+ \ || !l:linewise && col('.') < col("'[")
+ let l:paste = 'p'
else
- normal! `[v`]d
+ let l:paste = 'P'
endif
- call setreg(v:register, l:text)
- normal! P
+
+ " Run the paste
+ execute 'normal "'.l:register.l:paste
+
+endfunction
+
+" Helper function for normal mode map
+function! replace_operator#MapNormal(register) abort
+ let g:replace_operator#register = a:register
+ set operatorfunc=replace_operator#Operatorfunc
+endfunction
+
+" Helper function for visual mode map
+function! replace_operator#MapVisual(register, visualmode) abort
+ let g:replace_operator#register = a:register
+ call replace_operator#Operatorfunc(a:visualmode)
endfunction
diff --git a/plugin/replace_operator.vim b/plugin/replace_operator.vim
index 3e048d8..a5c4a95 100644
--- a/plugin/replace_operator.vim
+++ b/plugin/replace_operator.vim
@@ -16,7 +16,7 @@ let g:loaded_replace_operator = 1
" Set up mapping
nnoremap <silent> <unique>
\ <Plug>(ReplaceOperator)
- \ :<C-U>set operatorfunc=replace_operator#Operatorfunc<CR>g@
+ \ :<C-U>call replace_operator#MapNormal(v:register)<CR>g@
xnoremap <silent> <unique>
\ <Plug>(ReplaceOperator)
- \ :<C-U>call replace_operator#Operatorfunc(visualmode())<CR>
+ \ :<C-U>call replace_operator#MapVisual(v:register, visualmode())<CR>