Dave Vogt
Dave Vogt

Reputation: 19502

(gnu) diff - display corresponding line numbers

I'm trying to build a diff viewer plugin for my text editor (Kakoune). I'm comparing two files and marking any lines that are different across two panes.

However the two views don't scroll simultaneously. My idea is to get a list of line numbers that correspond to each other, so I can place the cursor correctly when switching panes, or scroll the secondary window when the primary one scrolls, etc.

So - Is there a way to get a list of corresponding numbers from commandline diff?

I'm hoping for something along the following example: Given file A and B, the output should tell me which line numbers (of the ones that didn't change) would correspond.

File A         File B            Output          
1: hello       1: hello          1:1
2: world       2: another        2:3
3: this        3: world          3:4
4: is          4: this           4:5
5: a           5: is
6: test        6: eof

The goal is that when I scroll to line 4 in file A, I'll know to scroll file B such that it's line 5 is rendered at the same position.

Doesn't have to be Gnu diff, but should only use tools that are available on most/all linux boxes.

Upvotes: 0

Views: 246

Answers (1)

alani
alani

Reputation: 13069

I can get some of the way using GNU diff, but then need a python script to post-process it to turn a group-based output into line-based.

#!/usr/bin/env python

import sys
import subprocess

file1, file2 = sys.argv[1:]

cmd = ["diff",
       "--changed-group-format=",
       "--unchanged-group-format=%df %dl %dF %dL,",
       file1,
       file2]

p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = p.communicate()[0]

for item in output.split(",")[:-1]:
    start1, end1, start2, end2 = [int(s) for s in item.split()]
    n = end1 - start1 + 1
    assert(n == end2 - start2 + 1)  # unchanged group, should be same length in each file
    for i in range(n):
        print("{}:{}".format(start1 + i, start2 + i))

gives:

$ ./compare.py fileA fileB
1:1
2:3
3:4
4:5

Upvotes: 1

Related Questions