Balakrishnan Balasubramanian
5e2943624a
This allows to include spaces in vim command
Add example to change default diff algorithm
Move to first line on each file
Backport from da5e24260
96 lines
2.6 KiB
Python
Executable File
96 lines
2.6 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import os
|
|
import argparse
|
|
import pathlib
|
|
import itertools
|
|
import tempfile
|
|
import subprocess
|
|
import shlex
|
|
|
|
def star(f):
|
|
""" see https://stackoverflow.com/q/21892989 """
|
|
return lambda args: f(*args)
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(
|
|
description="Show diff of files from two directories in vim tabs",
|
|
epilog="See https://github.com/balki/vimtabdiff for more info")
|
|
parser.add_argument("pathA")
|
|
parser.add_argument("pathB")
|
|
parser.add_argument("--vim", help="vim command to run", default="vim")
|
|
return parser.parse_args()
|
|
|
|
|
|
def get_dir_info(dirname):
|
|
if not dirname:
|
|
return [], []
|
|
dirs, files = [], []
|
|
dirp = pathlib.Path(dirname)
|
|
for p in dirp.iterdir():
|
|
if p.is_dir():
|
|
dirs.append(p)
|
|
else:
|
|
files.append(p)
|
|
return dirs, files
|
|
|
|
|
|
def get_pairs(aItems, bItems):
|
|
aItems = [(item, 'A') for item in aItems]
|
|
bItems = [(item, 'B') for item in bItems]
|
|
abItems = aItems + bItems
|
|
abItems.sort(key=star(lambda item, tag: (item.name, tag)))
|
|
for _, items in itertools.groupby(abItems,
|
|
key=star(lambda item, _: item.name)):
|
|
items = list(items)
|
|
# NOTE: python 3.10's match expression can make this better
|
|
if len(items) == 2:
|
|
(aItem, _), (bItem, _) = items
|
|
yield aItem, bItem
|
|
else:
|
|
(item, tag), = items
|
|
if tag == 'A':
|
|
yield item, None
|
|
else:
|
|
yield None, item
|
|
|
|
|
|
def get_file_pairs(a, b):
|
|
aDirs, aFiles = get_dir_info(a)
|
|
bDirs, bFiles = get_dir_info(b)
|
|
yield from get_pairs(aFiles, bFiles)
|
|
for aDir, bDir in get_pairs(aDirs, bDirs):
|
|
yield from get_file_pairs(aDir, bDir)
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
vimCmdFile = tempfile.NamedTemporaryFile(mode='w', delete=False)
|
|
with vimCmdFile:
|
|
cmds = f"""
|
|
let s:spr = &splitright
|
|
set splitright
|
|
"""
|
|
print(cmds, file=vimCmdFile)
|
|
for a, b in get_file_pairs(args.pathA, args.pathB):
|
|
aPath = a.resolve() if a else os.devnull
|
|
bPath = b.resolve() if b else os.devnull
|
|
print(
|
|
f"tabedit {aPath} | vsp {bPath}",
|
|
file=vimCmdFile)
|
|
cmds = f"""
|
|
let &splitright = s:spr
|
|
tabdo windo :1
|
|
tabdo windo diffthis
|
|
tabdo windo diffupdate
|
|
tabfirst | tabclose
|
|
call delete("{vimCmdFile.name}")
|
|
"""
|
|
print(cmds, file=vimCmdFile)
|
|
subprocess.run(shlex.split(args.vim) + ["-S", vimCmdFile.name])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|