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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Added the ability to change the style for line_diff via `ContextConfig` (#27)

### Removed

## 0.7.1
Expand Down
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,45 @@ void func3(){}
println!("diff_lines:");
println!("{}", diff_lines(code1_a, code1_b));
```
#### Diff Lines with Custom Config

![diff_lines](screens/diff_lines_format-color.png)

```rust
use prettydiff::{diff_lines, text:ContextConfig};
use owo_colors::Style;

let context = ContextConfig {
context_size: 2,
skipping_marker: "...",
remove_color: Style::new().red().underline(),
insert_color: Style::new().purple().bold(),
};

let code1_a = r#"
void func1() {
x += 1
}

void func2() {
x += 2
}
"#;
let code1_b = r#"
void func1(a: u32) {
x += 1
}

void functhreehalves() {
x += 1.5
}

void func2() {
x += 2
}

void func3(){}
"#;
println!("diff_lines:");
println!("{}", diff_lines(code1_a, code1_b).format_with_context(Some(context), true));
```
Binary file added screens/diff_lines_format-color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions src/lcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ where
Table { x, y, table }
}

fn seq_iter(&self) -> TableIter<T> {
fn seq_iter(&self) -> TableIter<'_, T> {
TableIter {
x: self.x.len(),
y: self.y.len(),
table: self,
}
}
fn get_match(&self, x: usize, y: usize, len: usize) -> Match<T> {
fn get_match(&self, x: usize, y: usize, len: usize) -> Match<'_, T> {
Match {
x,
y,
Expand All @@ -58,7 +58,7 @@ where
}

/// Returns matches between X and Y
pub fn matches(&self) -> Vec<Match<T>> {
pub fn matches(&self) -> Vec<Match<'_, T>> {
let mut matches: Vec<Match<T>> = Vec::new();
for (x, y) in self.seq_iter() {
if let Some(last) = matches.last_mut() {
Expand All @@ -76,7 +76,7 @@ where
}

/// Returns matches between X and Y with zero-len match at the end
pub fn matches_zero(&self) -> Vec<Match<T>> {
pub fn matches_zero(&self) -> Vec<Match<'_, T>> {
let mut matches = self.matches();
matches.push(self.get_match(self.x.len(), self.y.len(), 0));
matches
Expand Down
55 changes: 39 additions & 16 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@ fn color_multilines(color: AnsiColors, s: &str) -> String {
pub struct ContextConfig<'a> {
pub context_size: usize,
pub skipping_marker: &'a str,
pub remove_color: Style,
pub insert_color: Style,
}

impl<'a> Default for ContextConfig<'a> {
fn default() -> Self {
ContextConfig {
context_size: 0,
skipping_marker: "",
remove_color: Style::new().red().strikethrough(),
insert_color: Style::new().green(),
}
}
}

/// Container for line-by-line text diff result. Can be pretty-printed by Display trait.
Expand Down Expand Up @@ -414,12 +427,8 @@ impl<'a> LineChangeset<'a> {
table.print(f)
}

fn remove_color(&self, a: &str) -> String {
a.red().strikethrough().to_string()
}

fn insert_color(&self, a: &str) -> String {
a.green().to_string()
fn apply_style(&self, a: &str, style: Style) -> String {
a.style(style).to_string()
}

/// Returns formatted string with colors
Expand Down Expand Up @@ -457,16 +466,17 @@ impl<'a> LineChangeset<'a> {
display_line_numbers: bool,
prefix_size: usize,
line_counter: &mut usize,
remove_style: Style,
) -> String {
lines
.iter()
.map(|line| {
let res = if display_line_numbers {
// Pad and align the line number to the right
format!("{:>size$} ", *line_counter, size = prefix_size - 1)
+ &self.remove_color(line)
+ &self.apply_style(line, remove_style)
} else {
" ".repeat(prefix_size) + &self.remove_color(line)
" ".repeat(prefix_size) + &self.apply_style(line, remove_style)
};
*line_counter += 1;
res
Expand All @@ -476,10 +486,10 @@ impl<'a> LineChangeset<'a> {
}

/// Formats lines in DiffOp::Insert
fn format_insert(&self, lines: &[&str], prefix_size: usize) -> String {
fn format_insert(&self, lines: &[&str], prefix_size: usize, insert_style: Style) -> String {
lines
.iter()
.map(|line| " ".repeat(prefix_size) + &self.insert_color(line))
.map(|line| " ".repeat(prefix_size) + &self.apply_style(line, insert_style))
.reduce(|acc, line| acc + "\n" + &line)
.unwrap()
}
Expand All @@ -498,14 +508,20 @@ impl<'a> LineChangeset<'a> {
} else {
0
};
let skipping_marker_size = if let Some(ContextConfig {
skipping_marker, ..

let (skipping_marker_size, remove_color, insert_color) = if let Some(ContextConfig {
skipping_marker,
remove_color,
insert_color,
..
}) = context_config
Comment thread
oli-obk marked this conversation as resolved.
{
skipping_marker.len()
(skipping_marker.len(), remove_color, insert_color)
} else {
0
let c = ContextConfig::default();
(c.skipping_marker.len(), c.remove_color, c.insert_color)
};

let prefix_size = max(line_number_size, skipping_marker_size) + 1;

let mut next_line = 1;
Expand All @@ -520,6 +536,7 @@ impl<'a> LineChangeset<'a> {
Some(ContextConfig {
context_size,
skipping_marker,
..
}) => {
let mut lines = a;
if !at_beginning {
Expand Down Expand Up @@ -559,21 +576,25 @@ impl<'a> LineChangeset<'a> {
}
}
},
basic::DiffOp::Insert(a) => out.push(self.format_insert(a, prefix_size)),
basic::DiffOp::Insert(a) => {
out.push(self.format_insert(a, prefix_size, insert_color))
}
basic::DiffOp::Remove(a) => out.push(self.format_remove(
a,
display_line_numbers,
prefix_size,
&mut next_line,
remove_color,
)),
basic::DiffOp::Replace(a, b) => {
out.push(self.format_remove(
a,
display_line_numbers,
prefix_size,
&mut next_line,
remove_color,
));
out.push(self.format_insert(b, prefix_size));
out.push(self.format_insert(b, prefix_size, insert_color));
}
}
at_beginning = false;
Expand Down Expand Up @@ -869,6 +890,8 @@ fn test_format_with_context() {
let context = |n| ContextConfig {
context_size: n,
skipping_marker: "...",
remove_color: Default::default(),
insert_color: Default::default(),
};
println!(
"diff_lines:\n{}\n{:?}",
Expand Down
Loading