Skip to content

Commit

Permalink
files: make DiffLineIterator accept generic DiffLine iterator
Browse files Browse the repository at this point in the history
I'm thinking of adding some heuristics to render hunks containing lots of
small word changes differently, in a similar manner to the unified diffs. This
patch might help add some pre/post-processing at consumer.

files::diff() is inlined to caller to get around 'self borrowing.
  • Loading branch information
yuja committed Aug 15, 2024
1 parent f857922 commit 78c0128
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 18 deletions.
7 changes: 3 additions & 4 deletions cli/src/diff_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use jj_lib::commit::Commit;
use jj_lib::conflicts::{
materialized_diff_stream, MaterializedTreeDiffEntry, MaterializedTreeValue,
};
use jj_lib::diff::{Diff, DiffHunk};
use jj_lib::files::DiffLine;
use jj_lib::diff::{self, Diff, DiffHunk};
use jj_lib::files::{DiffLine, DiffLineIterator};
use jj_lib::matchers::Matcher;
use jj_lib::merge::MergedTreeValue;
use jj_lib::merged_tree::{MergedTree, TreeDiffEntry, TreeDiffStream};
Expand All @@ -35,7 +35,6 @@ use jj_lib::repo::Repo;
use jj_lib::repo_path::{RepoPath, RepoPathUiConverter};
use jj_lib::settings::{ConfigResultExt as _, UserSettings};
use jj_lib::store::Store;
use jj_lib::{diff, files};
use pollster::FutureExt;
use thiserror::Error;
use tracing::instrument;
Expand Down Expand Up @@ -401,7 +400,7 @@ fn show_color_words_diff_hunks(
let mut skipped_context = false;
// Are the lines in `context` to be printed before the next modified line?
let mut context_before = true;
for diff_line in files::diff(left, right) {
for diff_line in DiffLineIterator::new(Diff::default_refinement([left, right]).hunks()) {
if diff_line.is_unmodified() {
context.push_back(diff_line.clone());
let mut start_skipping_context = false;
Expand Down
32 changes: 18 additions & 14 deletions lib/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

#![allow(missing_docs)]

use std::borrow::Borrow;
use std::collections::VecDeque;
use std::fmt::{Debug, Error, Formatter};
use std::{iter, vec};
use std::iter;

use crate::diff;
use crate::diff::{Diff, DiffHunk};
use crate::merge::{trivial_merge, Merge};

Expand All @@ -45,19 +45,19 @@ impl DiffLine<'_> {
}
}

pub fn diff<'a>(left: &'a [u8], right: &'a [u8]) -> DiffLineIterator<'a> {
let diff_hunks = diff::diff(left, right);
DiffLineIterator::new(diff_hunks)
}

pub struct DiffLineIterator<'a> {
diff_hunks: iter::Fuse<vec::IntoIter<DiffHunk<'a>>>,
pub struct DiffLineIterator<'a, I> {
diff_hunks: iter::Fuse<I>,
current_line: DiffLine<'a>,
queued_lines: VecDeque<DiffLine<'a>>,
}

impl<'a> DiffLineIterator<'a> {
fn new(diff_hunks: Vec<DiffHunk<'a>>) -> Self {
impl<'a, I> DiffLineIterator<'a, I>
where
I: Iterator,
I::Item: Borrow<DiffHunk<'a>>,
{
/// Iterates `diff_hunks` by line. Each hunk should have exactly two inputs.
pub fn new(diff_hunks: I) -> Self {
let current_line = DiffLine {
left_line_number: 1,
right_line_number: 1,
Expand All @@ -66,14 +66,18 @@ impl<'a> DiffLineIterator<'a> {
hunks: vec![],
};
DiffLineIterator {
diff_hunks: diff_hunks.into_iter().fuse(),
diff_hunks: diff_hunks.fuse(),
current_line,
queued_lines: VecDeque::new(),
}
}
}

impl<'a> Iterator for DiffLineIterator<'a> {
impl<'a, I> Iterator for DiffLineIterator<'a, I>
where
I: Iterator,
I::Item: Borrow<DiffHunk<'a>>,
{
type Item = DiffLine<'a>;

fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -83,7 +87,7 @@ impl<'a> Iterator for DiffLineIterator<'a> {
let Some(hunk) = self.diff_hunks.next() else {
break;
};
match &hunk {
match hunk.borrow() {
DiffHunk::Matching(text) => {
let lines = text.split_inclusive(|b| *b == b'\n');
for line in lines {
Expand Down

0 comments on commit 78c0128

Please sign in to comment.