Vimdiff: How to Put All Changes Inside a Particular Function from One File to Another

Vimdiff: How to put all changes inside a particular function from one file to another?

You can use a visual selection and the ex command :diffget/:diffput

So, for example to get the changes for just the current insides of a code block ( { ... } )

Vi}:diffget<Enter>

To put the changes for the two enclosing levels including the lines with the brackets:

V2a}:diffput<Enter>

Note that since these are ex commands the motions are linewise. Of course, you could use any range, so you can repeat the visual range, or use markers

:'a,'bdiffput

etc. Use your imagination, this is vim :)

Merge changes using vimdiff

You can switch back and forth between the two windows with Ctrlww. You can copy from one window do a Ctrlww, and then paste into the other. As you resolve differences, the highlights will change, and disappear.

Take a look at this video.

How can I expand/collapse a diff sections in Vimdiff?

Aside from the ones you mention, I only use the following frequently when diffing:

  • :diffupdate :diffu -> recalculate the diff. It is useful when, after making several changes, Vim isn't showing minimal changes anymore. Note that it only works if the files have been modified inside vimdiff. Otherwise, use:
  • :e to reload the files if they have been modified outside of vimdiff.
  • :set noscrollbind -> temporarily disable simultaneous scrolling on both buffers, reenable by :set scrollbind and scrolling.

Most of what you asked for is folding: the Vim user manual's chapter on folding. Outside of diffs, I sometimes use:

  • zo -> open fold.
  • zc -> close fold.

But you'll probably be better served by:

  • zr -> reducing folding level.
  • zm -> one more folding level, please.

Or even:

  • zR -> Reduce completely the folding, I said!.
  • zM -> fold Most!.

The other thing you asked for, use n lines of folding, can be found at the Vim reference manual section on options, via the section on diff:

  • set diffopt=<TAB>, then update or add context:n.

You should also take a look at the user manual section on diff.

Give vimdiff some hints

Vim just delegates the actual work of comparing the files to the external diff utility, cp. :help diff-diffexpr. The help page also shows how a different utility can be used. Unfortunately, I'm not aware of any more "intelligent" or configurable diff tool that would help in your situation.

A workaround might be (temporarily) removing the excess functions that you're not interested in, anyway. With the BlockDiff plugin, you don't actually need to modify the files. Just select the interesting lines in both windows and execute :[range]BlockDiff on them. Only those sections will then be diffed in a separate tab page. (The plugin mentions this requires a GUI, but Vim in a terminal supports tab pages just as well.)

How to ‘diff’ two subroutines in the same file in Vim?

You cannot do this within the original file, but you can do this without using separate files, only separate buffers. This should work if you copied one subroutine in register a (for example, with "ay typed in Visual mode) and other subroutine in register b:

enew | call setline(1, split(@a, "\n")) | diffthis | vnew | call setline(1, split(@b, "\n")) | diffthis

To automate:

let g:diffed_buffers = []

function DiffText(a, b, diffed_buffers)
enew
setlocal buftype=nowrite
call add(a:diffed_buffers, bufnr('%'))
call setline(1, split(a:a, "\n"))
diffthis
vnew
setlocal buftype=nowrite
call add(a:diffed_buffers, bufnr('%'))
call setline(1, split(a:b, "\n"))
diffthis
endfunction

function WipeOutDiffs(diffed_buffers)
for buffer in a:diffed_buffers
execute 'bwipeout! ' . buffer
endfor
endfunction

nnoremap <special> <F7> :call DiffText(@a, @b, g:diffed_buffers)<CR>
nnoremap <special> <F8> :call WipeOutDiffs(g:diffed_buffers) | let g:diffed_buffers=[]<CR>

Note that you may want to set hidden option if Vim refuses to abandon changed file (see :h abandon).

how can I diff two sections of the same file?

The linediff plugin for Vim works well for me. Visually select one section of your file and type :Linediff. Visually select the other section and type :Linediff. It will put vim in to vimdiff mode, showing only the two sections you highlighted previously. Type:LinediffReset to exit vimdiff mode.

More info:

https://unix.stackexchange.com/a/52759/32477

https://superuser.com/a/414958/199800

Diff-ing windows in vim

What I usually do is diff to a copy

:%w %.alt
:vert diffsplit %.alt

And then happiliy rearrange the 'alt' version so that the pseudo-matching bits get aligned.


Note that (presumably) git contains spiffy merge/diff cow-powers that should be able to detect sub-file moved block changes.

Although I haven't (yet) actually put this into practice, I have a hunch that the very nice git plugin fugitive for vim might be able to leverage some of this horsepower to make this easier. Note: fully expect this to require scriptinh before being usable, but I still thought it would be nice to share this idea (perhaps you can share a script if you get to it first!)

vimdiff: force line-by-line comparison (ignore supposedly missing/additional lines)

How about using diffchar.vim plugin? It compares line-by-line in non-diff mode. Please open 2 files on 2 windows and then just press F7. By default, it tries to find the differences by characters in a line, but you can change the difference units, words or something.



Related Topics



Leave a reply



Submit