diff --git a/scm-record/src/ui.rs b/scm-record/src/ui.rs index 675f412..412e260 100644 --- a/scm-record/src/ui.rs +++ b/scm-record/src/ui.rs @@ -3100,6 +3100,42 @@ fn replace_control_character(character: char) -> Option<&'static str> { '\t' => Some("→ "), '\n' => Some("⏎"), '\r' => Some("␍"), + + '\x00' => Some("␀"), + '\x01' => Some("␁"), + '\x02' => Some("␂"), + '\x03' => Some("␃"), + '\x04' => Some("␄"), + '\x05' => Some("␅"), + '\x06' => Some("␆"), + '\x07' => Some("␇"), + '\x08' => Some("␈"), + // '\x09' ('\t') handled above + // '\x0A' ('\n') handled above + '\x0B' => Some("␋"), + '\x0C' => Some("␌"), + // '\x0D' ('\r') handled above + '\x0E' => Some("␎"), + '\x0F' => Some("␏"), + '\x10' => Some("␐"), + '\x11' => Some("␑"), + '\x12' => Some("␒"), + '\x13' => Some("␓"), + '\x14' => Some("␔"), + '\x15' => Some("␕"), + '\x16' => Some("␖"), + '\x17' => Some("␗"), + '\x18' => Some("␘"), + '\x19' => Some("␙"), + '\x1A' => Some("␚"), + '\x1B' => Some("␛"), + '\x1C' => Some("␜"), + '\x1D' => Some("␝"), + '\x1E' => Some("␞"), + '\x1F' => Some("␟"), + + '\x7F' => Some("␡"), + _ => None, } } diff --git a/scm-record/tests/test_scm_record.rs b/scm-record/tests/test_scm_record.rs index 498e427..bf64f80 100644 --- a/scm-record/tests/test_scm_record.rs +++ b/scm-record/tests/test_scm_record.rs @@ -3404,3 +3404,45 @@ fn test_carriage_return() -> TestResult { Ok(()) } + +#[test] +fn test_some_control_characters() -> TestResult { + let state = RecordState { + is_read_only: false, + commits: Default::default(), + files: vec![File { + old_path: None, + path: Cow::Borrowed(Path::new("foo")), + file_mode: None, + sections: vec![Section::Changed { + lines: vec![SectionChangedLine { + is_checked: false, + change_type: ChangeType::Added, + line: Cow::Borrowed("nul:\0, bel:\x07, esc:\x1b, del:\x7f\n"), + }], + }], + }], + }; + + let initial = TestingScreenshot::default(); + let mut input = TestingInput::new( + 80, + 8, + [Event::ExpandAll, initial.event(), Event::QuitAccept], + ); + let recorder = Recorder::new(state, &mut input); + recorder.run()?; + + insta::assert_snapshot!(initial, @r###" + "[File] [Edit] [Select] [View] " + "( ) foo (-)" + " [ ] Section 1/1 [-]" + " [ ] + nul:␀, bel:␇, esc:␛, del:␡⏎ " + " " + " " + " " + " " + "###); + + Ok(()) +}