Skip to content

Commit

Permalink
feat: diff view with --diff (-d) flag
Browse files Browse the repository at this point in the history
  • Loading branch information
nc7s committed Nov 25, 2023
1 parent 78748f3 commit 694f017
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 24 deletions.
59 changes: 36 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ memmap2 = "0.9.0"
tempfile = "3.8.0"
thiserror = "1.0.50"
clap.workspace = true
similar = { version = "2.3.0", features = ["inline", "bytes"] }

[dev-dependencies]
assert_cmd = "2.0.12"
Expand Down
5 changes: 5 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ pub struct Options {
/// format are likely to change in the future).
pub preview: bool,

#[arg(short, long)]
/// Show changes as a unified diff. You may want to use a rich
/// color pager to colorize it.
pub diff: bool,

#[arg(
short = 'F',
long = "fixed-strings",
Expand Down
28 changes: 28 additions & 0 deletions src/diff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use similar::TextDiff;
use std::path::Path;

use crate::error::{Error, Result};

pub(crate) fn create_udiff<UO: AsRef<[u8]>, UN: AsRef<[u8]>>(
old: UO,
new: UN,
context: usize,
path: Option<&Path>,
) -> Result<String> {
let diff = TextDiff::from_lines(old.as_ref(), new.as_ref());
let path = if let Some(path) = path {
if let Some(spath) = path.to_str() {
spath
} else {
return Err(Error::InvalidPath(path.into()));
}
} else {
""
};

let mut udiff = diff.unified_diff();
udiff.header(path, path);
udiff.context_radius(context);

Ok(udiff.to_string())
}
20 changes: 19 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod cli;
mod error;
mod input;

pub(crate) mod diff;
pub(crate) mod replacer;

use clap::Parser;
Expand Down Expand Up @@ -69,7 +70,9 @@ fn try_main() -> Result<()> {
.collect()
};

if options.preview || sources.first() == Some(&Source::Stdin) {
if options.preview
|| sources.first() == Some(&Source::Stdin) && !options.diff
{
let mut handle = stdout().lock();

for (source, replaced) in sources.iter().zip(replaced) {
Expand All @@ -78,6 +81,21 @@ fn try_main() -> Result<()> {
}
handle.write_all(&replaced)?;
}
} else if options.diff {
use crate::diff::create_udiff;

let mut handle = stdout().lock();

for ((source, mmap), replaced) in
sources.iter().zip(&mmaps).zip(replaced)
{
let path = match source {
Source::Stdin => None,
Source::File(path) => Some(path.as_path()),
};
// TODO: custom context radius
writeln!(handle, "{}", create_udiff(mmap, replaced, 3, path)?)?;
}
} else {
// Windows requires closing mmap before writing:
// > The requested operation cannot be performed on a file with a user-mapped section open
Expand Down

0 comments on commit 694f017

Please sign in to comment.