Permalink
Browse files

Version 2.10

- 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...
1 parent cc5f809 commit 55e6b05aeb1c8901209497614bb15abf42a4e3b6 Ingo Karkat committed with Dec 22, 2012
Showing with 129 additions and 8 deletions.
  1. +82 −1 autoload/UnconditionalPaste.vim
  2. +18 −0 doc/UnconditionalPaste.txt
  3. +29 −7 plugin/UnconditionalPaste.vim
@@ -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.
@@ -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 ==# '='.
@@ -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'
@@ -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
View
@@ -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
@@ -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
@@ -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.
@@ -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
@@ -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,

0 comments on commit 55e6b05

Please sign in to comment.