diff --git a/codex-rs/cli/src/doctor.rs b/codex-rs/cli/src/doctor.rs index 18149ce607..5559daf2ec 100644 --- a/codex-rs/cli/src/doctor.rs +++ b/codex-rs/cli/src/doctor.rs @@ -1892,6 +1892,7 @@ fn terminal_name(info: &TerminalInfo) -> &'static str { match info.name { TerminalName::AppleTerminal => "Apple Terminal", TerminalName::Ghostty => "Ghostty", + TerminalName::Rex => "Rex", TerminalName::Iterm2 => "iTerm2", TerminalName::WarpTerminal => "Warp", TerminalName::VsCode => "VS Code", diff --git a/codex-rs/terminal-detection/src/lib.rs b/codex-rs/terminal-detection/src/lib.rs index 26b51fa5b5..5451df294e 100644 --- a/codex-rs/terminal-detection/src/lib.rs +++ b/codex-rs/terminal-detection/src/lib.rs @@ -40,6 +40,8 @@ pub enum TerminalName { AppleTerminal, /// Ghostty terminal emulator. Ghostty, + /// Rex terminal emulator. + Rex, /// iTerm2 terminal emulator. Iterm2, /// Warp terminal emulator. @@ -138,6 +140,7 @@ impl TerminalInfo { let name = match term.as_str() { "dumb" => TerminalName::Dumb, "xterm-ghostty" => TerminalName::Ghostty, + "xterm-rex" => TerminalName::Rex, "wezterm" | "wezterm-mux" => TerminalName::WezTerm, _ => TerminalName::Unknown, }; @@ -176,6 +179,7 @@ impl TerminalInfo { format_terminal_version("Apple_Terminal", &self.version) } TerminalName::Ghostty => format_terminal_version("Ghostty", &self.version), + TerminalName::Rex => format_terminal_version("rex", &self.version), TerminalName::Iterm2 => format_terminal_version("iTerm.app", &self.version), TerminalName::WarpTerminal => { format_terminal_version("WarpTerminal", &self.version) @@ -416,6 +420,7 @@ fn terminal_name_from_term_program(value: &str) -> Option { match normalized.as_str() { "appleterminal" => Some(TerminalName::AppleTerminal), "ghostty" => Some(TerminalName::Ghostty), + "rex" => Some(TerminalName::Rex), "iterm" | "iterm2" | "itermapp" => Some(TerminalName::Iterm2), "warp" | "warpterminal" => Some(TerminalName::WarpTerminal), "vscode" => Some(TerminalName::VsCode), diff --git a/codex-rs/terminal-detection/src/terminal_tests.rs b/codex-rs/terminal-detection/src/terminal_tests.rs index d6b8e12635..c600d98aaa 100644 --- a/codex-rs/terminal-detection/src/terminal_tests.rs +++ b/codex-rs/terminal-detection/src/terminal_tests.rs @@ -218,6 +218,14 @@ fn detects_ghostty() { ); } +#[test] +fn detects_rex() { + for (key, value) in [("TERM_PROGRAM", "rex"), ("TERM", "xterm-rex")] { + let env = FakeEnvironment::new().with_var(key, value); + assert_eq!(detect_terminal_info_from_env(&env).name, TerminalName::Rex); + } +} + #[test] fn detects_vscode() { let env = FakeEnvironment::new() diff --git a/codex-rs/tui/src/local_settings.rs b/codex-rs/tui/src/local_settings.rs index 1d0d7eb84b..5adf8671b8 100644 --- a/codex-rs/tui/src/local_settings.rs +++ b/codex-rs/tui/src/local_settings.rs @@ -251,6 +251,7 @@ impl LocalSettings { | TerminalName::Iterm2 | TerminalName::WarpTerminal | TerminalName::WezTerm + | TerminalName::Rex | TerminalName::Alacritty | TerminalName::Konsole | TerminalName::GnomeTerminal diff --git a/codex-rs/tui/src/markdown_render/web_links.rs b/codex-rs/tui/src/markdown_render/web_links.rs index 773ff4ca51..6418e6bc0d 100644 --- a/codex-rs/tui/src/markdown_render/web_links.rs +++ b/codex-rs/tui/src/markdown_render/web_links.rs @@ -69,17 +69,11 @@ impl WebLinkDisplay { { return Self::WithDestination; } - if terminal - .term_program - .as_deref() - .is_some_and(|program| program.eq_ignore_ascii_case("rex")) - { - return Self::LabelOnly; - } match terminal.name { TerminalName::Ghostty | TerminalName::Iterm2 | TerminalName::WezTerm + | TerminalName::Rex | TerminalName::Kitty | TerminalName::VsCode | TerminalName::Alacritty diff --git a/codex-rs/tui/src/markdown_render/web_links_tests.rs b/codex-rs/tui/src/markdown_render/web_links_tests.rs index 3d5ea55cf6..f4c0ae8f5e 100644 --- a/codex-rs/tui/src/markdown_render/web_links_tests.rs +++ b/codex-rs/tui/src/markdown_render/web_links_tests.rs @@ -91,6 +91,7 @@ fn supporting_terminals_render_only_the_styled_label_and_keep_its_target() { TerminalName::Ghostty, TerminalName::Iterm2, TerminalName::WezTerm, + TerminalName::Rex, TerminalName::Kitty, TerminalName::VsCode, TerminalName::Alacritty, @@ -143,21 +144,6 @@ fn supporting_terminals_render_only_the_styled_label_and_keep_its_target() { } } -#[test] -fn rex_renders_only_the_label() { - let mut rex = terminal(TerminalName::Unknown); - rex.term_program = Some("rex".to_string()); - let markdown = "[label](https://example.com)"; - assert_eq!( - render( - markdown, - /*width*/ 80, - WebLinkDisplay::for_terminal(&rex, /*term*/ None), - ), - render(markdown, /*width*/ 80, WebLinkDisplay::LabelOnly), - ); -} - #[test] fn unknown_terminals_and_multiplexers_keep_visible_destinations() { let mut tmux = terminal(TerminalName::Ghostty); diff --git a/codex-rs/tui/src/pets/image_protocol.rs b/codex-rs/tui/src/pets/image_protocol.rs index 9cbcb96a5e..a17b913719 100644 --- a/codex-rs/tui/src/pets/image_protocol.rs +++ b/codex-rs/tui/src/pets/image_protocol.rs @@ -178,7 +178,7 @@ fn is_iterm2_terminal(info: &TerminalInfo) -> bool { fn supports_kitty_graphics(info: &TerminalInfo) -> bool { matches!( info.name, - TerminalName::Ghostty | TerminalName::Kitty | TerminalName::WezTerm + TerminalName::Ghostty | TerminalName::Kitty | TerminalName::Rex | TerminalName::WezTerm ) || terminal_field_contains(info.term.as_deref(), "kitty") || terminal_field_contains(info.term.as_deref(), "ghostty") || terminal_field_contains(info.term.as_deref(), "wezterm") @@ -516,6 +516,12 @@ mod tests { Some("kitty"), /*term*/ None, ), + terminal_info_for_test( + TerminalName::Rex, + /*multiplexer*/ None, + Some("rex"), + /*term*/ None, + ), terminal_info_for_test( TerminalName::WezTerm, /*multiplexer*/ None, diff --git a/codex-rs/tui/src/resize_reflow_cap.rs b/codex-rs/tui/src/resize_reflow_cap.rs index e690a77eb4..7f8e1f6d44 100644 --- a/codex-rs/tui/src/resize_reflow_cap.rs +++ b/codex-rs/tui/src/resize_reflow_cap.rs @@ -64,6 +64,7 @@ fn auto_resize_reflow_max_rows( TerminalName::Alacritty => ALACRITTY_RESIZE_REFLOW_MAX_ROWS, TerminalName::AppleTerminal | TerminalName::Ghostty + | TerminalName::Rex | TerminalName::Iterm2 | TerminalName::WarpTerminal | TerminalName::Kitty diff --git a/codex-rs/tui/src/startup_orchestration.rs b/codex-rs/tui/src/startup_orchestration.rs index fded18b135..43331cdae9 100644 --- a/codex-rs/tui/src/startup_orchestration.rs +++ b/codex-rs/tui/src/startup_orchestration.rs @@ -775,6 +775,7 @@ pub(super) async fn run_main_inner( let terminal_name = match terminal_info.name { TerminalName::AppleTerminal => "apple_terminal", TerminalName::Ghostty => "ghostty", + TerminalName::Rex => "rex", TerminalName::Iterm2 => "iterm2", TerminalName::WarpTerminal => "warp", TerminalName::VsCode => "vscode",