Add description for each settings item in /settings (#15936)

This commit is contained in:
Sehoon Shon
2026-01-06 14:06:15 -05:00
committed by GitHub
parent 6f4b2ad0b9
commit 9172e28315
3 changed files with 243 additions and 107 deletions
@@ -308,6 +308,23 @@ describe('SettingsDialog', () => {
});
});
describe('Setting Descriptions', () => {
it('should render descriptions for settings that have them', () => {
const settings = createMockSettings();
const onSelect = vi.fn();
const { lastFrame } = renderDialog(settings, onSelect);
const output = lastFrame();
// 'general.vimMode' has description 'Enable Vim keybindings' in settingsSchema.ts
expect(output).toContain('Vim Mode');
expect(output).toContain('Enable Vim keybindings');
// 'general.disableAutoUpdate' has description 'Disable automatic updates'
expect(output).toContain('Disable Auto Update');
expect(output).toContain('Disable automatic updates');
});
});
describe('Settings Navigation', () => {
it.each([
{
@@ -37,7 +37,12 @@ import {
import { useVimMode } from '../contexts/VimModeContext.js';
import { useKeypress } from '../hooks/useKeypress.js';
import chalk from 'chalk';
import { cpSlice, cpLen, stripUnsafeCharacters } from '../utils/textUtils.js';
import {
cpSlice,
cpLen,
stripUnsafeCharacters,
getCachedStringWidth,
} from '../utils/textUtils.js';
import {
type SettingsValue,
TOGGLE_TYPES,
@@ -65,7 +70,7 @@ interface SettingsDialogProps {
config?: Config;
}
const maxItemsToShow = 8;
const MAX_ITEMS_TO_SHOW = 8;
export function SettingsDialog({
settings,
@@ -194,6 +199,31 @@ export function SettingsDialog({
setShowRestartPrompt(newRestartRequired.size > 0);
}, [selectedScope, settings, globalPendingChanges]);
// Calculate max width for the left column (Label/Description) to keep values aligned or close
const maxLabelOrDescriptionWidth = useMemo(() => {
const allKeys = getDialogSettingKeys();
let max = 0;
for (const key of allKeys) {
const def = getSettingDefinition(key);
if (!def) continue;
const scopeMessage = getScopeMessageForSetting(
key,
selectedScope,
settings,
);
const label = def.label || key;
const labelFull = label + (scopeMessage ? ` ${scopeMessage}` : '');
const lWidth = getCachedStringWidth(labelFull);
const dWidth = def.description
? getCachedStringWidth(def.description)
: 0;
max = Math.max(max, lWidth, dWidth);
}
return max;
}, [selectedScope, settings]);
const generateSettingsItems = () => {
const settingKeys = searchQuery ? filteredKeys : getDialogSettingKeys();
@@ -202,6 +232,7 @@ export function SettingsDialog({
return {
label: definition?.label || key,
description: definition?.description,
value: key,
type: definition?.type,
toggle: () => {
@@ -478,8 +509,8 @@ export function SettingsDialog({
currentAvailableTerminalHeight - totalFixedHeight,
);
// Each setting item takes 2 lines (the setting row + spacing)
let maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 2));
// Each setting item takes up to 3 lines (label/value row, description row, and spacing)
let maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3));
// Decide whether to show scope selection based on remaining space
let showScopeSelection = true;
@@ -492,7 +523,7 @@ export function SettingsDialog({
1,
currentAvailableTerminalHeight - totalWithScope,
);
const maxItemsWithScope = Math.max(1, Math.floor(availableWithScope / 2));
const maxItemsWithScope = Math.max(1, Math.floor(availableWithScope / 3));
// If hiding scope selection allows us to show significantly more settings, do it
if (maxVisibleItems > maxItemsWithScope + 1) {
@@ -504,7 +535,7 @@ export function SettingsDialog({
1,
currentAvailableTerminalHeight - totalFixedHeight,
);
maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 2));
maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3));
}
} else {
// For normal height, include scope selection
@@ -513,13 +544,13 @@ export function SettingsDialog({
1,
currentAvailableTerminalHeight - totalFixedHeight,
);
maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 2));
maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3));
}
// Use the calculated maxVisibleItems or fall back to the original maxItemsToShow
const effectiveMaxItemsToShow = availableTerminalHeight
? Math.min(maxVisibleItems, items.length)
: maxItemsToShow;
: MAX_ITEMS_TO_SHOW;
// Ensure focus stays on settings when scope selection is hidden
React.useEffect(() => {
@@ -979,7 +1010,7 @@ export function SettingsDialog({
return (
<React.Fragment key={item.value}>
<Box marginX={1} flexDirection="row" alignItems="center">
<Box marginX={1} flexDirection="row" alignItems="flex-start">
<Box minWidth={2} flexShrink={0}>
<Text
color={
@@ -989,7 +1020,17 @@ export function SettingsDialog({
{isActive ? '●' : ''}
</Text>
</Box>
<Box minWidth={50}>
<Box
flexDirection="row"
flexGrow={1}
minWidth={0}
alignItems="flex-start"
>
<Box
flexDirection="column"
width={maxLabelOrDescriptionWidth}
minWidth={0}
>
<Text
color={
isActive ? theme.status.success : theme.text.primary
@@ -1003,8 +1044,12 @@ export function SettingsDialog({
</Text>
)}
</Text>
<Text color={theme.text.secondary} wrap="truncate">
{item.description ?? ''}
</Text>
</Box>
<Box minWidth={3} />
<Box flexShrink={0}>
<Text
color={
isActive
@@ -1017,6 +1062,8 @@ export function SettingsDialog({
{displayValue}
</Text>
</Box>
</Box>
</Box>
<Box height={1} />
</React.Fragment>
);
@@ -11,20 +11,28 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -49,20 +57,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode true* │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -87,20 +103,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false* │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false* │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false* │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false* │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false* │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -125,20 +149,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -163,20 +195,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -201,20 +241,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec
│ │
│ ▲ │
│ Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -239,20 +287,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false* │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update true* │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false* │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -277,20 +333,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title false │
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -315,20 +379,28 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false │
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode true* │
│ Enable Vim keybindings │
│ │
│ Disable Auto Update true* │
│ Disable automatic updates │
│ │
│ Enable Prompt Completion true* │
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging true* │
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false │
│ Enable automatic session cleanup │
│ │
│ Output Format Text │
│ The format of the CLI output. │
│ │
│ Hide Window Title true* │
│ Hide the window title bar │
│ │
│ ▼ │
│ │