Skip to content

Commit e028308

Browse files
committed
Implement --tabsize option
1 parent 8d65c2b commit e028308

File tree

9 files changed

+207
-40
lines changed

9 files changed

+207
-40
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ path = "src/main.rs"
1616

1717
[dependencies]
1818
diff = "0.1.10"
19+
regex = "1.10.3"
1920
same-file = "1.0.6"
2021
unicode-width = "0.1.11"
2122

src/context_diff.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ pub fn diff(
273273
context_size: usize,
274274
stop_early: bool,
275275
expand_tabs: bool,
276+
tabsize: usize,
276277
) -> Vec<u8> {
277278
let mut output = format!("*** {expected_filename}\t\n--- {actual_filename}\t\n").into_bytes();
278279
let diff_results = make_diff(expected, actual, context_size, stop_early);
@@ -317,19 +318,19 @@ pub fn diff(
317318
match line {
318319
DiffLine::Context(e) => {
319320
write!(output, " ").expect("write to Vec is infallible");
320-
do_write_line(&mut output, &e, expand_tabs)
321+
do_write_line(&mut output, &e, expand_tabs, tabsize)
321322
.expect("write to Vec is infallible");
322323
writeln!(output).unwrap();
323324
}
324325
DiffLine::Change(e) => {
325326
write!(output, "! ").expect("write to Vec is infallible");
326-
do_write_line(&mut output, &e, expand_tabs)
327+
do_write_line(&mut output, &e, expand_tabs, tabsize)
327328
.expect("write to Vec is infallible");
328329
writeln!(output).unwrap();
329330
}
330331
DiffLine::Add(e) => {
331332
write!(output, "- ").expect("write to Vec is infallible");
332-
do_write_line(&mut output, &e, expand_tabs)
333+
do_write_line(&mut output, &e, expand_tabs, tabsize)
333334
.expect("write to Vec is infallible");
334335
writeln!(output).unwrap();
335336
}
@@ -347,19 +348,19 @@ pub fn diff(
347348
match line {
348349
DiffLine::Context(e) => {
349350
write!(output, " ").expect("write to Vec is infallible");
350-
do_write_line(&mut output, &e, expand_tabs)
351+
do_write_line(&mut output, &e, expand_tabs, tabsize)
351352
.expect("write to Vec is infallible");
352353
writeln!(output).unwrap();
353354
}
354355
DiffLine::Change(e) => {
355356
write!(output, "! ").expect("write to Vec is infallible");
356-
do_write_line(&mut output, &e, expand_tabs)
357+
do_write_line(&mut output, &e, expand_tabs, tabsize)
357358
.expect("write to Vec is infallible");
358359
writeln!(output).unwrap();
359360
}
360361
DiffLine::Add(e) => {
361362
write!(output, "+ ").expect("write to Vec is infallible");
362-
do_write_line(&mut output, &e, expand_tabs)
363+
do_write_line(&mut output, &e, expand_tabs, tabsize)
363364
.expect("write to Vec is infallible");
364365
writeln!(output).unwrap();
365366
}
@@ -434,6 +435,7 @@ mod tests {
434435
2,
435436
false,
436437
false,
438+
8,
437439
);
438440
File::create(&format!("{target}/ab.diff"))
439441
.unwrap()
@@ -514,6 +516,7 @@ mod tests {
514516
2,
515517
false,
516518
false,
519+
8,
517520
);
518521
File::create(&format!("{target}/ab_.diff"))
519522
.unwrap()
@@ -597,6 +600,7 @@ mod tests {
597600
2,
598601
false,
599602
false,
603+
8,
600604
);
601605
File::create(&format!("{target}/abx.diff"))
602606
.unwrap()
@@ -683,6 +687,7 @@ mod tests {
683687
2,
684688
false,
685689
false,
690+
8,
686691
);
687692
File::create(&format!("{target}/abr.diff"))
688693
.unwrap()
@@ -729,6 +734,7 @@ mod tests {
729734
context_size,
730735
false,
731736
false,
737+
8,
732738
);
733739
let expected_full = [
734740
"*** foo\t",
@@ -755,6 +761,7 @@ mod tests {
755761
context_size,
756762
true,
757763
false,
764+
8,
758765
);
759766
let expected_brief = ["*** foo\t", "--- bar\t", ""].join("\n");
760767
assert_eq!(diff_brief, expected_brief.as_bytes());
@@ -767,6 +774,7 @@ mod tests {
767774
context_size,
768775
false,
769776
false,
777+
8,
770778
);
771779
assert!(nodiff_full.is_empty());
772780

@@ -778,6 +786,7 @@ mod tests {
778786
context_size,
779787
true,
780788
false,
789+
8,
781790
);
782791
assert!(nodiff_brief.is_empty());
783792
}

src/ed_diff.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ pub fn diff(
114114
actual: &[u8],
115115
stop_early: bool,
116116
expand_tabs: bool,
117+
tabsize: usize,
117118
) -> Result<Vec<u8>, DiffError> {
118119
let mut output = Vec::new();
119120
let diff_results = make_diff(expected, actual, stop_early)?;
@@ -152,7 +153,7 @@ pub fn diff(
152153
if actual == b"." {
153154
writeln!(&mut output, "..\n.\ns/.//\na").unwrap();
154155
} else {
155-
do_write_line(&mut output, actual, expand_tabs).unwrap();
156+
do_write_line(&mut output, actual, expand_tabs, tabsize).unwrap();
156157
writeln!(&mut output).unwrap();
157158
}
158159
}
@@ -167,7 +168,7 @@ mod tests {
167168
use super::*;
168169
use pretty_assertions::assert_eq;
169170
pub fn diff_w(expected: &[u8], actual: &[u8], filename: &str) -> Result<Vec<u8>, DiffError> {
170-
let mut output = diff(expected, actual, false, false)?;
171+
let mut output = diff(expected, actual, false, false, 8)?;
171172
writeln!(&mut output, "w {filename}").unwrap();
172173
Ok(output)
173174
}
@@ -176,7 +177,7 @@ mod tests {
176177
fn test_basic() {
177178
let from = b"a\n";
178179
let to = b"b\n";
179-
let diff = diff(from, to, false, false).unwrap();
180+
let diff = diff(from, to, false, false, 8).unwrap();
180181
let expected = ["1c", "b", ".", ""].join("\n");
181182
assert_eq!(diff, expected.as_bytes());
182183
}
@@ -411,18 +412,18 @@ mod tests {
411412
let from = ["a", "b", "c", ""].join("\n");
412413
let to = ["a", "d", "c", ""].join("\n");
413414

414-
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false).unwrap();
415+
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false, 8).unwrap();
415416
let expected_full = ["2c", "d", ".", ""].join("\n");
416417
assert_eq!(diff_full, expected_full.as_bytes());
417418

418-
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false).unwrap();
419+
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false, 8).unwrap();
419420
let expected_brief = "\0".as_bytes();
420421
assert_eq!(diff_brief, expected_brief);
421422

422-
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false).unwrap();
423+
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false, 8).unwrap();
423424
assert!(nodiff_full.is_empty());
424425

425-
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false).unwrap();
426+
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false, 8).unwrap();
426427
assert!(nodiff_brief.is_empty());
427428
}
428429
}

src/main.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn main() -> ExitCode {
3232
report_identical_files,
3333
brief,
3434
expand_tabs,
35+
tabsize,
3536
} = parse_params(opts).unwrap_or_else(|error| {
3637
eprintln!("{error}");
3738
exit(2);
@@ -67,7 +68,9 @@ fn main() -> ExitCode {
6768
};
6869
// run diff
6970
let result: Vec<u8> = match format {
70-
Format::Normal => normal_diff::diff(&from_content, &to_content, brief, expand_tabs),
71+
Format::Normal => {
72+
normal_diff::diff(&from_content, &to_content, brief, expand_tabs, tabsize)
73+
}
7174
Format::Unified => unified_diff::diff(
7275
&from_content,
7376
&from.to_string_lossy(),
@@ -76,6 +79,7 @@ fn main() -> ExitCode {
7679
context_count,
7780
brief,
7881
expand_tabs,
82+
tabsize,
7983
),
8084
Format::Context => context_diff::diff(
8185
&from_content,
@@ -85,13 +89,13 @@ fn main() -> ExitCode {
8589
context_count,
8690
brief,
8791
expand_tabs,
92+
tabsize,
8893
),
89-
Format::Ed => {
90-
ed_diff::diff(&from_content, &to_content, brief, expand_tabs).unwrap_or_else(|error| {
94+
Format::Ed => ed_diff::diff(&from_content, &to_content, brief, expand_tabs, tabsize)
95+
.unwrap_or_else(|error| {
9196
eprintln!("{error}");
9297
exit(2);
93-
})
94-
}
98+
}),
9599
};
96100
if brief && !result.is_empty() {
97101
println!(

src/normal_diff.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,13 @@ fn make_diff(expected: &[u8], actual: &[u8], stop_early: bool) -> Vec<Mismatch>
116116
}
117117

118118
#[must_use]
119-
pub fn diff(expected: &[u8], actual: &[u8], stop_early: bool, expand_tabs: bool) -> Vec<u8> {
119+
pub fn diff(
120+
expected: &[u8],
121+
actual: &[u8],
122+
stop_early: bool,
123+
expand_tabs: bool,
124+
tabsize: usize,
125+
) -> Vec<u8> {
120126
// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Normal.html
121127
// for details on the syntax of the normal format.
122128
let mut output = Vec::new();
@@ -190,7 +196,7 @@ pub fn diff(expected: &[u8], actual: &[u8], stop_early: bool, expand_tabs: bool)
190196
}
191197
for expected in &result.expected {
192198
write!(&mut output, "< ").unwrap();
193-
do_write_line(&mut output, expected, expand_tabs).unwrap();
199+
do_write_line(&mut output, expected, expand_tabs, tabsize).unwrap();
194200
writeln!(&mut output).unwrap();
195201
}
196202
if result.expected_missing_nl {
@@ -201,7 +207,7 @@ pub fn diff(expected: &[u8], actual: &[u8], stop_early: bool, expand_tabs: bool)
201207
}
202208
for actual in &result.actual {
203209
write!(&mut output, "> ").unwrap();
204-
do_write_line(&mut output, actual, expand_tabs).unwrap();
210+
do_write_line(&mut output, actual, expand_tabs, tabsize).unwrap();
205211
writeln!(&mut output).unwrap();
206212
}
207213
if result.actual_missing_nl {
@@ -222,7 +228,7 @@ mod tests {
222228
a.write_all(b"a\n").unwrap();
223229
let mut b = Vec::new();
224230
b.write_all(b"b\n").unwrap();
225-
let diff = diff(&a, &b, false, false);
231+
let diff = diff(&a, &b, false, false, 8);
226232
let expected = b"1c1\n< a\n---\n> b\n".to_vec();
227233
assert_eq!(diff, expected);
228234
}
@@ -275,7 +281,7 @@ mod tests {
275281
}
276282
// This test diff is intentionally reversed.
277283
// We want it to turn the alef into bet.
278-
let diff = diff(&alef, &bet, false, false);
284+
let diff = diff(&alef, &bet, false, false, 8);
279285
File::create(&format!("{target}/ab.diff"))
280286
.unwrap()
281287
.write_all(&diff)
@@ -367,7 +373,7 @@ mod tests {
367373
}
368374
// This test diff is intentionally reversed.
369375
// We want it to turn the alef into bet.
370-
let diff = diff(&alef, &bet, false, false);
376+
let diff = diff(&alef, &bet, false, false, 8);
371377
File::create(&format!("{target}/abn.diff"))
372378
.unwrap()
373379
.write_all(&diff)
@@ -441,7 +447,7 @@ mod tests {
441447
}
442448
// This test diff is intentionally reversed.
443449
// We want it to turn the alef into bet.
444-
let diff = diff(&alef, &bet, false, false);
450+
let diff = diff(&alef, &bet, false, false, 8);
445451
File::create(&format!("{target}/ab_.diff"))
446452
.unwrap()
447453
.write_all(&diff)
@@ -519,7 +525,7 @@ mod tests {
519525
}
520526
// This test diff is intentionally reversed.
521527
// We want it to turn the alef into bet.
522-
let diff = diff(&alef, &bet, false, false);
528+
let diff = diff(&alef, &bet, false, false, 8);
523529
File::create(&format!("{target}/abr.diff"))
524530
.unwrap()
525531
.write_all(&diff)
@@ -554,18 +560,18 @@ mod tests {
554560
let from = ["a", "b", "c"].join("\n");
555561
let to = ["a", "d", "c"].join("\n");
556562

557-
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false);
563+
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false, 8);
558564
let expected_full = ["2c2", "< b", "---", "> d", ""].join("\n");
559565
assert_eq!(diff_full, expected_full.as_bytes());
560566

561-
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false);
567+
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false, 8);
562568
let expected_brief = "\0".as_bytes();
563569
assert_eq!(diff_brief, expected_brief);
564570

565-
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false);
571+
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false, 8);
566572
assert!(nodiff_full.is_empty());
567573

568-
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false);
574+
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false, 8);
569575
assert!(nodiff_brief.is_empty());
570576
}
571577
}

0 commit comments

Comments
 (0)