aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2018-12-29 23:01:20 +1300
committerTom Ryder <tom@sanctum.geek.nz>2018-12-29 23:01:20 +1300
commit5c63d2da1e96d4d399c7319faa0577ee278a6e2a (patch)
tree0d9149a0364f05e9fd0fdfe3c05832dbb276761b
parentCorrect use of plural in documentation (diff)
downloadvim-replace-operator-5c63d2da1e96d4d399c7319faa0577ee278a6e2a.tar.gz
vim-replace-operator-5c63d2da1e96d4d399c7319faa0577ee278a6e2a.zip
Refactor with expression mappings and simpler alg
-rw-r--r--autoload/replace_operator.vim76
-rw-r--r--plugin/replace_operator.vim14
2 files changed, 38 insertions, 52 deletions
diff --git a/autoload/replace_operator.vim b/autoload/replace_operator.vim
index 74711fd..a48a04d 100644
--- a/autoload/replace_operator.vim
+++ b/autoload/replace_operator.vim
@@ -1,59 +1,47 @@
" Replace the operated text with the contents of a register
function! replace_operator#Operatorfunc(type) abort
- " 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'
+ " Save the active register into a local variable
+ let l:register = v:register
+
+ " Save the current value of the unnamed register and the current value of
+ " the 'clipboard' and 'selection' options into a dictionary for restoring
+ " after this is all done
+ let l:save = {
+ \ 'unnamed': @@,
+ \ 'clipboard': &clipboard,
+ \ 'selection': &selection
+ \ }
+
+ " Don't involve any system clipboard for the duration of this function
+ set clipboard-=unnamed
+ set clipboard-=unnamedplus
+
+ " Ensure that we include end-of-line and final characters in selections
+ set selection=inclusive
+
+ " Select or re-select text, depending on how we were invoked
+ if a:type ==# 'line'
normal! '[V']
+ elseif a:type ==# 'block'
+ execute "normal! `[\<C-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
+ " Re-select the text, and replace it with the contents of the register
+ execute 'normal! "'.l:register.'p'
- " 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
- let l:paste = 'P'
- endif
-
- " Run the paste
- execute 'normal "'.l:register.l:paste
+ " Restore contents of the unnamed register and the previous values of the
+ " 'clipboard' and 'selection' options
+ let @@ = l:save['unnamed']
+ let &clipboard = l:save['clipboard']
+ let &selection = l:save['selection']
endfunction
" Helper function for normal mode map
-function! replace_operator#MapNormal(register) abort
- let g:replace_operator#register = a:register
+function! replace_operator#Map(register) abort
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)
+ return 'g@'
endfunction
diff --git a/plugin/replace_operator.vim b/plugin/replace_operator.vim
index a5c4a95..982b573 100644
--- a/plugin/replace_operator.vim
+++ b/plugin/replace_operator.vim
@@ -1,6 +1,6 @@
"
-" replace_operator.vim: Replace text selected with a motion with the
-" contents of a register in a repeatable way.
+" replace_operator.vim: Replace text selected with a motion with the contents
+" of a register in a repeatable way.
"
" Author: Tom Ryder <tom@sanctum.geek.nz>
" License: Same as Vim itself
@@ -14,9 +14,7 @@ endif
let g:loaded_replace_operator = 1
" Set up mapping
-nnoremap <silent> <unique>
- \ <Plug>(ReplaceOperator)
- \ :<C-U>call replace_operator#MapNormal(v:register)<CR>g@
-xnoremap <silent> <unique>
- \ <Plug>(ReplaceOperator)
- \ :<C-U>call replace_operator#MapVisual(v:register, visualmode())<CR>
+nnoremap <expr> <Plug>(ReplaceOperator)
+ \ replace_operator#Map()
+xnoremap <expr> <Plug>(ReplaceOperator)
+ \ replace_operator#Map()