From f929881ee454b1baa4a75b276c0bc2330638a7e7 Mon Sep 17 00:00:00 2001 From: Thomas Otto Date: Wed, 10 Jul 2024 08:48:31 +0200 Subject: [PATCH] Add --max-syntax-highlighting-length (WIP) --- src/cli.rs | 18 ++++++++++++---- src/config.rs | 2 ++ src/options/set.rs | 1 + src/paint.rs | 32 ++++++++++++++++++++++----- src/tests/test_example_diffs.rs | 38 +++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index a18f11e46..9afadd055 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -734,14 +734,24 @@ pub struct Opt { /// insertion operations transforming one into the other. pub max_line_distance: f64, - #[arg(long = "max-line-length", default_value = "512", value_name = "N")] + #[arg(long = "max-line-length", default_value = "3000", value_name = "N")] /// Truncate lines longer than this. /// - /// To prevent any truncation, set to zero. Note that delta will be slow on very long lines - /// (e.g. minified .js) if truncation is disabled. When wrapping lines it is automatically set - /// to fit at least all visible characters. + /// To prevent any truncation, set to zero. When wrapping lines it is automatically overwritten + /// to fit at least all visible characters, see `--wrap-max-lines`. pub max_line_length: usize, + #[arg( + long = "max-syntax-highlighting-length", + default_value = "400", + value_name = "N" + )] + /// Stop syntax highlighting lines after this length. + /// + /// To highlighting the entire line, set to zero - but note that delta will be slow on very long + /// lines (e.g. minified .js). + pub max_syntax_length: usize, + #[arg( long = "merge-conflict-begin-symbol", default_value = "▼", diff --git a/src/config.rs b/src/config.rs index 351d57d4c..c2fbccb73 100644 --- a/src/config.rs +++ b/src/config.rs @@ -101,6 +101,7 @@ pub struct Config { pub max_line_distance_for_naively_paired_lines: f64, pub max_line_distance: f64, pub max_line_length: usize, + pub max_syntax_length: usize, pub merge_conflict_begin_symbol: String, pub merge_conflict_ours_diff_header_style: Style, pub merge_conflict_theirs_diff_header_style: Style, @@ -392,6 +393,7 @@ impl From for Config { } else { opt.max_line_length }, + max_syntax_length: opt.max_syntax_length, merge_conflict_begin_symbol: opt.merge_conflict_begin_symbol, merge_conflict_ours_diff_header_style: styles["merge-conflict-ours-diff-header-style"], merge_conflict_theirs_diff_header_style: styles diff --git a/src/options/set.rs b/src/options/set.rs index 8677d158f..2fae345bf 100644 --- a/src/options/set.rs +++ b/src/options/set.rs @@ -174,6 +174,7 @@ pub fn set_options( map_styles, max_line_distance, max_line_length, + max_syntax_length, // Hack: minus-style must come before minus-*emph-style because the latter default // dynamically to the value of the former. merge_conflict_begin_symbol, diff --git a/src/paint.rs b/src/paint.rs index 4b487ea38..9442e8b1e 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -696,11 +696,33 @@ pub fn get_syntax_style_sections_for_lines<'a>( ) { (Some(highlighter), true) => { for (line, _) in lines.iter() { - line_sections.push( - highlighter - .highlight_line(line, &config.syntax_set) - .unwrap(), - ); + if line.len() < config.max_syntax_length || config.max_syntax_length == 0 { + line_sections.push( + highlighter + .highlight_line(line, &config.syntax_set) + .unwrap(), + ); + } else { + // Detailed ansi vs ascii length does not matter here, but this means the + // result is not cut at exactly the requested position. + let line_syntax = ansi::truncate_str(line, config.max_syntax_length, ""); + // re-split to get references into `line` with correct lifetimes. + // SAFETY: slicing the string is safe because `truncate_str` only + // cuts at grapheme borders, and nothing (`tail=""`) is added. + let (with_syntax, plain) = line.split_at(line_syntax.len()); + line_sections.push( + highlighter + .highlight_line(with_syntax, &config.syntax_set) + .unwrap(), + ); + + if !plain.is_empty() { + line_sections + .last_mut() + .unwrap() + .push((config.null_syntect_style, plain)); + } + } } } _ => { diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs index 9ee3ca5bb..1888ccac0 100644 --- a/src/tests/test_example_diffs.rs +++ b/src/tests/test_example_diffs.rs @@ -1994,6 +1994,44 @@ src/align.rs:71: impl<'a> Alignment<'a> { │ .expect_after_header("#partial\n\nremoved: a"); } + #[test] + fn test_lines_with_syntax_width_limit() { + let result = DeltaTest::with_args(&[ + "--max-line-length=42", + "--max-syntax-highlighting-length=18", + ]) + .explain_ansi() + .with_input(GIT_DIFF_SINGLE_HUNK); + assert_snapshot!(result.output, @r###" + (normal)commit 94907c0f136f46dc46ffae2dc92dca9af7(reverse normal)→(normal) + Author: Dan Davison (149)Alignmen(normal)t<'a> { (blue)│(normal) + (blue)─────────────────────────────(blue)┘(normal) + + (231) (203)for(231) (i, x_(normal)i) in self.x.iter().en→ + (231) (203)for(231) (j(normal), y_j) in self.y.iter(→ + (normal 52) let (left, diag, up) =(normal 124) ((normal) + (normal 52) self.index(i, j + 1(normal 124)),(normal) + (normal 52) self.index(i, j),(normal) + (normal 52) self.index(i + 1, j),(normal) + (normal 52) );(normal) + (231 22) le(normal 22)t (left, diag, up) =(normal) + (231 22) (normal 22) (normal 28)((normal 22)self.index(i, j + 1(normal 28)→(normal) + (231) le(normal)t candidates = [ + (231) (normal) Cell { + (231) (normal) parent: left, + "###); + } + const GIT_DIFF_SINGLE_HUNK: &str = "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e Author: Dan Davison