diff --git a/desktop/frontend/src/App.tsx b/desktop/frontend/src/App.tsx index 9d27a321a3..7d6af4984e 100644 --- a/desktop/frontend/src/App.tsx +++ b/desktop/frontend/src/App.tsx @@ -3918,9 +3918,10 @@ export default function App() { return isNavigationIntentCurrent(navigationIntentSeq); }, [enqueueNavigationWithIntent, isNavigationIntentCurrent, noteNavigationIntent, singleSurfaceLayout, state.running, t]); - // Command palette: ⌘K / Ctrl+K opens a fuzzy navigator over commands and - // recent sessions. Sessions are snapshotted on open so the list is stable - // while the palette is up; extension actions follow the same snapshot rule. + // Command palette: F1 (every platform, matching VSCode) opens a fuzzy + // navigator over commands and recent sessions. Sessions are snapshotted on + // open so the list is stable while the palette is up; extension actions + // follow the same snapshot rule. const openPalette = useCallback(async () => { closeTransientOverlays(); setPaletteOpen(true); diff --git a/desktop/frontend/src/__tests__/keyboard-shortcuts.test.ts b/desktop/frontend/src/__tests__/keyboard-shortcuts.test.ts index 57717d7b8a..cbebfb7e17 100644 --- a/desktop/frontend/src/__tests__/keyboard-shortcuts.test.ts +++ b/desktop/frontend/src/__tests__/keyboard-shortcuts.test.ts @@ -9,6 +9,7 @@ import { isCloseTabShortcut, isReservedComposerHistoryShortcut, matchesShortcut, + migrateLegacyCustomShortcuts, shortcutAcceptsCombo, shortcutConflict, shortcutDefinition, @@ -69,10 +70,21 @@ eq(isCloseTabShortcut(event("w", { ctrlKey: true }), "linux"), true, "Ctrl+W clo for (const platform of ["darwin", "windows", "linux"] satisfies ShortcutPlatform[]) { eq(isCloseTabShortcut(event("k", { ctrlKey: true, metaKey: true }), platform), false, `${platform} ignores non-W keys`); eq(isCloseTabShortcut(event("w"), platform), false, `${platform} requires the platform modifier`); + eq(matchesShortcut(event("F1"), "commandPalette.open", platform), true, `${platform} opens the palette on F1 (VSCode convention)`); + eq(matchesShortcut(event("k", { ctrlKey: true }), "commandPalette.open", platform), false, `${platform} Ctrl+K is not the palette`); + eq(matchesShortcut(event("k", { metaKey: true }), "commandPalette.open", platform), false, `${platform} Cmd+K is not the palette`); + eq(matchesShortcut(event("k", { metaKey: true }), "terminal.clear", "darwin"), true, "macOS terminal clear defaults to Cmd+K"); + eq(matchesShortcut(event("k", { ctrlKey: true }), "terminal.clear", platform), platform === "darwin" ? false : true, `${platform} terminal clear matches the platform modifier`); + eq(matchesShortcut(event("k"), "terminal.clear", platform), false, `${platform} bare K is not the terminal clear chord`); } - -eq(matchesShortcut(event("k", { metaKey: true }), "commandPalette.open", "darwin"), true, "Cmd+K opens the palette on macOS"); -eq(matchesShortcut(event("k", { ctrlKey: true }), "commandPalette.open", "windows"), true, "Ctrl+K opens the palette on Windows"); +eq(formatShortcutCombo(defaultShortcutCombo("commandPalette.open", "darwin"), "darwin"), "F1", "formats the macOS palette shortcut as F1"); +eq(formatShortcutCombo(defaultShortcutCombo("commandPalette.open", "windows"), "windows"), "F1", "formats the Windows palette shortcut as F1"); +eq(formatShortcutCombo(defaultShortcutCombo("terminal.clear", "darwin"), "darwin"), "⌘K", "formats the macOS terminal clear shortcut as ⌘K"); +eq(formatShortcutCombo(defaultShortcutCombo("terminal.clear", "windows"), "windows"), "Ctrl+K", "formats the Windows terminal clear shortcut as Ctrl+K"); +eq(migrateLegacyCustomShortcuts({ "commandPalette.open": { key: "k", meta: true } }, "darwin")["commandPalette.open"], undefined, "legacy macOS Cmd+K palette binding is dropped so terminal.clear owns Cmd+K"); +eq(migrateLegacyCustomShortcuts({ "commandPalette.open": { key: "F2" } }, "darwin")["commandPalette.open"]?.key, "F2", "custom palette bindings other than legacy Cmd+K are kept"); +eq(migrateLegacyCustomShortcuts({ "commandPalette.open": { key: "k", ctrl: true } }, "darwin")["commandPalette.open"]?.key, "k", "non-darwin legacy bindings are only normalized, never dropped by the darwin migration"); +eq(migrateLegacyCustomShortcuts({ "commandPalette.open": { key: "k", meta: true } }, "windows")["commandPalette.open"]?.key, "k", "the migration is a no-op on non-darwin platforms"); eq(matchesShortcut({ key: "?", shiftKey: true }, "shortcuts.show", "darwin"), true, "? opens shortcut help"); eq(matchesShortcut({ key: "+", metaKey: true, shiftKey: true }, "textSize.increase", "darwin"), true, "Cmd+Plus still increases text size"); eq(formatShortcutCombo(defaultShortcutCombo("settings.open", "darwin"), "darwin"), "⌘,", "formats mac settings shortcut"); diff --git a/desktop/frontend/src/__tests__/terminal-clear-shortcut.test.ts b/desktop/frontend/src/__tests__/terminal-clear-shortcut.test.ts new file mode 100644 index 0000000000..50b40b0664 --- /dev/null +++ b/desktop/frontend/src/__tests__/terminal-clear-shortcut.test.ts @@ -0,0 +1,52 @@ +// Run: tsx src/__tests__/terminal-clear-shortcut.test.ts +// +// Contract test: the terminal's clear-screen-and-scrollback action lives in +// the shared shortcut registry ("terminal.clear", Cmd+K / Ctrl+K like VSCode's +// integrated terminal) and TerminalView resolves it through matchesShortcut, so +// the shortcut settings panel, conflict detection, and custom bindings all +// apply to it automatically. + +import { readFileSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +let passed = 0; +let failed = 0; + +function ok(condition: boolean, label: string) { + if (condition) { + process.stdout.write(` PASS ${label}\n`); + passed += 1; + } else { + process.stdout.write(` FAIL ${label}\n`); + failed += 1; + } +} + +const testDir = dirname(fileURLToPath(import.meta.url)); +const terminalViewSource = readFileSync(resolve(testDir, "../components/TerminalView.tsx"), "utf8"); +const keyboardSource = readFileSync(resolve(testDir, "../lib/keyboardShortcuts.ts"), "utf8"); + +console.log("\nterminal clear shortcut"); + +// The action must be a first-class registry citizen so the settings panel and +// the shortcuts cheatsheet render it and users can rebind it. +ok(/action: "terminal\.clear"/.test(keyboardSource), "terminal.clear is a registered shortcut action"); +ok(/labelKey: "shortcuts\.action\.terminalClear"/.test(keyboardSource), "terminal.clear has a settings label key"); +ok(/descriptionKey: "shortcuts\.desc\.terminalClear"/.test(keyboardSource), "terminal.clear has a settings description key"); +ok(/defaults: modCombo\("k"\)/.test(keyboardSource), "terminal.clear defaults to Cmd+K on macOS, Ctrl+K on Windows/Linux"); +ok(/allowInEditable: true/.test(keyboardSource), "terminal.clear may fire from the terminal's editable surface"); +ok(/action: "commandPalette\.open"[\s\S]*?defaults: allPlatforms\(\{ key: "F1" \}\)/.test(keyboardSource), "command palette is F1 on every platform (VSCode convention)"); + +// TerminalView must resolve the chord through the shared matcher, not a +// hardcoded key check, so custom bindings and conflicts are respected. +ok(/matchesShortcut\(event, "terminal\.clear", detectShortcutPlatform\(\)\)/.test(terminalViewSource), "TerminalView resolves the chord via the shared shortcut matcher"); +ok(/host\.closest\("\.terminal-panel"\)/.test(terminalViewSource) && /panel\.contains\(event\.target\)/.test(terminalViewSource), "handler only fires while focus is inside the terminal panel"); +ok(/event\.preventDefault\(\)/.test(terminalViewSource), "handler stops the browser from processing the chord"); +ok(/event\.stopImmediatePropagation\(\)/.test(terminalViewSource), "handler suppresses other global shortcut handlers"); +ok(/terminal\.clear\(\)/.test(terminalViewSource), "handler clears the full buffer (screen + scrollback)"); +ok(/addEventListener\("keydown", clearTerminal, \{ capture: true \}\)/.test(terminalViewSource), "handler registers in the capture phase before xterm"); +ok(/removeEventListener\("keydown", clearTerminal, \{ capture: true \}\)/.test(terminalViewSource), "handler unregisters when the terminal unmounts"); + +console.log(`\n${passed} passed, ${failed} failed, ${passed + failed} total`); +if (failed > 0) process.exit(1); diff --git a/desktop/frontend/src/components/CommandPalette.tsx b/desktop/frontend/src/components/CommandPalette.tsx index 78e8cee138..89889484df 100644 --- a/desktop/frontend/src/components/CommandPalette.tsx +++ b/desktop/frontend/src/components/CommandPalette.tsx @@ -4,12 +4,13 @@ import { Command, Search } from "lucide-react"; import { useT } from "../lib/i18n"; import { useMountTransition } from "../lib/useMountTransition"; -// CommandPalette is a ⌘K / Ctrl+K modal that surfaces the desktop app's -// long-tail navigation surface. Tabs through sessions, slash-commands, and -// recent files via a single fuzzy search. The list of items is provided by -// the caller (App) so the palette stays decoupled from the controller — the -// same component will work for skills, MCP servers, and future surfaces -// once a buildItems() helper is added for them. +// CommandPalette is an F1 modal (every platform, matching VSCode's command +// palette) that surfaces the desktop app's long-tail navigation surface. Tabs +// through sessions, slash-commands, and recent files via a single fuzzy +// search. The list of items is provided by the caller (App) so the palette +// stays decoupled from the controller — the same component will work for +// skills, MCP servers, and future surfaces once a buildItems() helper is +// added for them. // // Interaction model: // - Input is auto-focused on open; the first match is highlighted. diff --git a/desktop/frontend/src/components/TabBar.tsx b/desktop/frontend/src/components/TabBar.tsx index 181a5bddf3..4b588be652 100644 --- a/desktop/frontend/src/components/TabBar.tsx +++ b/desktop/frontend/src/components/TabBar.tsx @@ -6,6 +6,7 @@ import { FileText, Plus, Search, X } from "lucide-react"; import { normalizeCollaborationMode, normalizeMode, normalizeToolApprovalMode, type Mode, type TabMeta } from "../lib/types"; import { projectColorValue } from "../lib/projectColors"; import { useT } from "../lib/i18n"; +import { useShortcutComboLabel } from "../lib/keyboardShortcuts"; import { Tooltip } from "./Tooltip"; import { ContextMenu, contextMenuPointFromEvent, type ContextMenuItem, type ContextMenuPoint } from "./ContextMenu"; import { WorktreeBadge } from "./WorktreeBadge"; @@ -55,6 +56,7 @@ function projectAccentStyle(color?: string): CSSProperties | undefined { export function TabBar({ tabs, activeTabId, onTabChange, onTabClose, onTabsClose, onTabsReorder, onNewTab, onOpenPalette, commandCompact = false, revealActiveSignal = 0 }: TabBarProps) { const t = useT(); + const paletteShortcut = useShortcutComboLabel("commandPalette.open"); const [draggingTabId, setDraggingTabId] = useState(null); const [dropTarget, setDropTarget] = useState<{ id: string; side: DropSide } | null>(null); const [menuTabId, setMenuTabId] = useState(null); @@ -297,7 +299,7 @@ export function TabBar({ tabs, activeTabId, onTabChange, onTabClose, onTabsClose <> {t("tabBar.commandSearch")} {t("tabBar.commandSearchCompact")} - ⌘K + {paletteShortcut} )} diff --git a/desktop/frontend/src/components/TerminalView.tsx b/desktop/frontend/src/components/TerminalView.tsx index 04f820716a..197214783d 100644 --- a/desktop/frontend/src/components/TerminalView.tsx +++ b/desktop/frontend/src/components/TerminalView.tsx @@ -6,6 +6,7 @@ import "@xterm/xterm/css/xterm.css"; import { useTerminalStore } from "../store/terminal"; import { registerTerminalSink, startTerminalEventBridge } from "../lib/terminalEvents"; import { observeTerminalTheme, terminalThemeForElement } from "../lib/terminalTheme"; +import { detectShortcutPlatform, matchesShortcut } from "../lib/keyboardShortcuts"; import type { TerminalSessionView } from "../lib/types"; export function TerminalView({ tabId, session }: { tabId: string; session: TerminalSessionView }) { @@ -34,6 +35,24 @@ export function TerminalView({ tabId, session }: { tabId: string; session: Termi const unregister = registerTerminalSink(session.id, (bytes) => terminal.write(bytes)); const input = terminal.onData((data) => { void write(tabId, session.id, data).catch(() => {}); }); const outputResize = terminal.onResize(({ cols, rows }) => { void resize(tabId, session.id, cols, rows).catch(() => {}); }); + // Clear-screen-and-scrollback lives in the shared shortcut registry as + // "terminal.clear" (Cmd+K on macOS, Ctrl+K elsewhere — VSCode's terminal + // convention), so users can rebind or inspect it from the shortcut + // settings like any other action. xterm.clear() empties the whole buffer, + // making the prompt line the new first line. The capture-phase listener + // fires before xterm's own key handling, and only while focus is anywhere + // inside the terminal panel (not just the xterm element), so the chord + // keeps its native meaning in the composer and other editors. + const clearTerminal = (event: globalThis.KeyboardEvent) => { + if (!(event.target instanceof Node)) return; + const panel = host.closest(".terminal-panel"); + if (!panel || !panel.contains(event.target)) return; + if (!matchesShortcut(event, "terminal.clear", detectShortcutPlatform())) return; + event.preventDefault(); + event.stopImmediatePropagation(); + terminal.clear(); + }; + document.addEventListener("keydown", clearTerminal, { capture: true }); const fitTerminal = () => { fit.fit(); const { cols, rows } = terminal; @@ -45,6 +64,7 @@ export function TerminalView({ tabId, session }: { tabId: string; session: Termi return () => { observer?.disconnect(); stopObservingTheme(); + document.removeEventListener("keydown", clearTerminal, { capture: true }); input.dispose(); outputResize.dispose(); unregister(); diff --git a/desktop/frontend/src/lib/keyboardShortcuts.ts b/desktop/frontend/src/lib/keyboardShortcuts.ts index 7a516d8a7a..160a4acd01 100644 --- a/desktop/frontend/src/lib/keyboardShortcuts.ts +++ b/desktop/frontend/src/lib/keyboardShortcuts.ts @@ -16,6 +16,7 @@ export type ShortcutAction = | "shell.toggle" | "terminal.toggle" | "terminal.newSession" + | "terminal.clear" | "sidebar.toggle" | "textSize.increase" | "textSize.decrease" @@ -75,7 +76,10 @@ export const SHORTCUT_DEFINITIONS: readonly ShortcutDefinition[] = [ section: "global", labelKey: "shortcuts.action.commandPalette", descriptionKey: "shortcuts.desc.commandPalette", - defaults: modCombo("k"), + // F1 on every platform matches VSCode's command palette. macOS keeps + // Cmd+K for the terminal's clear-screen-and-scrollback action; on + // Windows/Linux Ctrl+K belongs to the terminal for the same reason. + defaults: allPlatforms({ key: "F1" }), preventDefault: true, allowInEditable: true, }, @@ -179,6 +183,20 @@ export const SHORTCUT_DEFINITIONS: readonly ShortcutDefinition[] = [ preventDefault: true, allowInEditable: true, }, + { + action: "terminal.clear", + section: "view", + labelKey: "shortcuts.action.terminalClear", + descriptionKey: "shortcuts.desc.terminalClear", + // Matches VSCode's integrated terminal: Cmd+K / Ctrl+K while the terminal + // has focus clears the screen and the scrollback. The action is handled + // inside TerminalView (it is only meaningful while the terminal is + // focused), but it lives in the shared registry so users can rebind or + // inspect it from the shortcut settings like any other action. + defaults: modCombo("k"), + preventDefault: true, + allowInEditable: true, + }, { action: "sidebar.toggle", section: "view", @@ -372,13 +390,32 @@ export function loadCustomShortcuts(): Partial> { + const out = normalizeCustomShortcuts(value); + if (platform !== "darwin") return out; + const legacyPaletteDefault: ShortcutCombo = { key: "k", meta: true }; + const palette = out["commandPalette.open"]; + if (palette && sameCombo(palette, legacyPaletteDefault)) delete out["commandPalette.open"]; + return out; +} + export function saveCustomShortcut(action: ShortcutAction, combo: ShortcutCombo | null): void { const next = { ...loadCustomShortcuts() }; if (combo) { diff --git a/desktop/frontend/src/locales/en.ts b/desktop/frontend/src/locales/en.ts index c98ed96784..051b80af84 100644 --- a/desktop/frontend/src/locales/en.ts +++ b/desktop/frontend/src/locales/en.ts @@ -2410,6 +2410,7 @@ export const en = { "shortcuts.action.shellToggle": "Toggle shell", "shortcuts.action.terminalToggle": "Toggle integrated terminal", "shortcuts.action.terminalNewSession": "New terminal session", + "shortcuts.action.terminalClear": "Clear terminal screen", "shortcuts.action.sidebarToggle": "Toggle sidebar", "shortcuts.action.textSizeIncrease": "Increase text size", "shortcuts.action.textSizeDecrease": "Decrease text size", @@ -2428,6 +2429,7 @@ export const en = { "shortcuts.desc.shellToggle": "Expand or collapse the shell panel.", "shortcuts.desc.terminalToggle": "Show or hide the integrated terminal.", "shortcuts.desc.terminalNewSession": "Open a new integrated terminal session.", + "shortcuts.desc.terminalClear": "While the terminal has focus, clear the screen and the scrollback.", "shortcuts.desc.sidebarToggle": "Show or hide the left sidebar.", "shortcuts.desc.textSizeIncrease": "Make transcript and UI text larger.", "shortcuts.desc.textSizeDecrease": "Make transcript and UI text smaller.", diff --git a/desktop/frontend/src/locales/zh-TW.ts b/desktop/frontend/src/locales/zh-TW.ts index 057a1e3a3d..2605ff7951 100644 --- a/desktop/frontend/src/locales/zh-TW.ts +++ b/desktop/frontend/src/locales/zh-TW.ts @@ -3051,6 +3051,7 @@ export const zhTW: Record = { "shortcuts.action.shellToggle": "切換 Shell", "shortcuts.action.terminalToggle": "切換內建終端機", "shortcuts.action.terminalNewSession": "新增終端機工作階段", + "shortcuts.action.terminalClear": "清除畫面與捲動區", "shortcuts.action.sidebarToggle": "切換側邊欄", "shortcuts.action.textSizeIncrease": "增大字號", "shortcuts.action.textSizeDecrease": "減小字號", @@ -3069,6 +3070,7 @@ export const zhTW: Record = { "shortcuts.desc.shellToggle": "展開或折疊 Shell 面板。", "shortcuts.desc.terminalToggle": "顯示或隱藏內建終端機。", "shortcuts.desc.terminalNewSession": "開啟新的內建終端機工作階段。", + "shortcuts.desc.terminalClear": "終端機取得焦點時,清除畫面與捲動區。", "shortcuts.desc.sidebarToggle": "顯示或隱藏左側邊欄。", "shortcuts.desc.textSizeIncrease": "放大會話和介面文字。", "shortcuts.desc.textSizeDecrease": "縮小會話和介面文字。", diff --git a/desktop/frontend/src/locales/zh.ts b/desktop/frontend/src/locales/zh.ts index 696102b85c..485a64ad83 100644 --- a/desktop/frontend/src/locales/zh.ts +++ b/desktop/frontend/src/locales/zh.ts @@ -2413,6 +2413,7 @@ export const zh: Record = { "shortcuts.action.shellToggle": "切换 Shell", "shortcuts.action.terminalToggle": "切换内置终端", "shortcuts.action.terminalNewSession": "新建终端会话", + "shortcuts.action.terminalClear": "清屏并清除滚动区", "shortcuts.action.sidebarToggle": "切换侧边栏", "shortcuts.action.textSizeIncrease": "增大字号", "shortcuts.action.textSizeDecrease": "减小字号", @@ -2431,6 +2432,7 @@ export const zh: Record = { "shortcuts.desc.shellToggle": "展开或折叠 Shell 面板。", "shortcuts.desc.terminalToggle": "显示或隐藏内置终端。", "shortcuts.desc.terminalNewSession": "打开一个新的内置终端会话。", + "shortcuts.desc.terminalClear": "终端获得焦点时,清空屏幕和滚动区。", "shortcuts.desc.sidebarToggle": "显示或隐藏左侧边栏。", "shortcuts.desc.textSizeIncrease": "放大会话和界面文字。", "shortcuts.desc.textSizeDecrease": "缩小会话和界面文字。", diff --git a/desktop/frontend/src/styles.css b/desktop/frontend/src/styles.css index 71b2f59cbf..9de2b0e354 100644 --- a/desktop/frontend/src/styles.css +++ b/desktop/frontend/src/styles.css @@ -10959,7 +10959,7 @@ body > .mermaid-diagram--fullscreen { background: rgba(0, 0, 0, 0.16); } -/* ── command palette (⌘K) — centered modal over a dimmed backdrop ─────────── */ +/* ── command palette (F1) — centered modal over a dimmed backdrop ─────────── */ .drawer-backdrop:has(> .palette) { justify-content: center; align-items: flex-start; @@ -23346,7 +23346,7 @@ body > .mermaid-diagram--fullscreen { color: var(--fg); } -/* L1: command-search bar — opens the ⌘K palette. Sits after the new-tab +/* L1: command-search bar — opens the F1 palette. Sits after the new-tab button and fills the remaining strip width like the prototype. */ .tabbar__command { flex: 1 1 auto; diff --git a/docs/GUIDE.md b/docs/GUIDE.md index dbb7ea0a9a..2fbc0c8d48 100644 --- a/docs/GUIDE.md +++ b/docs/GUIDE.md @@ -565,11 +565,12 @@ Global shortcuts: | Key or control | What it does | Notes | | --- | --- | --- | -| `Cmd+K` on macOS, `Ctrl+K` on Windows/Linux | Toggles the command palette | The palette focuses search when it opens; `Esc` closes it. | +| `F1` | Toggles the command palette | Matches VSCode on every platform; `Cmd+K`/`Ctrl+K` is reserved for the terminal's clear action. The palette focuses search when it opens; `Esc` closes it. | | `Cmd+,` on macOS, `Ctrl+,` on Windows/Linux | Opens Settings | Use **Shortcuts** in Settings to customize desktop bindings. | | `Cmd+W` on macOS, `Ctrl+W` on Windows/Linux | Closes the active top tab | The last tab is kept by the normal close-tab guard. | | `Cmd+B` / `Ctrl+B` | Shows or hides the left sidebar | Same action as clicking the sidebar toggle. | | `Cmd+Shift+B` / `Ctrl+Shift+B` | Expands or collapses the most recent shell output | Same action as clicking the collapsed shell-output hint. | +| `Cmd+K` on macOS, `Ctrl+K` on Windows/Linux | While the terminal has focus, clears the screen and the scrollback | Matches VSCode's integrated terminal; the terminal must have focus, elsewhere the chord keeps its native meaning. Rebindable from **Settings → Shortcuts**. | | `Cmd+1`-`Cmd+9` on macOS, `Ctrl+1`-`Ctrl+9` elsewhere | Jumps to the matching visible chat in the sidebar | Hold `Cmd`/`Ctrl` briefly to reveal the numbered badges. Existing custom shortcuts that already use the same key take precedence. | | `Cmd++`, `Cmd+-`, `Cmd+0` on macOS; `Ctrl++`, `Ctrl+-`, `Ctrl+0` elsewhere | Increases, decreases, or resets text size | `=` is accepted for the plus key on keyboards that report it that way. | | `?` | Opens the keyboard shortcuts sheet | The sheet shows the current effective desktop bindings. | diff --git a/docs/GUIDE.zh-CN.md b/docs/GUIDE.zh-CN.md index 000e720bd8..8ecc7368b0 100644 --- a/docs/GUIDE.zh-CN.md +++ b/docs/GUIDE.zh-CN.md @@ -448,11 +448,12 @@ CLI/TUI 文本输入可通过 `[ui].cursor_shape` 设置光标形状,支持 `u | 按键或控件 | 作用 | 说明 | | --- | --- | --- | -| macOS `Cmd+K`,Windows/Linux `Ctrl+K` | 打开或关闭命令面板 | 打开时会聚焦搜索框;`Esc` 关闭命令面板。 | +| `F1` | 打开或关闭命令面板 | 全平台与 VSCode 对齐;`Cmd+K`/`Ctrl+K` 保留给终端的清屏动作。打开时会聚焦搜索框;`Esc` 关闭命令面板。 | | macOS `Cmd+,`,Windows/Linux `Ctrl+,` | 打开设置 | 在设置里的 **快捷键** 页可自定义桌面端绑定。 | | macOS `Cmd+W`,Windows/Linux `Ctrl+W` | 关闭当前顶部标签页 | 最后一个标签页仍由原有关闭保护保留。 | | `Cmd+B` / `Ctrl+B` | 显示或隐藏左侧边栏 | 和点击侧边栏开关是同一个动作。 | | `Cmd+Shift+B` / `Ctrl+Shift+B` | 展开或收起最近的 shell 输出 | 和点击折叠 shell 输出提示是同一个动作。 | +| macOS `Cmd+K`,Windows/Linux `Ctrl+K` | 终端获得焦点时,清屏并清除滚动区 | 与 VSCode 内置终端一致;需终端持有焦点,其他位置保留该组合键的原生含义。可在 **设置 → 快捷键** 中重新绑定。 | | macOS `Cmd+1`-`Cmd+9`,其它平台 `Ctrl+1`-`Ctrl+9` | 跳转到侧边栏中对应编号的可见对话 | 短暂按住 `Cmd`/`Ctrl` 会显示编号标记;已有自定义快捷键占用相同按键时,自定义动作优先生效。 | | macOS `Cmd++`、`Cmd+-`、`Cmd+0`;其它平台 `Ctrl++`、`Ctrl+-`、`Ctrl+0` | 放大、缩小或重置文字大小 | 对把加号上报为 `=` 的键盘也兼容。 | | `?` | 打开键盘快捷键帮助表 | 帮助表显示当前实际生效的桌面端绑定。 | diff --git a/tools/repolint/baseline.json b/tools/repolint/baseline.json index b30d6db3c0..4556917f78 100644 --- a/tools/repolint/baseline.json +++ b/tools/repolint/baseline.json @@ -84,7 +84,7 @@ "essay": 2 }, "desktop/frontend/src/App.tsx": { - "file-size": 4733 + "file-size": 4734 }, "desktop/frontend/src/__tests__/app-chrome-tabs.test.ts": { "test-file-size": 19