What version of Codex CLI is running?
0.125.0, or latest main HEAD
What subscription do you have?
ChatGPT Plus
Which model were you using?
Unrelated
What platform is your computer?
Linux 6.19.11-arch1-1 x86_64 unknown
What terminal emulator and version are you using (if applicable)?
Windows Terminal
What issue are you seeing?
The TUI slash command popup recalculates the command-name column width from only the currently visible rows. As a result, the description column shifts left or right while scrolling through the / command list, depending on the longest command name visible in the current viewport.
What steps can reproduce the bug?
- Open the TUI.
- Type
/ to show the slash command popup.
- Scroll through the list.
One viewport may render with a narrower name column:
/copy copy last response as markdown
/diff show git diff (including untracked files)
/mention mention a file
/status show current session configuration and token usage
/title configure which items appear in the terminal title
/statusline configure which items appear in the status line
/theme choose a syntax highlighting theme
/mcp list configured MCP tools; use /mcp verbose for details
After scrolling, the same popup may render with a wider name column:
/permissions choose what Codex is allowed to do
/experimental toggle experimental features
/memories configure memory use and generation
/skills use skills to improve how Codex performs specific tasks
/review review my current changes and find issues
/rename rename the current thread
/new start a new chat during a conversation
/resume resume a saved chat
What is the expected behavior?
The description column should remain stable while scrolling. For a given filtered slash command list, the popup should reserve the width needed by the longest matching command name, not just the longest command visible in the current viewport.
Additional information
I understand external pull requests are by invitation only, so I am opening this as an issue first with analysis and a small proposed patch. If this approach aligns with the intended fix, I would appreciate an invitation to submit a PR.
CommandPopup currently uses the default selection popup row measurement and
rendering helpers:
measure_rows_height
render_rows
Those use the default ColumnWidthMode::AutoVisible, which derives the left column width from visible rows only. This is useful for compact generic lists, but it causes visible layout movement in the slash command popup.
The shared selection popup code already supports ColumnWidthMode::AutoAllRows, which derives the column width from all rows and is intended for stable columns while scrolling.
The following patch switches slash command popup measurement and rendering to AutoAllRows.
diff --git a/codex-rs/tui/src/bottom_pane/command_popup.rs b/codex-rs/tui/src/bottom_pane/command_popup.rs
index 28c749cb57..50aeed738d 100644
--- a/codex-rs/tui/src/bottom_pane/command_popup.rs
+++ b/codex-rs/tui/src/bottom_pane/command_popup.rs
@@ -4,8 +4,11 @@ use ratatui::widgets::WidgetRef;
use super::popup_consts::MAX_POPUP_ROWS;
use super::scroll_state::ScrollState;
+use super::selection_popup_common::ColumnWidthConfig;
+use super::selection_popup_common::ColumnWidthMode;
use super::selection_popup_common::GenericDisplayRow;
-use super::selection_popup_common::render_rows;
+use super::selection_popup_common::measure_rows_height_with_col_width_mode;
+use super::selection_popup_common::render_rows_with_col_width_mode;
use super::slash_commands;
use crate::render::Insets;
use crate::render::RectExt;
@@ -15,6 +18,10 @@ use crate::slash_command::SlashCommand;
// `quit` is an alias of `exit`, so we skip `quit` here.
// `approvals` is an alias of `permissions`.
const ALIAS_COMMANDS: &[SlashCommand] = &[SlashCommand::Quit, SlashCommand::Approvals];
+const COMMAND_COLUMN_WIDTH: ColumnWidthConfig = ColumnWidthConfig::new(
+ ColumnWidthMode::AutoAllRows,
+ /*name_column_width*/ None,
+);
/// A selectable item in the popup.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -107,10 +114,15 @@ impl CommandPopup {
/// Determine the preferred height of the popup for a given width.
/// Accounts for wrapped descriptions so that long tooltips don't overflow.
pub(crate) fn calculate_required_height(&self, width: u16) -> u16 {
- use super::selection_popup_common::measure_rows_height;
let rows = self.rows_from_matches(self.filtered());
- measure_rows_height(&rows, &self.state, MAX_POPUP_ROWS, width)
+ measure_rows_height_with_col_width_mode(
+ &rows,
+ &self.state,
+ MAX_POPUP_ROWS,
+ width,
+ COMMAND_COLUMN_WIDTH,
+ )
}
/// Compute exact/prefix matches over built-in commands and user prompts,
@@ -221,7 +233,7 @@ impl CommandPopup {
impl WidgetRef for CommandPopup {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
let rows = self.rows_from_matches(self.filtered());
- render_rows(
+ render_rows_with_col_width_mode(
area.inset(Insets::tlbr(
/*top*/ 0, /*left*/ 2, /*bottom*/ 0, /*right*/ 0,
)),
@@ -230,6 +242,7 @@ impl WidgetRef for CommandPopup {
&self.state,
MAX_POPUP_ROWS,
"no matches",
+ COMMAND_COLUMN_WIDTH,
);
}
}
I have tested locally and it is fixed by this patch.
What version of Codex CLI is running?
0.125.0, or latest main HEAD
What subscription do you have?
ChatGPT Plus
Which model were you using?
Unrelated
What platform is your computer?
Linux 6.19.11-arch1-1 x86_64 unknown
What terminal emulator and version are you using (if applicable)?
Windows Terminal
What issue are you seeing?
The TUI slash command popup recalculates the command-name column width from only the currently visible rows. As a result, the description column shifts left or right while scrolling through the
/command list, depending on the longest command name visible in the current viewport.What steps can reproduce the bug?
/to show the slash command popup.One viewport may render with a narrower name column:
After scrolling, the same popup may render with a wider name column:
What is the expected behavior?
The description column should remain stable while scrolling. For a given filtered slash command list, the popup should reserve the width needed by the longest matching command name, not just the longest command visible in the current viewport.
Additional information
I understand external pull requests are by invitation only, so I am opening this as an issue first with analysis and a small proposed patch. If this approach aligns with the intended fix, I would appreciate an invitation to submit a PR.
CommandPopupcurrently uses the default selection popup row measurement andrendering helpers:
measure_rows_heightrender_rowsThose use the default
ColumnWidthMode::AutoVisible, which derives the left column width from visible rows only. This is useful for compact generic lists, but it causes visible layout movement in the slash command popup.The shared selection popup code already supports
ColumnWidthMode::AutoAllRows, which derives the column width from all rows and is intended for stable columns while scrolling.The following patch switches slash command popup measurement and rendering to
AutoAllRows.I have tested locally and it is fixed by this patch.