Cloning text in Vim
There are a couple of keystrokes in Vim that you can use to clone text:
- Ctrl+E copies the character from the line immediately below the cursor
- Ctrl+Y copies the character from the line immediately above the cursor
I thought it would be useful to extend this so that I will be able to clone text from anywhere I choose (based on setting a mark), rather like the area cloning you get in image editors like Photoshop.
Here’s what I’ve come up with and added to my vimrc file.
" Added <C-S-C> to clone text from wherever the "a mark is set
" The <Space><Backspace> preserves the automatic indent if you've opened a new line
inoremap <C-S-C> <Space><Backspace><Esc>:call Clone()<CR>a
nnoremap <C-S-C> :call Clone()<CR>
function! Clone()
normal `a
let isendofline = 0
if col('.') + 1 == col('$') || col('$') == 1
let isendofline = 1
endif
normal yl
" move the "a mark one place to the right or to the start of the next line
if isendofline > 0
normal j0
else
normal l
endif
normal ma
normal ``
normal p
if isendofline > 0
if mode() == 'n'
normal o
normal \<Esc>
else
normal <CR>
endif
endif
endfunction
It works in both normal and insert mode. You just set the “a mark wherever you like and then use Ctrl+Shift+C to start cloning. It’s most useful when you wish to intersperse the thing you’re cloning with annotations, as shown in the following demo (forgive the clunky animated gif, but hopefully you get the idea).
I set the mark at the H of Here is some text., open a new line, start typing and then use Ctrl+Shift+C to bring in the original text. Each time I press this shortcut, it takes one more character and moves the “a mark along one. It works across line breaks too.
I hope you find it useful. It’s a handy thing to have in your Vim kit bag.