Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
source: crates/forge_app/src/fmt/fmt_output.rs
expression: actual
---
1 |-Hello world
2 |-This is a test
1 |+Hello universe
2 |+This is a test
3 |+New line
1 |-Hello world
2 |-This is a test
1 |+Hello universe
2 |+This is a test
3 |+New line
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ expression: to_value(actual)
path="/home/user/existing_file.txt"
total_lines="1"
>
<file_diff><![CDATA[1 |-Old content
1 |+New content for the file
<file_diff><![CDATA[1 |-Old content
1 |+New content for the file
]]></file_diff>
</file_overwritten>
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ expression: to_value(actual)
<file_diff
path="/home/user/test.txt"
total_lines="2"
><![CDATA[1 |-Hello world
1 |+Hello universe
2 2 | This is a test
><![CDATA[1 |-Hello world
1 |+Hello universe
2 2 | This is a test
]]>
</file_diff>
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ expression: to_value(actual)
<file_diff
path="/home/user/large_file.txt"
total_lines="3"
><![CDATA[1 1 | line1
2 |+new line
2 3 | line2
><![CDATA[1 1 | line1
2 |+new line
2 3 | line2
]]>
<warning>Large file modification</warning>
</file_diff>
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ expression: to_value(actual)
<file_undo
path="/home/user/restored_file.txt"
status="restored"
><![CDATA[1 |-Original content
2 |-Before changes
1 |+Modified content
2 |+After restoration
><![CDATA[1 |-Original content
2 |-Before changes
1 |+Modified content
2 |+After restoration
]]>
</file_undo>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: to_value(actual)
<file_undo
path="/home/user/test.txt"
status="restored"
><![CDATA[1 |-ABC
1 |+PQR
><![CDATA[1 |-ABC
1 |+PQR
]]>
</file_undo>
86 changes: 79 additions & 7 deletions crates/forge_display/src/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ use std::fmt;
use console::{Style, style};
use similar::{ChangeTag, TextDiff};

struct Line(Option<usize>);
struct Line {
index: Option<usize>,
width: usize,
}

impl Line {
fn new(index: Option<usize>, width: usize) -> Self {
Self { index, width }
}
}

impl fmt::Display for Line {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
None => write!(f, " "),
Some(idx) => write!(f, "{:<4}", idx + 1),
match self.index {
None => write!(f, "{:width$}", "", width = self.width),
Some(idx) => write!(f, "{:<width$}", idx + 1, width = self.width),
}
}
}
Expand Down Expand Up @@ -52,6 +61,28 @@ impl DiffFormat {
return DiffResult { result: output, lines_added, lines_removed };
}

// First pass: Calculate dynamic width based on max line numbers in actual
// changes
let mut max_line_number = 0;
for group in &ops {
for op in group {
for change in diff.iter_inline_changes(op) {
if let Some(old_idx) = change.old_index() {
max_line_number = max_line_number.max(old_idx + 1);
}
if let Some(new_idx) = change.new_index() {
max_line_number = max_line_number.max(new_idx + 1);
}
}
}
}
let width = if max_line_number == 0 {
1
} else {
(max_line_number as f64).log10().floor() as usize + 1
};

// Second pass: Format the output
for (idx, group) in ops.iter().enumerate() {
if idx > 0 {
output.push_str(&format!("{}\n", style("...").dim()));
Expand All @@ -71,9 +102,9 @@ impl DiffFormat {
};

output.push_str(&format!(
"{}{} |{}",
style(Line(change.old_index())).dim(),
style(Line(change.new_index())).dim(),
"{} {} |{}",
style(Line::new(change.old_index(), width)).dim(),
style(Line::new(change.new_index(), width)).dim(),
s.apply_to(sign),
));

Expand Down Expand Up @@ -139,4 +170,45 @@ mod tests {
assert_eq!(diff.lines_removed(), 1);
assert_snapshot!(clean_diff);
}

#[test]
fn test_dynamic_width_with_large_line_numbers() {
// Test with 100+ lines to verify width calculation
let old_lines = (1..=150).map(|i| format!("line {}", i)).collect::<Vec<_>>();
let mut new_lines = old_lines.clone();
new_lines[99] = "modified line 100".to_string();

let old = old_lines.join("\n");
let new = new_lines.join("\n");
let diff = DiffFormat::format(&old, &new);
let clean_diff = strip_ansi_codes(&diff.diff());

// With 150 lines, width should be 3 (for numbers like "100")
// Verify the format includes proper spacing
assert!(clean_diff.contains("100"));
assert_eq!(diff.lines_added(), 1);
}

#[test]
fn test_width_based_on_diff_not_file_size() {
// Large file but diff only at the beginning
let old_lines = (1..=1000)
.map(|i| format!("line {}", i))
.collect::<Vec<_>>();
let mut new_lines = old_lines.clone();
new_lines[4] = "modified line 5".to_string(); // Only change line 5

let old = old_lines.join("\n");
let new = new_lines.join("\n");
let diff = DiffFormat::format(&old, &new);
let clean_diff = strip_ansi_codes(&diff.diff());

// Diff only shows lines 3-8 (context), so width should be 1 (for single digit
// numbers) NOT 4 (which would be needed for line 1000)
assert!(clean_diff.contains("3 3 | line 3"));
assert!(clean_diff.contains("5 |-line 5"));
assert_eq!(diff.lines_added(), 1);
assert_eq!(diff.lines_removed(), 1);
assert_snapshot!(clean_diff);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
source: crates/forge_display/src/diff.rs
expression: clean_diff
---
1 1 | line 1
2 |-line 2
2 |+modified line
3 3 | line 3
4 4 | line 5
5 5 | line 6
1 1 | line 1
2 |-line 2
2 |+modified line
3 3 | line 3
4 4 | line 5
5 5 | line 6
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
source: crates/forge_display/src/diff.rs
expression: clean_diff
---
1 1 | line 1
2 2 | line 2
3 |-line 3
4 |-line 4
5 |-line 5
3 |+line 3
1 1 | line 1
2 2 | line 2
3 |-line 3
4 |-line 4
5 |-line 5
3 |+line 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
source: crates/forge_display/src/diff.rs
expression: clean_diff
---
2 2 | line 2
3 3 | line 3
4 4 | line 4
5 |-line 5
5 |+modified line 5
6 6 | line 6
7 7 | line 7
8 8 | line 8
Loading