Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
e26e40413f | |||
5e2943624a | |||
32e186695a |
31
README.md
31
README.md
@ -24,34 +24,20 @@ You may need to add `~/bin` to your PATH variable if not already done. See [here
|
|||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
```help
|
```help
|
||||||
usage: vimtabdiff.py [-h] [--vim VIM] [--onlydiffs] pathA pathB
|
usage: vimtabdiff.py [-h] [--vim VIM] pathA pathB
|
||||||
|
|
||||||
Show diff of files from two directories in vim tabs
|
Show diff of files from two directories in vim tabs
|
||||||
|
|
||||||
positional arguments:
|
positional arguments:
|
||||||
pathA
|
pathA
|
||||||
pathB
|
pathB
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
--vim VIM vim command to run
|
--vim VIM vim command to run
|
||||||
--onlydiffs only open files where there is a diff
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Relevant vim tips
|
# Git difftool
|
||||||
|
|
||||||
* `gt` → Go to next tab
|
|
||||||
* `gT` → Go to previous tab
|
|
||||||
* `:tabr` → Go to first tab
|
|
||||||
* `:drop filenam<Tab>` → Go to the tab with filename
|
|
||||||
* `g<Tab>` → Go to last used tab (Works in vim version > 8.2.1401)
|
|
||||||
* `:set mouse=a` → Now clicking on a tab works
|
|
||||||
* `]c` → Go to next diff hunk
|
|
||||||
* `[c` → Go to previous diff hunk
|
|
||||||
* `do`, `dp` → Diff obtain, Diff put
|
|
||||||
* `zo`, `zc`, `zi` → Fold open, Fold close, toggle all folds
|
|
||||||
|
|
||||||
# See Git diffs
|
|
||||||
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
@ -79,7 +65,7 @@ Using clean vim without reading `vimrc`
|
|||||||
|
|
||||||
Git config file (`~/.gitconfig`) should look like this
|
Git config file (`~/.gitconfig`) should look like this
|
||||||
|
|
||||||
```TOML
|
```toml
|
||||||
[alias]
|
[alias]
|
||||||
...
|
...
|
||||||
dt = difftool --tool vimtabdiff --dir-diff
|
dt = difftool --tool vimtabdiff --dir-diff
|
||||||
@ -97,7 +83,4 @@ Using better diff algorithm
|
|||||||
|
|
||||||
# Similar
|
# Similar
|
||||||
|
|
||||||
* https://gist.github.com/Osse/4709787 is very similar, written as a `zsh` script.
|
https://gist.github.com/Osse/4709787
|
||||||
* https://github.com/will133/vim-dirdiff is a Vim plugin that uses an interactive list of files instead of tabs.
|
|
||||||
* https://github.com/Soares/tabdiff.vim is a Vim plugin takes a list of files as aguments.
|
|
||||||
* [`:Git difftool -y`](https://github.com/tpope/vim-fugitive/blob/d507d00bd04794119beeb41da118774a96815b65/doc/fugitive.txt#L92) is a command from vim-fugitive which is a vim git plugin.
|
|
||||||
|
@ -1,45 +1,34 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
|
import pathlib
|
||||||
import itertools
|
import itertools
|
||||||
import tempfile
|
import tempfile
|
||||||
import subprocess
|
import subprocess
|
||||||
import shlex
|
import shlex
|
||||||
from pathlib import Path
|
|
||||||
from typing import TypeVar
|
|
||||||
from collections.abc import Iterator, Callable
|
|
||||||
|
|
||||||
R = TypeVar('R')
|
def star(f):
|
||||||
|
|
||||||
|
|
||||||
def star(f: Callable[..., R]) -> Callable[[tuple], R]:
|
|
||||||
""" see https://stackoverflow.com/q/21892989 """
|
""" see https://stackoverflow.com/q/21892989 """
|
||||||
return lambda args: f(*args)
|
return lambda args: f(*args)
|
||||||
|
|
||||||
|
|
||||||
def parse_args() -> argparse.Namespace:
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Show diff of files from two directories in vim tabs",
|
description="Show diff of files from two directories in vim tabs",
|
||||||
epilog="See https://github.com/balki/vimtabdiff for more info")
|
epilog="See https://github.com/balki/vimtabdiff for more info")
|
||||||
parser.add_argument("pathA", type=Path)
|
parser.add_argument("pathA")
|
||||||
parser.add_argument("pathB", type=Path)
|
parser.add_argument("pathB")
|
||||||
parser.add_argument("--vim", help="vim command to run", default="vim")
|
parser.add_argument("--vim", help="vim command to run", default="vim")
|
||||||
parser.add_argument(
|
|
||||||
"--onlydiffs", help="only open files where there is a diff", action="store_true"
|
|
||||||
)
|
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def get_dir_info(dirpath: Path | None) -> tuple[list[Path], list[Path]]:
|
def get_dir_info(dirname):
|
||||||
if not dirpath:
|
if not dirname:
|
||||||
return [], []
|
return [], []
|
||||||
dirs, files = [], []
|
dirs, files = [], []
|
||||||
for p in dirpath.iterdir():
|
dirp = pathlib.Path(dirname)
|
||||||
|
for p in dirp.iterdir():
|
||||||
if p.is_dir():
|
if p.is_dir():
|
||||||
dirs.append(p)
|
dirs.append(p)
|
||||||
else:
|
else:
|
||||||
@ -47,26 +36,27 @@ def get_dir_info(dirpath: Path | None) -> tuple[list[Path], list[Path]]:
|
|||||||
return dirs, files
|
return dirs, files
|
||||||
|
|
||||||
|
|
||||||
def get_pairs(aPaths: list[Path],
|
def get_pairs(aItems, bItems):
|
||||||
bPaths: list[Path]) -> Iterator[tuple[Path | None, Path | None]]:
|
aItems = [(item, 'A') for item in aItems]
|
||||||
aItems = [(item, 'A') for item in aPaths]
|
bItems = [(item, 'B') for item in bItems]
|
||||||
bItems = [(item, 'B') for item in bPaths]
|
|
||||||
abItems = aItems + bItems
|
abItems = aItems + bItems
|
||||||
abItems.sort(key=star(lambda item, tag: (item.name, tag)))
|
abItems.sort(key=star(lambda item, tag: (item.name, tag)))
|
||||||
for _, items in itertools.groupby(abItems,
|
for _, items in itertools.groupby(abItems,
|
||||||
key=star(lambda item, _: item.name)):
|
key=star(lambda item, _: item.name)):
|
||||||
match list(items):
|
items = list(items)
|
||||||
case [(aItem, _), (bItem, _)]:
|
# NOTE: python 3.10's match expression can make this better
|
||||||
|
if len(items) == 2:
|
||||||
|
(aItem, _), (bItem, _) = items
|
||||||
yield aItem, bItem
|
yield aItem, bItem
|
||||||
case [(item, 'A'),]:
|
else:
|
||||||
|
(item, tag), = items
|
||||||
|
if tag == 'A':
|
||||||
yield item, None
|
yield item, None
|
||||||
case [(item, 'B'),]:
|
else:
|
||||||
yield None, item
|
yield None, item
|
||||||
|
|
||||||
|
|
||||||
def get_file_pairs(
|
def get_file_pairs(a, b):
|
||||||
a: Path | None,
|
|
||||||
b: Path | None) -> Iterator[tuple[Path | None, Path | None]]:
|
|
||||||
aDirs, aFiles = get_dir_info(a)
|
aDirs, aFiles = get_dir_info(a)
|
||||||
bDirs, bFiles = get_dir_info(b)
|
bDirs, bFiles = get_dir_info(b)
|
||||||
yield from get_pairs(aFiles, bFiles)
|
yield from get_pairs(aFiles, bFiles)
|
||||||
@ -74,7 +64,7 @@ def get_file_pairs(
|
|||||||
yield from get_file_pairs(aDir, bDir)
|
yield from get_file_pairs(aDir, bDir)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
vimCmdFile = tempfile.NamedTemporaryFile(mode='w', delete=False)
|
vimCmdFile = tempfile.NamedTemporaryFile(mode='w', delete=False)
|
||||||
with vimCmdFile:
|
with vimCmdFile:
|
||||||
@ -86,13 +76,9 @@ def main() -> None:
|
|||||||
for a, b in get_file_pairs(args.pathA, args.pathB):
|
for a, b in get_file_pairs(args.pathA, args.pathB):
|
||||||
aPath = a.resolve() if a else os.devnull
|
aPath = a.resolve() if a else os.devnull
|
||||||
bPath = b.resolve() if b else os.devnull
|
bPath = b.resolve() if b else os.devnull
|
||||||
if (
|
print(
|
||||||
args.onlydiffs
|
f"tabedit {aPath} | vsp {bPath}",
|
||||||
and a and b
|
file=vimCmdFile)
|
||||||
and open(aPath, mode="rb").read() == open(bPath, mode="rb").read()
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
print(f"tabedit {aPath} | vsp {bPath}", file=vimCmdFile)
|
|
||||||
cmds = f"""
|
cmds = f"""
|
||||||
let &splitright = s:spr
|
let &splitright = s:spr
|
||||||
tabdo windo :1
|
tabdo windo :1
|
||||||
|
Loading…
Reference in New Issue
Block a user