Skip to content

Commit

Permalink
Version 2.10
Browse files Browse the repository at this point in the history
- ENH: Add gpp / gpP mappings to paste with one number (which depending on the current cursor position) incremented / decremented.
- FIX: For characterwise pastes with a [count], the multiplied pastes must be joined with the desired separator, not just plainly concatenated.
- FIX: Don't lose the original [count] given when repeating the mapping.
- FIX: Do not re-query on repeat of the mapping.
  • Loading branch information
Ingo Karkat authored and vim-scripts committed Dec 25, 2012
1 parent cc5f809 commit 55e6b05
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 8 deletions.
83 changes: 82 additions & 1 deletion autoload/UnconditionalPaste.vim
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@
" http://vim.wikia.com/wiki/Unconditional_linewise_or_characterwise_paste
"
" REVISION DATE REMARKS
" 2.10.019 21-Dec-2012 FIX: For characterwise pastes with a [count],
" the multiplied pastes must be joined with the
" desired separator, not just plainly
" concatenated.
" ENH: Add mappings to paste with one number
" (which depending on the current cursor position)
" incremented / decremented.
" Handle repeat of gpp with the last used offset
" and the same number position by introducing a
" special ".p" paste type.
" FIX: Don't lose the original [count] given when
" repeating the mapping. As
" UnconditionalPaste#Paste() executes a normal
" mode command, we need to store v:count and make
" it available to the <Plug>-mapping via the new
" UnconditionalPaste#GetCount() getter.
" 2.00.018 07-Dec-2012 FIX: Differentiate between pasteType and a:how
" argument, as setregtype() only understands the
" former.
Expand Down Expand Up @@ -94,8 +110,31 @@ function! s:Unjoin( text, separatorPattern )
" pasting. For consistency, do the same for a single leading separator.
return (l:text =~# '^\n' ? l:text[1:] : l:text)
endfunction
function! s:Increment( text, vcol, offset )
let l:replacement = '\=submatch(0) + ' . a:offset

if a:vcol == -1 || a:vcol == 0 && col('.') + 1 == col('$')
return [-1, substitute(a:text, '\d\+\ze\D*$', l:replacement, '')]
endif

let l:text = a:text
let l:vcol = (a:vcol == 0 ? virtcol('.') : a:vcol)
if l:vcol > 1
let l:text = substitute(a:text, '\d*\%>' . (l:vcol - 1) . 'v\d\+', l:replacement, '')
endif
if l:text ==# a:text
return [1, substitute(a:text, '\d\+', l:replacement, '')]
else
return [l:vcol, l:text]
endif
endfunction

function! UnconditionalPaste#GetCount()
return s:count
endfunction
function! UnconditionalPaste#Paste( regName, how, ... )
let l:count = v:count
let s:count = v:count
let l:regType = getregtype(a:regName)
let l:regContent = getreg(a:regName, 1) " Expression evaluation inside function context may cause errors, therefore get unevaluated expression when a:regName ==# '='.

Expand Down Expand Up @@ -147,6 +186,14 @@ function! UnconditionalPaste#Paste( regName, how, ... )
else
throw 'ASSERT: Invalid how: ' . string(a:how)
endif

if l:count > 1
" To join the multiplied pastes with the desired separator, we
" need to process the multiplication on our own.
let l:pasteContent = repeat(l:pasteContent . "\n", l:count)
let l:count = 0
endif

let l:pasteContent = s:Flatten(l:pasteContent, l:separator)
elseif a:how ==? 'u'
if a:how ==# 'u'
Expand All @@ -168,11 +215,45 @@ function! UnconditionalPaste#Paste( regName, how, ... )
endif
elseif a:how ==# 'l' && l:regType[0] ==# "\<C-v>"
let l:pasteContent = s:StripTrailingWhitespace(l:regContent)
elseif a:how ==# 'p' || a:how ==# '.p'
let l:pasteType = l:regType " Keep the original paste type.
let l:offset = (a:1 ==# 'p' ? 1 : -1)
if a:how ==# 'p'
let l:baseCount = 1
let l:vcol = 0
elseif a:how ==# '.p'
" Continue increasing with the last used (saved) offset, and at
" the same number position (after the first paste, the cursor
" will have jumped to the beginning of the pasted text).
let l:baseCount = s:lastCount + 1
let l:vcol = s:lastVcol
else
throw 'ASSERT: Invalid how: ' . string(a:how)
endif
let s:lastCount = l:baseCount

let [s:lastVcol, l:pasteContent] = s:Increment(l:regContent, l:vcol, l:offset * l:baseCount)
if l:pasteContent ==# l:regContent
" No number was found in the register; this is probably not what
" the user intended (maybe wrong register?), so don't just
" insert the contents unchanged, but rather alert the user.
execute "normal! \<C-\>\<C-n>\<Esc>" | " Beep.
return ''
endif

if l:count > 1
" To increment each multiplied paste one more, we need to
" process the multiplication on our own.
let l:numbers = (l:offset > 0 ? range(l:baseCount, l:baseCount + l:count - 1) : range(-1 * (l:baseCount + l:count - 1), -1 * l:baseCount))
let l:pasteContent = join(map(l:numbers, 's:Increment(l:regContent, l:vcol, v:val)[1]'), (l:regType[0] ==# "\<C-v>" ? "\n" : ''))
let s:lastCount = l:baseCount + l:count - 1
let l:count = 0
endif
endif

if a:0
call setreg(l:regName, l:pasteContent, l:pasteType)
execute 'normal! "' . l:regName . (v:count ? v:count : '') . a:1
execute 'normal! "' . l:regName . (l:count ? l:count : '') . a:1
call setreg(l:regName, l:regContent, l:regType)
else
return l:pasteContent
Expand Down
18 changes: 18 additions & 0 deletions doc/UnconditionalPaste.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ USAGE *UnconditionalPaste-usage*
queried (|gup|) separator pattern, then paste
linewise.

*gpp* *gpP*
["x]gpp, ["x]gpP Paste with the first number found on or after the
current cursor column (or the overall first number, if
no such match, or the last number, if the cursor is at
the end of the line) incremented / decremented by 1.
Do this [count] times, with each paste further
incremented / decremented.


CTRL-R CTRL-C {0-9a-z"%#*+/:.-} *i_CTRL-R_CTRL-C*
Insert the contents of a register characterwise
Expand Down Expand Up @@ -150,6 +158,8 @@ script (e.g. in your |vimrc|): >
nmap <Leader>pu <Plug>UnconditionalPasteUnjoinAfter
nmap <Leader>PU <Plug>UnconditionalPasteRecallUnjoinBefore
nmap <Leader>pU <Plug>UnconditionalPasteRecallUnjoinAfter
nmap <Leader>Pp <Plug>UnconditionalPastePlusBefore
nmap <Leader>pp <Plug>UnconditionalPastePlusAfter
imap <C-G>c <Plug>UnconditionalPasteChar
imap <C-G>, <Plug>UnconditionalPasteComma
Expand All @@ -170,6 +180,14 @@ IDEAS *UnconditionalPaste-ideas*
==============================================================================
HISTORY *UnconditionalPaste-history*

2.10 22-Dec-2012
- ENH: Add gpp / gpP mappings to paste with one number (which depending on the
current cursor position) incremented / decremented.
- FIX: For characterwise pastes with a [count], the multiplied pastes must be
joined with the desired separator, not just plainly concatenated.
- FIX: Don't lose the original [count] given when repeating the mapping.
- FIX: Do not re-query on repeat of the mapping.

2.00 05-Dec-2012
- ENH: Add g,p / gqp / gQp mappings to paste lines flattened with comma,
queried, or recalled last used delimiter.
Expand Down
36 changes: 29 additions & 7 deletions plugin/UnconditionalPaste.vim
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
" http://vim.wikia.com/wiki/Unconditional_linewise_or_characterwise_paste
"
" REVISION DATE REMARKS
" 2.10.018 22-Dec-2012 FIX: Do not re-query on repeat of the mapping.
" This wasn't updated for the Query mapping and
" not implemented at all for the Unjoin mapping.
" 2.10.017 21-Dec-2012 ENH: Add mappings to paste with one number
" (which depending on the current cursor position)
" incremented / decremented.
" Handle repeat of gpp with the last used offset
" and the same number position by introducing a
" special ".p" paste type.
" FIX: Don't lose the original [count] given when
" repeating the mapping. As
" UnconditionalPaste#Paste() executes a normal
" mode command, we need to store v:count and make
" it available to the <Plug>-mapping via the new
" UnconditionalPaste#GetCount() getter.
" 2.00.016 05-Dec-2012 ENH: Add mappings to insert register contents
" characterwise (flattened) from insert mode.
" ENH: Add mappings to paste lines flattened with
Expand Down Expand Up @@ -98,32 +113,39 @@ function! s:CreateMappings()
\ [
\ ['Char', 'c'], ['Line', 'l'], ['Block', 'b'], ['Comma', ','],
\ ['Queried', 'q'], ['RecallQueried', 'Q'],
\ ['Unjoin', 'u'], ['RecallUnjoin', 'U']
\ ['Unjoin', 'u'], ['RecallUnjoin', 'U'],
\ ['Plus', 'p'], ['PlusRepeat', '.p']
\ ]
for [l:direction, l:pasteCmd] in [['After', 'p'], ['Before', 'P']]
let l:mappingName = 'UnconditionalPaste' . l:pasteName . l:direction
let l:plugMappingName = '<Plug>' . l:mappingName

if l:pasteType ==# '/'
" On repeat of the UnconditionalPasteQueried mapping, we want to
" skip the query and recall the last queried separator instead.
let l:mappingName = 'UnconditionalPasteRecalled' . l:direction
if l:pasteType ==# 'q' || l:pasteType ==# 'u'
" On repeat of one of the mappings that query, we want to skip
" the query and recall the last queried separator instead.
let l:mappingName = 'UnconditionalPasteRecall' . l:pasteName . l:direction
elseif l:pasteType ==# 'p'
" On repeat of the UnconditionalPastePlus mapping, we want to
" continue increasing with the last used (saved) offset, and at
" the same number position (after the first paste, the cursor
" will have jumped to the beginning of the pasted text).
let l:mappingName = 'UnconditionalPaste' . l:pasteName . 'Repeat' . l:direction
endif
execute printf('nnoremap <silent> %s :<C-u>' .
\ 'execute ''silent! call repeat#setreg("\<lt>Plug>%s", v:register)''<Bar>' .
\ 'if v:register ==# "="<Bar>' .
\ ' call UnconditionalPaste#HandleExprReg(getreg("="))<Bar>' .
\ 'endif<Bar>' .
\ 'call UnconditionalPaste#Paste(v:register, %s, %s)<Bar>' .
\ 'silent! call repeat#set("\<lt>Plug>%s")<CR>',
\ 'silent! call repeat#set("\<lt>Plug>%s", UnconditionalPaste#GetCount())<CR>',
\
\ l:plugMappingName,
\ l:mappingName,
\ string(l:pasteType),
\ string(l:pasteCmd),
\ l:mappingName
\)
if ! hasmapto(l:plugMappingName, 'n')
if ! hasmapto(l:plugMappingName, 'n') && len(l:pasteType) == 1
execute printf('nmap g%s%s %s',
\ l:pasteType,
\ l:pasteCmd,
Expand Down

0 comments on commit 55e6b05

Please sign in to comment.