From 7b6658cc427085b85857fbcd7022a9660c53dc81 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Wed, 1 Apr 2026 00:26:08 -0700 Subject: [PATCH] Fix preview panel UTF-8 panics and preserve whitespace in redactions Snap byte offsets to character boundaries in the preview layout to prevent slicing inside multi-byte characters. Preserve all whitespace (not just newlines) in redacted regions. Force dark theme explicitly. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/main.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 81c6d56..1b30d5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,6 +55,7 @@ fn configure_fonts(ctx: &egui::Context) { } fn apply_nord_theme(ctx: &egui::Context) { + ctx.set_theme(egui::Theme::Dark); let mut style = (*ctx.style()).clone(); let v = &mut style.visuals; @@ -403,8 +404,8 @@ impl eframe::App for RedactorApp { &self_redactions, r.end, ); - let os = out_start.min(text.len()); - let oe = out_end.min(text.len()); + let os = snap_to_char_boundary(text, out_start.min(text.len())); + let oe = snap_to_char_boundary(text, out_end.min(text.len())); if pos < os { job.append(&text[pos..os], 0.0, normal.clone()); @@ -437,6 +438,13 @@ impl eframe::App for RedactorApp { } } +fn snap_to_char_boundary(s: &str, mut i: usize) -> usize { + while i > 0 && !s.is_char_boundary(i) { + i -= 1; + } + i +} + #[allow(unused_assignments)] fn byte_to_preview_byte_static( source: &str, @@ -471,7 +479,7 @@ fn byte_to_preview_byte_static( } for ch in source[r_start..r_end].chars() { - if ch == '\n' || ch == '\r' { + if ch.is_whitespace() { preview_pos += ch.len_utf8(); } else { preview_pos += '\u{2588}'.len_utf8();