Add full Mercurial extdiff support

pull/41/head
Wilfred Hughes 2021-09-26 21:23:22 +07:00
parent 6ac01365c6
commit ec37c5bef1
5 changed files with 39 additions and 3 deletions

@ -4,6 +4,12 @@
Improved handling of paired delimiters, particularly in C, C++ and C#.
### Integration
Added support for Mercuial, see [this section in the
manual](http://difftastic.wilfred.me.uk/getting_started.html#mercurial-external-diffs)
for instructions.
### Build
Fix compilation for systems where the C++ compiler defaulted to a

1
Cargo.lock generated

@ -257,6 +257,7 @@ dependencies = [
"term_size",
"tree-sitter",
"typed-arena",
"walkdir",
]
[[package]]

@ -36,6 +36,7 @@ log = "0.4.14"
pretty_env_logger = "0.4.0"
mimalloc = { version = "0.1.26", default-features = false }
radix-heap = "0.3.8"
walkdir = "2.3.2"
[dev-dependencies]
pretty_assertions = "0.6.1"

@ -89,8 +89,7 @@ extdiff =
```
You can then run `hg extdiff -p difftastic` (assumes difftastic is on
your `$PATH`). **This currently only supports diffs where a single file
is modified.**
your `$PATH`).
You can also define an alias to run difftastic with hg. Add the
following to your `.hgrc` to run difftastic with `hg dft`.

@ -7,6 +7,7 @@ use atty::Stream;
use clap::{crate_version, App, AppSettings, Arg};
use std::{env, ffi::OsStr, path::Path};
use typed_arena::Arena;
use walkdir::WalkDir;
use difftastic::*;
use difftastic::{
@ -191,9 +192,14 @@ fn main() {
} => (display_path, lhs_path, rhs_path),
};
diff_file(&display_path, &lhs_path, &rhs_path);
if Path::new(&lhs_path).is_dir() && Path::new(&rhs_path).is_dir() {
diff_directories(&lhs_path, &rhs_path);
} else {
diff_file(&display_path, &lhs_path, &rhs_path);
}
}
// TODO: prefer PathBuf to &str for paths.
fn diff_file(display_path: &str, lhs_path: &str, rhs_path: &str) {
let lhs_bytes = read_or_die(lhs_path);
let rhs_bytes = read_or_die(rhs_path);
@ -276,3 +282,26 @@ fn diff_file(display_path: &str, lhs_path: &str, rhs_path: &str) {
}
println!();
}
/// Given two directories that contain the files, compare them
/// pairwise.
///
/// This is how the hg extdiff extension calls a diff tool when there
/// is more than one changed file.
fn diff_directories(lhs_dir: &str, rhs_dir: &str) {
for entry in WalkDir::new(lhs_dir).into_iter().filter_map(Result::ok) {
let lhs_path = entry.path();
if lhs_path.is_dir() {
continue;
}
let rel_path = lhs_path.strip_prefix(lhs_dir).unwrap();
let rhs_path = Path::new(rhs_dir).join(rel_path);
diff_file(
&rel_path.to_string_lossy(),
&lhs_path.to_string_lossy(),
&rhs_path.to_string_lossy(),
);
}
}