diff --git a/docs/cli/keyboard-shortcuts.md b/docs/cli/keyboard-shortcuts.md
index ce5990a906..d377cfd3e2 100644
--- a/docs/cli/keyboard-shortcuts.md
+++ b/docs/cli/keyboard-shortcuts.md
@@ -131,7 +131,8 @@ available combinations.
- `!` on an empty prompt: Enter or exit shell mode.
- `?` on an empty prompt: Toggle the shortcuts panel above the input. Press
`Esc`, `Backspace`, or any printable key to close it. Press `?` again to close
- the panel and insert a `?` into the prompt.
+ the panel and insert a `?` into the prompt. You can hide only the hint text
+ via `ui.showShortcutsHint`, without changing this keyboard behavior.
- `\` (at end of a line) + `Enter`: Insert a newline without leaving single-line
mode.
- `Esc` pressed twice quickly: Clear the input prompt if it is not empty,
diff --git a/docs/cli/settings.md b/docs/cli/settings.md
index e7fe0dd1ee..70523c6fd1 100644
--- a/docs/cli/settings.md
+++ b/docs/cli/settings.md
@@ -49,6 +49,7 @@ they appear in the UI.
| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` |
| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` |
| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` |
+| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `true` |
| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` |
| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` |
| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory path in the footer. | `false` |
diff --git a/docs/get-started/configuration.md b/docs/get-started/configuration.md
index eba48e8d74..619dbf6869 100644
--- a/docs/get-started/configuration.md
+++ b/docs/get-started/configuration.md
@@ -220,6 +220,10 @@ their corresponding top-level category object in your `settings.json` file.
- **Description:** Hide helpful tips in the UI
- **Default:** `false`
+- **`ui.showShortcutsHint`** (boolean):
+ - **Description:** Show the "? for shortcuts" hint above the input.
+ - **Default:** `true`
+
- **`ui.hideBanner`** (boolean):
- **Description:** Hide the application banner
- **Default:** `false`
diff --git a/packages/cli/src/config/settingsSchema.test.ts b/packages/cli/src/config/settingsSchema.test.ts
index d83ac705f7..bc558e77b8 100644
--- a/packages/cli/src/config/settingsSchema.test.ts
+++ b/packages/cli/src/config/settingsSchema.test.ts
@@ -186,6 +186,9 @@ describe('SettingsSchema', () => {
expect(getSettingsSchema().ui.properties.hideTips.showInDialog).toBe(
true,
);
+ expect(
+ getSettingsSchema().ui.properties.showShortcutsHint.showInDialog,
+ ).toBe(true);
expect(getSettingsSchema().ui.properties.hideBanner.showInDialog).toBe(
true,
);
@@ -328,6 +331,28 @@ describe('SettingsSchema', () => {
).toBe('Enable debug logging of keystrokes to the console.');
});
+ it('should have showShortcutsHint setting in schema', () => {
+ expect(getSettingsSchema().ui.properties.showShortcutsHint).toBeDefined();
+ expect(getSettingsSchema().ui.properties.showShortcutsHint.type).toBe(
+ 'boolean',
+ );
+ expect(getSettingsSchema().ui.properties.showShortcutsHint.category).toBe(
+ 'UI',
+ );
+ expect(getSettingsSchema().ui.properties.showShortcutsHint.default).toBe(
+ true,
+ );
+ expect(
+ getSettingsSchema().ui.properties.showShortcutsHint.requiresRestart,
+ ).toBe(false);
+ expect(
+ getSettingsSchema().ui.properties.showShortcutsHint.showInDialog,
+ ).toBe(true);
+ expect(
+ getSettingsSchema().ui.properties.showShortcutsHint.description,
+ ).toBe('Show the "? for shortcuts" hint above the input.');
+ });
+
it('should have enableAgents setting in schema', () => {
const setting = getSettingsSchema().experimental.properties.enableAgents;
expect(setting).toBeDefined();
diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts
index cc9e12f06f..d530ec4a53 100644
--- a/packages/cli/src/config/settingsSchema.ts
+++ b/packages/cli/src/config/settingsSchema.ts
@@ -462,6 +462,15 @@ const SETTINGS_SCHEMA = {
description: 'Hide helpful tips in the UI',
showInDialog: true,
},
+ showShortcutsHint: {
+ type: 'boolean',
+ label: 'Show Shortcuts Hint',
+ category: 'UI',
+ requiresRestart: false,
+ default: true,
+ description: 'Show the "? for shortcuts" hint above the input.',
+ showInDialog: true,
+ },
hideBanner: {
type: 'boolean',
label: 'Hide Banner',
diff --git a/packages/cli/src/ui/components/Composer.test.tsx b/packages/cli/src/ui/components/Composer.test.tsx
index da7b866391..ee3a441c04 100644
--- a/packages/cli/src/ui/components/Composer.test.tsx
+++ b/packages/cli/src/ui/components/Composer.test.tsx
@@ -650,6 +650,19 @@ describe('Composer', () => {
});
describe('Shortcuts Hint', () => {
+ it('hides shortcuts hint when showShortcutsHint setting is false', () => {
+ const uiState = createMockUIState();
+ const settings = createMockSettings({
+ ui: {
+ showShortcutsHint: false,
+ },
+ });
+
+ const { lastFrame } = renderComposer(uiState, settings);
+
+ expect(lastFrame()).not.toContain('ShortcutsHint');
+ });
+
it('hides shortcuts hint when a action is required (e.g. dialog is open)', () => {
const uiState = createMockUIState({
customDialog: (
diff --git a/packages/cli/src/ui/components/Composer.tsx b/packages/cli/src/ui/components/Composer.tsx
index 84001056a8..e87e86e801 100644
--- a/packages/cli/src/ui/components/Composer.tsx
+++ b/packages/cli/src/ui/components/Composer.tsx
@@ -133,7 +133,8 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
flexDirection="column"
alignItems={isNarrow ? 'flex-start' : 'flex-end'}
>
- {!hasPendingActionRequired && }
+ {settings.merged.ui.showShortcutsHint &&
+ !hasPendingActionRequired && }
{uiState.shortcutsHelpVisible && }
diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx
index 0903c0b066..0446f67381 100644
--- a/packages/cli/src/ui/components/InputPrompt.test.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.test.tsx
@@ -4296,6 +4296,30 @@ describe('InputPrompt', () => {
});
describe('shortcuts help visibility', () => {
+ it('opens shortcuts help with ? on empty prompt even when showShortcutsHint is false', async () => {
+ const setShortcutsHelpVisible = vi.fn();
+ const settings = createMockSettings({
+ ui: { showShortcutsHint: false },
+ });
+
+ const { stdin, unmount } = renderWithProviders(
+ ,
+ {
+ settings,
+ uiActions: { setShortcutsHelpVisible },
+ },
+ );
+
+ await act(async () => {
+ stdin.write('?');
+ });
+
+ await waitFor(() => {
+ expect(setShortcutsHelpVisible).toHaveBeenCalledWith(true);
+ });
+ unmount();
+ });
+
it.each([
{
name: 'terminal paste event occurs',
diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json
index d5146d46f8..9072077c2c 100644
--- a/schemas/settings.schema.json
+++ b/schemas/settings.schema.json
@@ -245,6 +245,13 @@
"default": false,
"type": "boolean"
},
+ "showShortcutsHint": {
+ "title": "Show Shortcuts Hint",
+ "description": "Show the \"? for shortcuts\" hint above the input.",
+ "markdownDescription": "Show the \"? for shortcuts\" hint above the input.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `true`",
+ "default": true,
+ "type": "boolean"
+ },
"hideBanner": {
"title": "Hide Banner",
"description": "Hide the application banner",