Browse files

Version 2.20

- ENH: gpp also handles multi-line pastes. A number (after the corresponding column) is incremented in every line. If there are no increments this way, fall back to replacement of the first occurrence.
- ENH: Add gPp / gPP mappings to paste with all numbers incremented / decremented.
- ENH: Add g]p / g]P mappings to paste linewise with adjusted indent. Thanks to Gary Fixler for the suggestion.
  • Loading branch information...
1 parent 55e6b05 commit 035ee5dc314d43db0426581969135409d1e11fa1 Ingo Karkat committed with Mar 18, 2013
Showing with 119 additions and 31 deletions.
  1. +10 −0 README
  2. +48 −19 autoload/UnconditionalPaste.vim
  3. +25 −2 doc/UnconditionalPaste.txt
  4. +36 −10 plugin/UnconditionalPaste.vim
View
10 README
@@ -34,6 +34,10 @@ USAGE
pushing existing text further to the right) [count]
times.
+["x]g]p, ["x]g[P or Paste linewise (even if yanked text is not a complete
+ ["x]g]P or line) [count] times like glp, but adjust the indent
+ ["x]g[p to the current line (like ]p) .
+
["x]g,p, ["x]g,P Paste characterwise, with each line delimited by ", "
instead of the newline (and indent).
@@ -57,6 +61,12 @@ USAGE
Do this [count] times, with each paste further
incremented / decremented.
+["x]gPp, ["x]gPP Paste with the all numbers incremented / decremented
+ by 1.
+ Do this [count] times, with each paste further
+ incremented / decremented.
+
+
CTRL-R CTRL-C {0-9a-z"%#*+/:.-}
Insert the contents of a register characterwise
(newline characters and indent are flattened to
View
67 autoload/UnconditionalPaste.vim
@@ -3,14 +3,21 @@
"
" DEPENDENCIES:
-" Copyright: (C) 2006-2012 Ingo Karkat
+" Copyright: (C) 2006-2013 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
" Source: Based on vimtip #1199 by cory,
" http://vim.wikia.com/wiki/Unconditional_linewise_or_characterwise_paste
"
" REVISION DATE REMARKS
+" 2.20.021 18-Mar-2013 ENH: Add gPp / gPP mappings to paste with all
+" numbers incremented / decremented.
+" 2.20.020 15-Mar-2013 ENH: gpp also handles multi-line pastes. A
+" number (after the corresponding column) is
+" incremented in every line. If there are no
+" increments this way, fall back to replacement of
+" the first occurrence.
" 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
@@ -110,24 +117,44 @@ 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
-
+function! s:IncrementLine( line, vcol, replacement )
if a:vcol == -1 || a:vcol == 0 && col('.') + 1 == col('$')
- return [-1, substitute(a:text, '\d\+\ze\D*$', l:replacement, '')]
+ " Increment the last number.
+ return [-1, substitute(a:line, '\d\+\ze\D*$', a:replacement, '')]
endif
- let l:text = a:text
+ let l:text = a:line
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, '')]
+ return [l:vcol, substitute(a:line, '\d*\%>' . (l:vcol - 1) . 'v\d\+', a:replacement, '')]
else
- return [l:vcol, l:text]
+ return [1, substitute(a:line, '\d\+', a:replacement, '')]
endif
endfunction
+function! s:SingleIncrement( text, vcol, offset )
+ let l:replacement = '\=submatch(0) + ' . a:offset
+
+ let l:didIncrement = 0
+ let l:vcol = 0
+ let l:result = []
+ for l:line in split(a:text, "\n", 1)
+ let [l:vcol, l:incrementedLine] = s:IncrementLine(l:line, a:vcol, l:replacement)
+ let l:didIncrement = l:didIncrement || (l:line !=# l:incrementedLine)
+ call add(l:result, l:incrementedLine)
+ endfor
+
+ if ! l:didIncrement
+ " Fall back to incrementing the first number.
+ let l:vcol = 0
+ let l:result = map(split(a:text, "\n", 1), 'substitute(v:val, "\\d\\+", l:replacement, "")')
+ endif
+
+ return [l:vcol, join(l:result, "\n")]
+endfunction
+function! s:GlobalIncrement( text, vcol, offset )
+ let l:replacement = '\=submatch(0) + ' . a:offset
+ return [0, substitute(a:text, '\d\+', l:replacement, 'g')]
+endfunction
function! UnconditionalPaste#GetCount()
return s:count
@@ -215,24 +242,26 @@ 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'
+ 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'
+ 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).
+ elseif a:how ==? '.p'
+ " Continue increasing with the last used (saved) offset, and
+ " (for 'p') 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)
+ let l:IncrementFunc = (a:how ==# 'p' || a:how ==# '.p' ? 's:SingleIncrement' : 's:GlobalIncrement')
+ let [s:lastVcol, l:pasteContent] = call(l:IncrementFunc, [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
@@ -245,7 +274,7 @@ function! UnconditionalPaste#Paste( regName, how, ... )
" 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 l:pasteContent = join(map(l:numbers, l:IncrementFunc . '(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
View
27 doc/UnconditionalPaste.txt
@@ -51,6 +51,11 @@ USAGE *UnconditionalPaste-usage*
pushing existing text further to the right) [count]
times.
+ *g]p* *g[P* *g]P* *g[p*
+["x]g]p, ["x]g[P or Paste linewise (even if yanked text is not a complete
+ ["x]g]P or line) [count] times like |glp|, but adjust the indent
+ ["x]g[p to the current line (like |]p|) .
+
*g,p* *g,P*
["x]g,p, ["x]g,P Paste characterwise, with each line delimited by ", "
instead of the newline (and indent).
@@ -76,6 +81,11 @@ USAGE *UnconditionalPaste-usage*
the end of the line) incremented / decremented by 1.
Do this [count] times, with each paste further
incremented / decremented.
+ *gPp* *gPP*
+["x]gPp, ["x]gPP Paste with the all numbers 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*
@@ -148,6 +158,8 @@ script (e.g. in your |vimrc|): >
nmap <Leader>pl <Plug>UnconditionalPasteLineAfter
nmap <Leader>Pb <Plug>UnconditionalPasteBlockBefore
nmap <Leader>pb <Plug>UnconditionalPasteBlockAfter
+ nmap <Leader>Pi <Plug>UnconditionalPasteIndentedBefore
+ nmap <Leader>pi <Plug>UnconditionalPasteIndentedAfter
nmap <Leader>P, <Plug>UnconditionalPasteCommaBefore
nmap <Leader>p, <Plug>UnconditionalPasteCommaAfter
nmap <Leader>Pq <Plug>UnconditionalPasteQueriedBefore
@@ -160,6 +172,8 @@ script (e.g. in your |vimrc|): >
nmap <Leader>pU <Plug>UnconditionalPasteRecallUnjoinAfter
nmap <Leader>Pp <Plug>UnconditionalPastePlusBefore
nmap <Leader>pp <Plug>UnconditionalPastePlusAfter
+ nmap <Leader>PP <Plug>UnconditionalPasteGPlusBefore
+ nmap <Leader>pP <Plug>UnconditionalPasteGPlusAfter
imap <C-G>c <Plug>UnconditionalPasteChar
imap <C-G>, <Plug>UnconditionalPasteComma
@@ -180,6 +194,15 @@ IDEAS *UnconditionalPaste-ideas*
==============================================================================
HISTORY *UnconditionalPaste-history*
+2.20 18-Mar-2013
+- ENH: gpp also handles multi-line pastes. A number (after the corresponding
+ column) is incremented in every line. If there are no increments this way,
+ fall back to replacement of the first occurrence.
+- ENH: Add gPp / gPP mappings to paste with all numbers incremented /
+ decremented.
+- ENH: Add g]p / g]P mappings to paste linewise with adjusted indent. Thanks
+ to Gary Fixler for the suggestion.
+
2.10 22-Dec-2012
- ENH: Add gpp / gpP mappings to paste with one number (which depending on the
current cursor position) incremented / decremented.
@@ -235,8 +258,8 @@ Published, prompted by a related question on reddit.
Started development, based on vimtip #1199 by cory.
==============================================================================
-Copyright: (C) 2006-2012 Ingo Karkat
-The VIM LICENSE applies to this script; see |copyright|.
+Copyright: (C) 2006-2013 Ingo Karkat
+The VIM LICENSE applies to this plugin; see |copyright|.
Maintainer: Ingo Karkat <ingo@karkat.de>
==============================================================================
View
46 plugin/UnconditionalPaste.vim
@@ -14,6 +14,11 @@
" http://vim.wikia.com/wiki/Unconditional_linewise_or_characterwise_paste
"
" REVISION DATE REMARKS
+" 2.20.020 18-Mar-2013 ENH: Add g]p / g]P mappings to paste linewise
+" with adjusted indent. Thanks to Gary Fixler for
+" the suggestion.
+" 2.20.019 18-Mar-2013 ENH: Add gPp / gPP mappings to paste with all
+" numbers incremented / decremented.
" 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.
@@ -112,25 +117,47 @@ function! s:CreateMappings()
for [l:pasteName, pasteType] in
\ [
\ ['Char', 'c'], ['Line', 'l'], ['Block', 'b'], ['Comma', ','],
+ \ ['Indented', 'l'],
\ ['Queried', 'q'], ['RecallQueried', 'Q'],
\ ['Unjoin', 'u'], ['RecallUnjoin', 'U'],
- \ ['Plus', 'p'], ['PlusRepeat', '.p']
+ \ ['Plus', 'p'], ['PlusRepeat', '.p'],
+ \ ['GPlus', 'P'], ['GPlusRepeat', '.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
+ " Do not create default mappings for the special paste repeats.
+ let l:pasteMappingDefaultKeys = (len(l:pasteType) == 1 ? l:pasteType . l:pasteCmd : '')
+
+
+ if l:pasteName ==# 'Indented'
+ " This is a variant of forced linewise paste (glp) that uses ]p
+ " instead of p for pasting.
+ let l:pasteMappingDefaultKeys = ']' . l:pasteCmd
+ let l:pasteCmd = ']' . l:pasteCmd
+
+ " Define additional variations like with the built-in ]P.
+ if ! hasmapto('<Plug>UnconditionalPasteIndentBefore', 'n')
+ nmap g]P <Plug>UnconditionalPasteIndentedBefore
+ nmap g[P <Plug>UnconditionalPasteIndentedBefore
+ nmap g[p <Plug>UnconditionalPasteIndentedBefore
+ endif
+ endif
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).
+ elseif l:pasteType ==? 'p'
+ " On repeat of the UnconditionalPastePlus /
+ " UnconditionalPasteGPlus mappings, 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>' .
@@ -145,10 +172,9 @@ function! s:CreateMappings()
\ string(l:pasteCmd),
\ l:mappingName
\)
- if ! hasmapto(l:plugMappingName, 'n') && len(l:pasteType) == 1
- execute printf('nmap g%s%s %s',
- \ l:pasteType,
- \ l:pasteCmd,
+ if ! hasmapto(l:plugMappingName, 'n') && ! empty(l:pasteMappingDefaultKeys)
+ execute printf('nmap g%s %s',
+ \ l:pasteMappingDefaultKeys,
\ l:plugMappingName
\)
endif

0 comments on commit 035ee5d

Please sign in to comment.