mirror of
https://github.com/openai/codex.git
synced 2026-10-31 19:28:49 +00:00
## Why VTE versions before 0.54 lack the parser that safely ignores unknown OSC sequences. Terminal status reporting needs to account for the VTE backend even when the terminal identifies itself as GNOME Terminal or another application. ## What changed - Track VTE backend versions independently of terminal application identity. - Disable `OSC 7501` and `OSC 21337` status reporting when the detected VTE version is below 0.54. Preserve existing behavior for newer or unknown versions. - Prefer `VTE_VERSION` over the terminal application version, treating empty or malformed values as unknown. ## Testing Add regression tests for GNOME identity with VTE metadata, version precedence, and status protocol selection around the VTE 0.54 boundary, including unknown versions. GitOrigin-RevId: 1aa57901d1b1457f9971c07cb51ec4554915ae3b
186 lines
6.2 KiB
Rust
186 lines
6.2 KiB
Rust
//! Terminal-specific row caps for resize reflow.
|
|
//!
|
|
//! The auto cap mirrors documented scrollback defaults for terminals we can identify. Console Host
|
|
//! does not expose its configured screen buffer through terminal metadata, so it usually lands in
|
|
//! the fallback bucket.
|
|
//!
|
|
//! These caps are deliberately conservative: Codex is rebuilding normal terminal scrollback, not an
|
|
//! internal virtual transcript. Replaying more rows than the terminal retains wastes work and can
|
|
//! make interactive resize feel worse without giving the user more usable history.
|
|
|
|
use codex_config::types::DEFAULT_TERMINAL_RESIZE_REFLOW_FALLBACK_MAX_ROWS;
|
|
use codex_terminal_detection::TerminalInfo;
|
|
use codex_terminal_detection::TerminalName;
|
|
use codex_terminal_detection::terminal_info;
|
|
|
|
use crate::legacy_core::config::TerminalResizeReflowConfig;
|
|
use crate::legacy_core::config::TerminalResizeReflowMaxRows;
|
|
|
|
const VSCODE_RESIZE_REFLOW_MAX_ROWS: usize = 1_000;
|
|
const WINDOWS_TERMINAL_RESIZE_REFLOW_MAX_ROWS: usize = 9_001;
|
|
const WEZTERM_RESIZE_REFLOW_MAX_ROWS: usize = 3_500;
|
|
const ALACRITTY_RESIZE_REFLOW_MAX_ROWS: usize = 10_000;
|
|
|
|
/// Resolve the configured row cap for resize and initial replay.
|
|
///
|
|
/// `Auto` uses terminal detection plus the VS Code environment probe because VS Code can run shells
|
|
/// whose terminal-name metadata points at the host shell rather than VS Code itself. Returning
|
|
/// `None` means the user explicitly disabled row limiting with `max_rows = 0`.
|
|
pub(crate) fn resize_reflow_max_rows(config: TerminalResizeReflowConfig) -> Option<usize> {
|
|
resize_reflow_max_rows_for(
|
|
config,
|
|
&terminal_info(),
|
|
crate::tui::running_in_vscode_terminal(),
|
|
)
|
|
}
|
|
|
|
fn resize_reflow_max_rows_for(
|
|
config: TerminalResizeReflowConfig,
|
|
terminal: &TerminalInfo,
|
|
running_in_vscode_terminal: bool,
|
|
) -> Option<usize> {
|
|
match config.max_rows {
|
|
TerminalResizeReflowMaxRows::Auto => Some(auto_resize_reflow_max_rows(
|
|
terminal.name,
|
|
running_in_vscode_terminal,
|
|
)),
|
|
TerminalResizeReflowMaxRows::Disabled => None,
|
|
TerminalResizeReflowMaxRows::Limit(max_rows) => Some(max_rows),
|
|
}
|
|
}
|
|
|
|
fn auto_resize_reflow_max_rows(
|
|
terminal_name: TerminalName,
|
|
running_in_vscode_terminal: bool,
|
|
) -> usize {
|
|
if running_in_vscode_terminal {
|
|
return VSCODE_RESIZE_REFLOW_MAX_ROWS;
|
|
}
|
|
|
|
match terminal_name {
|
|
TerminalName::VsCode => VSCODE_RESIZE_REFLOW_MAX_ROWS,
|
|
TerminalName::WindowsTerminal => WINDOWS_TERMINAL_RESIZE_REFLOW_MAX_ROWS,
|
|
TerminalName::WezTerm => WEZTERM_RESIZE_REFLOW_MAX_ROWS,
|
|
TerminalName::Alacritty => ALACRITTY_RESIZE_REFLOW_MAX_ROWS,
|
|
TerminalName::AppleTerminal
|
|
| TerminalName::Ghostty
|
|
| TerminalName::Iterm2
|
|
| TerminalName::WarpTerminal
|
|
| TerminalName::Kitty
|
|
| TerminalName::Konsole
|
|
| TerminalName::GnomeTerminal
|
|
| TerminalName::Vte
|
|
| TerminalName::Dumb
|
|
| TerminalName::Unknown => DEFAULT_TERMINAL_RESIZE_REFLOW_FALLBACK_MAX_ROWS,
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use codex_terminal_detection::Multiplexer;
|
|
|
|
fn test_terminal(name: TerminalName) -> TerminalInfo {
|
|
TerminalInfo {
|
|
backend: None,
|
|
name,
|
|
term_program: None,
|
|
version: None,
|
|
term: None,
|
|
multiplexer: None,
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn auto_resize_reflow_max_rows_uses_terminal_defaults() {
|
|
let cases = [
|
|
(TerminalName::VsCode, VSCODE_RESIZE_REFLOW_MAX_ROWS),
|
|
(
|
|
TerminalName::WindowsTerminal,
|
|
WINDOWS_TERMINAL_RESIZE_REFLOW_MAX_ROWS,
|
|
),
|
|
(TerminalName::WezTerm, WEZTERM_RESIZE_REFLOW_MAX_ROWS),
|
|
(TerminalName::Alacritty, ALACRITTY_RESIZE_REFLOW_MAX_ROWS),
|
|
(
|
|
TerminalName::Ghostty,
|
|
DEFAULT_TERMINAL_RESIZE_REFLOW_FALLBACK_MAX_ROWS,
|
|
),
|
|
(
|
|
TerminalName::Unknown,
|
|
DEFAULT_TERMINAL_RESIZE_REFLOW_FALLBACK_MAX_ROWS,
|
|
),
|
|
];
|
|
|
|
for (terminal_name, expected_max_rows) in cases {
|
|
assert_eq!(
|
|
auto_resize_reflow_max_rows(
|
|
terminal_name,
|
|
/*running_in_vscode_terminal*/ false
|
|
),
|
|
expected_max_rows
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn auto_resize_reflow_max_rows_prefers_vscode_probe() {
|
|
assert_eq!(
|
|
auto_resize_reflow_max_rows(
|
|
TerminalName::WindowsTerminal,
|
|
/*running_in_vscode_terminal*/ true
|
|
),
|
|
VSCODE_RESIZE_REFLOW_MAX_ROWS
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn configured_resize_reflow_max_rows_overrides_auto_detection() {
|
|
let terminal = test_terminal(TerminalName::VsCode);
|
|
let config = TerminalResizeReflowConfig {
|
|
max_rows: TerminalResizeReflowMaxRows::Limit(42),
|
|
};
|
|
|
|
assert_eq!(
|
|
resize_reflow_max_rows_for(
|
|
config, &terminal, /*running_in_vscode_terminal*/ false
|
|
),
|
|
Some(42)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn disabled_resize_reflow_max_rows_keeps_all_rows() {
|
|
let terminal = test_terminal(TerminalName::VsCode);
|
|
let config = TerminalResizeReflowConfig {
|
|
max_rows: TerminalResizeReflowMaxRows::Disabled,
|
|
};
|
|
|
|
assert_eq!(
|
|
resize_reflow_max_rows_for(
|
|
config, &terminal, /*running_in_vscode_terminal*/ false
|
|
),
|
|
None
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn unknown_terminal_uses_fallback_even_under_multiplexer() {
|
|
let terminal = TerminalInfo {
|
|
backend: None,
|
|
name: TerminalName::Unknown,
|
|
term_program: None,
|
|
version: None,
|
|
term: Some("xterm-256color".to_string()),
|
|
multiplexer: Some(Multiplexer::Tmux { version: None }),
|
|
};
|
|
let config = TerminalResizeReflowConfig::default();
|
|
|
|
assert_eq!(
|
|
resize_reflow_max_rows_for(
|
|
config, &terminal, /*running_in_vscode_terminal*/ false
|
|
),
|
|
Some(DEFAULT_TERMINAL_RESIZE_REFLOW_FALLBACK_MAX_ROWS)
|
|
);
|
|
}
|
|
}
|