2

I use vimdiff as my preferred diff tool. I wonder if there is a way to vimdiff only certain blocks between two files (preferably without a plugin).

e.g. Comparing file1.py getValues() fn between line 14 - 26 to getValues() fn in file2.py between line 30 - 60

3
  • This looked promising to me github.com/rickhowe/spotdiff.vim but I won't mind a workflow without a plugin
    – ankitj
    Jan 21, 2020 at 22:12
  • 1
    Have you looked at ctags/etags? You would need to generate tags file first but then vimdiff -t <function> should diff at that function.
    – paxri01
    Jan 22, 2020 at 0:11
  • This is my preferred plugin for this task: github.com/AndrewRadev/linediff.vim. To do it without a plugin would likely involve some copy-pasting, opening new buffers, etc., which is overhead that is resolved precisely by plugins. Jan 23, 2020 at 22:33

1 Answer 1

1

Plugin solutions

As already mentioned, there are several plugins:

  • BlockDiff.vim is an old, minimalistic plugin to view a diff between text blocks in a separate tab page.
  • linediff.vim is a modern, way more powerful variant that can also sync back changes and even handles merge conflicts, shows the scope with signs, etc.
  • spotdiff.vim has a different approach: instead of temporarily copying the areas to separate buffers (in a new tab page), it instead does the diff in the original windows and just fades out the unrelated parts.
  • My own AdvancedDiffOptions plugin has a :DiffIRange command that excludes certain lines from the diff, via a custom 'diffexpr' that filters the files via shell commands. The plugin can also filter by line and pattern.

homemade

On Unix, you can combine shell (e.g. Bash) features with common tools (sed) to just feed the extracted text contents to vim:

vimdiff <(sed -n '14,26p' file1.py) <(sed -n '30,60p' file2.py)

This uses process substitution (<(command)) to run command, and provide its output as a temporary file descriptor, which Vim can read just like any other file. sed with default output suppression (-n) is used to selectively choose lines (via the {range}print command); you could also use head, tail, or even grep, depending on the situation.

This works similar to my plugin; the downside here is that only the selected ranges are accessible inside Vim.

2
  • Ingo Karkat Works like a charm. In fact , I was able to compare parts inside the same file. But can this workflow be used while inside the vim. Something like file1.py is already opened in vim and I want to compare one function in it to other function file2.py. Something similar to vert diffsplit file2.py which compares the whole file
    – ankitj
    Mar 5, 2020 at 3:31
  • @ankitj Inside Vim, you'd have to remove all those lines you're not interested in (:{range}delete _), and then ensure that you don't accidentally :write those incomplete buffers. Plugins (at least the mentioned BlockDiff.vim) clone the selected buffer contents into scratch buffers; as that addresses the no-persistence and also enables diffing of two parts of the same buffer. So inside Vim, use of a plugin really is recommended for a good user experience. Mar 5, 2020 at 7:04

You must log in to answer this question.

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