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

View File

@@ -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([
{

View File

@@ -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,33 +1020,49 @@ export function SettingsDialog({
{isActive ? '●' : ''}
</Text>
</Box>
<Box minWidth={50}>
<Text
color={
isActive ? theme.status.success : theme.text.primary
}
>
{item.label}
{scopeMessage && (
<Text color={theme.text.secondary}>
{' '}
{scopeMessage}
</Text>
)}
</Text>
</Box>
<Box minWidth={3} />
<Text
color={
isActive
? theme.status.success
: shouldBeGreyedOut
? theme.text.secondary
: theme.text.primary
}
<Box
flexDirection="row"
flexGrow={1}
minWidth={0}
alignItems="flex-start"
>
{displayValue}
</Text>
<Box
flexDirection="column"
width={maxLabelOrDescriptionWidth}
minWidth={0}
>
<Text
color={
isActive ? theme.status.success : theme.text.primary
}
>
{item.label}
{scopeMessage && (
<Text color={theme.text.secondary}>
{' '}
{scopeMessage}
</Text>
)}
</Text>
<Text color={theme.text.secondary} wrap="truncate">
{item.description ?? ''}
</Text>
</Box>
<Box minWidth={3} />
<Box flexShrink={0}>
<Text
color={
isActive
? theme.status.success
: shouldBeGreyedOut
? theme.text.secondary
: theme.text.primary
}
>
{displayValue}
</Text>
</Box>
</Box>
</Box>
<Box height={1} />
</React.Fragment>

View File

@@ -10,21 +10,29 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false
│ Vim Mode false
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false
│ Disable Auto Update false
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false
│ Hide Window Title false
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -48,21 +56,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode true*
│ Vim Mode true*
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false
│ Disable Auto Update false
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false
│ Hide Window Title false
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -86,21 +102,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false*
│ Vim Mode false*
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false*
│ Disable Auto Update false*
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false*
│ Enable Prompt Completion false*
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false*
│ Debug Keystroke Logging false*
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false*
│ Hide Window Title false*
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -124,21 +148,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false
│ Vim Mode false
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false
│ Disable Auto Update false
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false
│ Hide Window Title false
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -162,21 +194,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false
│ Vim Mode false
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false
│ Disable Auto Update false
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false
│ Hide Window Title false
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -200,21 +240,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ Preview Features (e.g., models) false
│ Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false
│ Vim Mode false
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false
│ Disable Auto Update false
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false
│ Hide Window Title false
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -238,21 +286,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false*
│ Vim Mode false*
│ Enable Vim keybindings │
│ │
│ Disable Auto Update true*
│ Disable Auto Update true*
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false*
│ Hide Window Title false*
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -276,21 +332,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode false
│ Vim Mode false
│ Enable Vim keybindings │
│ │
│ Disable Auto Update false
│ Disable Auto Update false
│ Disable automatic updates │
│ │
│ Enable Prompt Completion false
│ Enable Prompt Completion false
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging false
│ Debug Keystroke Logging false
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title false
│ Hide Window Title false
│ Hide the window title bar │
│ │
│ ▼ │
│ │
@@ -314,21 +378,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ ▲ │
│ ● Preview Features (e.g., models) false
│ ● Preview Features (e.g., models) false
│ Enable preview features (e.g., preview models). │
│ │
│ Vim Mode true*
│ Vim Mode true*
│ Enable Vim keybindings │
│ │
│ Disable Auto Update true*
│ Disable Auto Update true*
│ Disable automatic updates │
│ │
│ Enable Prompt Completion true*
│ Enable Prompt Completion true*
│ Enable AI-powered prompt completion suggestions while typing. │
│ │
│ Debug Keystroke Logging true*
│ Debug Keystroke Logging true*
│ Enable debug logging of keystrokes to the console. │
│ │
│ Enable Session Cleanup false
│ Enable Session Cleanup false
│ Enable automatic session cleanup │
│ │
│ Output Format Text
│ Output Format Text
│ The format of the CLI output. │
│ │
│ Hide Window Title true*
│ Hide Window Title true*
│ Hide the window title bar │
│ │
│ ▼ │
│ │