12

TL;DR; version - How do I undo text that was pasted in from my OS copy buffer without undoing other text that was typed in since I went into insert mode?

Longer description:

  1. Put something in your OS copy buffer (e.g. highlight some text and do Command-c on Mac)
  2. Go into insert mode in vim ( i )
  3. Type something ( e.g. asdf)
  4. Without exiting insert mode, paste from your copy buffer into vim ( Command-v on Mac)
  5. Hit escape
  6. Try to undo the paste ( u )

It undoes everything from the last time you went into insert mode. In otherwords, it clears out asdf plus all the text I pasted in.

How do I just undo the text that pasted in? Do I have to always go out of insert mode and back in before I paste text just to have the option to undo the pasted text?

3 Answers 3

5

One way is explicitly dropping out and back into insert mode before the paste. If you extend the paste commands, you can also automatically set an undo point before the paste:

" Any text fragment pasted in insert mode should be undone separately, without
" destroying what was typed before.
inoremap <C-R> <C-G>u<C-R>

The above is for the built-in i_CTRL-R command. I don't know how Command-v is implemented in MacVim, but prepending <C-G>u to the :imap command should achieve the same effect.

2
  • 1
    Works like a charm, thanks! I should probably stick with standard vim methods for pasting anyways. Commented Feb 28, 2014 at 22:33
  • 1
    Just adding this: :h i_CTRL-G_u (i.e., "break undo sequence, start new change" in insert mode).
    – toraritte
    Commented Oct 29, 2017 at 12:04
2

In MacVim, you need to unmap the Edit > Paste menu item in order to override the shortcut, then you can remap Cmd-V (D-v in MacVim parlance) to the appropriate command in each mode. I added this to my ~/.gvimrc and now everything works wonderfully:

macmenu Edit.Paste key=<nop>
noremap <D-v> "*P
cnoremap <D-v> <C-r><C-o>*
inoremap <D-v> <C-g>u<C-r><C-o>*

The <C-g>u is necessary only in insert mode to fix the undo history; the noremap and cnoremap are simply to restore the default paste behavior in the normal and command modes.

Thanks to Ingo Karkat for pointing me in the right direction here.

1

Actually the solution is you have to go to command mode(e.g. Esc) first and re-enter the insert mode, but it only works if I type manually but it seems "randomly" stop working if I test it in ~/.vimrc. Google doesn't help at all.

I spends a lot of time try to fix this issue and I just figure out the reason in my case:

Don't map the paste key same with the terminal existing paste key

e.g. Ctrl+Shift+V will paste in my Konsole terminal, but if I assign this key <C-S-v> in ~/.vimrc, the "undo for only single paste instead of multiple pastes" will not working.

In my case, I have to use <C-v> instead of <C-S-v>:

inoremap <C-v> <Esc>"+pi<Esc>i<Right><Right>

Your case may difference, but the point is same: don't assign the same paste key conflicts with existing terminal emulator key.

I've 100% proved this conclusion by set my terminal paste key to Ctrl+V and now <C-v> stop working but <C-S-v> working.

Note also that the vim is too sensitive and strange. I figure out I have to use i and then 2 Right keys manually to make it works in the correct cursor position, that's means I have to put i and 2 Right keys in the ~/.vimrc too. Your case might difference, but the point is same, ensure the keys+order in ~/.vimrc 100% match with what you type manually.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .