How do I only dp or do just the lines, not the entire block in Vim diff?

28

9

I'm currently using MacVim (Snapshot 64) "Split Diff by..." menu option.

The file is Django's my settings.py from version 1.3.1 to a fresh file from version 1.4.

Screenshot

I know two basic commands

  1. do to "obtain" (and replace) a block from the other side.
  2. dp to "put" (and replace) a block to the other side.

But those two commands writes the entire block, which in MacVim is the purple highlights.

If you look at the 2nd block, you can see that from line 2 and 3 only has 2 words that are different: mysite and hobbes3. I just want to replace per line not the entire block.

So what is there a command to replace do do and dp per line as oppose to an entire block or do I have to manually type it out?

Bonus question: I noticed that once I manually edit a block, I lose the purple highlighting. How do I "refresh" the diff again to include the highlights without reopening the file?

Please try to keep the answers Vim-general as oppose to MacVim-specific.

hobbes3

Posted 2012-03-24T16:55:54.713

Reputation: 741

Answers

30

There are a number of ways to do this.

  1. Select the range of lines in the destination buffer that you want to obtain from the source buffer and use :diffget. For example, you could visually-select a range of lines with V, then type :diffget.
  2. Select the range of lines in the source buffer that you want to put into the destination buffer and use :diffput. For example, to put the current line into the other buffer, type :.diffput.
  3. Use yank and put. Select the range of lines in the source buffer that you want to copy into the destination buffer, yank them using Y, move the cursor to the destination buffer and put them where you want them with p or P, then delete the lines you don't want.
  4. Yank as above, but in the destination buffer, visually-select the range of lines you want to replace (not necessarily the same number of lines) and type "0p. That uses the 0 (zero) register which always contains the text of the most recent yank.

To "refresh" the display to show the proper highlighting, execute :diffupdate or simply :diffu. Sometimes that isn't sufficient and you need to move the cursor to the other window to complete the refreshing.

You can read more about copying diffs in

:help copy-diffs

garyjohn

Posted 2012-03-24T16:55:54.713

Reputation: 29 085

3

I also wanted to modify one line at a given moment during a diff. So I created a simple map and put them in my vimrc file.

nnoremap <silent> <leader>dp V:diffput<cr>
nnoremap <silent> <leader>dg V:diffget<cr>

You could use do instead of dg, but I am more used to thinking "diffget" instead of [o]btain.

For your bonus, I just use a another simple map twice:

nnoremap <silent> <leader>df :call DiffToggle()<CR>

Now, df will turn off/on the diffmode, so I just turn it off and back on.

And a bonus option is to add

nmap <silent> <leader>du :wincmd w<cr>:normal u<cr>:wincmd w<cr>

This will allow you to undo a typo or unwanted change on the other file/window, because :undo of just u will only undo a change in the present window.

lucky85dog

Posted 2012-03-24T16:55:54.713

Reputation: 31