diff --git a/codex-rs/tui/src/diff_render.rs b/codex-rs/tui/src/diff_render.rs index 350c3c7aa..9df58fb7e 100644 --- a/codex-rs/tui/src/diff_render.rs +++ b/codex-rs/tui/src/diff_render.rs @@ -1307,6 +1307,7 @@ fn style_gutter_dim() -> Style { #[cfg(test)] mod tests { use super::*; + use insta::assert_debug_snapshot; use insta::assert_snapshot; use pretty_assertions::assert_eq; use ratatui::Terminal; @@ -2200,6 +2201,58 @@ mod tests { ); } + #[test] + fn cpp_module_extensions_use_cpp_highlighting() { + let highlighted_tokens = ["cpp", "cppm", "CPPM", "cxxm", "CxXm", "ixx", "IXX"] + .into_iter() + .map(|extension| { + let mut changes: HashMap = HashMap::new(); + changes.insert( + PathBuf::from(format!("math.{extension}")), + FileChange::Add { + content: + "export module math;\nexport int sum(int a, int b) { return a + b; }\n" + .to_string(), + }, + ); + + let lines = + create_diff_summary(&changes, &PathBuf::from("/"), /*wrap_cols*/ 80); + let rgb_tokens = lines + .iter() + .flat_map(|line| &line.spans) + .filter(|span| matches!(span.style.fg, Some(ratatui::style::Color::Rgb(..)))) + .map(|span| span.content.to_string()) + .collect::>(); + assert!( + !rgb_tokens.is_empty(), + "add diff for .{extension} file should produce syntax-highlighted (RGB) spans" + ); + (extension, rgb_tokens.join("|")) + }) + .collect::>(); + + assert_debug_snapshot!("cpp_module_extension_highlighting", highlighted_tokens); + } + + #[test] + fn unknown_extension_falls_back_without_syntax_highlighting() { + let mut changes: HashMap = HashMap::new(); + changes.insert( + PathBuf::from("math.unknown-extension"), + FileChange::Add { + content: "export module math;\nexport int value = 42;\n".to_string(), + }, + ); + + let lines = create_diff_summary(&changes, &PathBuf::from("/"), /*wrap_cols*/ 80); + assert!(lines.iter().all(|line| { + line.spans + .iter() + .all(|span| !matches!(span.style.fg, Some(ratatui::style::Color::Rgb(..)))) + })); + } + #[test] fn delete_diff_uses_path_extension_for_highlighting() { let mut changes: HashMap = HashMap::new(); diff --git a/codex-rs/tui/src/render/highlight.rs b/codex-rs/tui/src/render/highlight.rs index cb83f06f4..ef4d7a2f3 100644 --- a/codex-rs/tui/src/render/highlight.rs +++ b/codex-rs/tui/src/render/highlight.rs @@ -526,8 +526,10 @@ fn find_syntax(lang: &str) -> Option<&'static SyntaxReference> { let ss = syntax_set(); // Aliases that two-face does not resolve on its own. - let patched = match lang { + let normalized = lang.to_ascii_lowercase(); + let patched = match normalized.as_str() { "csharp" | "c-sharp" => "c#", + "cppm" | "cxxm" | "ixx" => "cpp", "golang" => "go", "python3" => "python", "shell" => "bash", @@ -1203,7 +1205,10 @@ mod tests { ); } // Patched aliases that two-face cannot resolve on its own. - for alias in ["csharp", "c-sharp", "golang", "python3", "shell"] { + for alias in [ + "csharp", "c-sharp", "cppm", "CPPM", "cxxm", "CxXm", "ixx", "IXX", "golang", "python3", + "shell", + ] { assert!( find_syntax(alias).is_some(), "find_syntax({alias:?}) returned None — patched alias broken" diff --git a/codex-rs/tui/src/snapshots/codex_tui__diff_render__tests__cpp_module_extension_highlighting.snap b/codex-rs/tui/src/snapshots/codex_tui__diff_render__tests__cpp_module_extension_highlighting.snap new file mode 100644 index 000000000..be5ab4fe1 --- /dev/null +++ b/codex-rs/tui/src/snapshots/codex_tui__diff_render__tests__cpp_module_extension_highlighting.snap @@ -0,0 +1,34 @@ +--- +source: tui/src/diff_render.rs +expression: highlighted_tokens +--- +[ + ( + "cpp", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), + ( + "cppm", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), + ( + "CPPM", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), + ( + "cxxm", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), + ( + "CxXm", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), + ( + "ixx", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), + ( + "IXX", + "export| module math|;|export| |int| |sum|(|int| |a|,| |int| |b|)| |{| |return| a |+| b|;| |}", + ), +]