diff --git a/src/ui/locales/en.json b/src/ui/locales/en.json index ea9dbfea6..89112aada 100644 --- a/src/ui/locales/en.json +++ b/src/ui/locales/en.json @@ -1514,6 +1514,18 @@ "title": "Keyboard Shortcuts", "description": "Bind keys to actions in the terminal and the app, or change the built-in shortcuts.", "defaultsHeading": "Built-in Shortcuts", + "fixedHeading": "App Shortcuts", + "fixed": { + "splitRight": "Split right", + "splitDown": "Split down", + "zoomPane": "Zoom the focused pane", + "navigatePane": "Move between panes", + "nextTab": "Next tab", + "previousTab": "Previous tab", + "jumpTab": "Jump to tab", + "previousView": "Back to the previous sidebar view", + "fullscreen": "Toggle fullscreen" + }, "customHeading": "Custom Shortcuts", "addBinding": "Add Shortcut", "addBindingTitle": "Add Shortcut", diff --git a/src/ui/sidebar/FixedShortcutsList.tsx b/src/ui/sidebar/FixedShortcutsList.tsx new file mode 100644 index 000000000..2e36ccd7d --- /dev/null +++ b/src/ui/sidebar/FixedShortcutsList.tsx @@ -0,0 +1,48 @@ +import { useTranslation } from "react-i18next"; +import { tabJumpHotkeyKeys } from "@/lib/tab-jump-hotkey"; + +/** Shortcuts the shell handles itself; they cannot be rebound. */ +export function fixedShortcuts(): Array<{ keys: string[]; labelKey: string }> { + return [ + { keys: ["Ctrl", "Shift", "\\"], labelKey: "splitRight" }, + { keys: ["Ctrl", "Shift", "-"], labelKey: "splitDown" }, + { keys: ["Ctrl", "Shift", "Enter"], labelKey: "zoomPane" }, + { keys: ["Alt", "↑↓←→"], labelKey: "navigatePane" }, + { keys: ["Ctrl", "Shift", "]"], labelKey: "nextTab" }, + { keys: ["Ctrl", "Shift", "["], labelKey: "previousTab" }, + { keys: tabJumpHotkeyKeys(), labelKey: "jumpTab" }, + { keys: ["Ctrl", "Shift", "E"], labelKey: "previousView" }, + { keys: ["Ctrl", "Shift", "F"], labelKey: "fullscreen" }, + ]; +} + +export function FixedShortcutsList() { + const { t } = useTranslation(); + return ( +
+ + {t("newUi.sidebar.keybindings.fixedHeading")} + + {fixedShortcuts().map(({ keys, labelKey }) => ( +
+ + {t(`newUi.sidebar.keybindings.fixed.${labelKey}`)} + +
+ {keys.map((key, index) => ( + + {key} + + ))} +
+
+ ))} +
+ ); +} diff --git a/src/ui/sidebar/KeybindingsDialog.tsx b/src/ui/sidebar/KeybindingsDialog.tsx index a94c7e350..a5eb0b84a 100644 --- a/src/ui/sidebar/KeybindingsDialog.tsx +++ b/src/ui/sidebar/KeybindingsDialog.tsx @@ -26,6 +26,7 @@ import { import { Button } from "@/components/button"; import { Input } from "@/components/input"; import { Pencil, Plus, RotateCcw, Trash2 } from "lucide-react"; +import { FixedShortcutsList } from "./FixedShortcutsList"; function formatCombo(combo: KeyCombo): string { const parts: string[] = []; @@ -395,6 +396,7 @@ export function KeybindingsDialog({ }) )} +
diff --git a/src/ui/tests/sidebar/FixedShortcutsList.test.tsx b/src/ui/tests/sidebar/FixedShortcutsList.test.tsx new file mode 100644 index 000000000..ed8518237 --- /dev/null +++ b/src/ui/tests/sidebar/FixedShortcutsList.test.tsx @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { + FixedShortcutsList, + fixedShortcuts, +} from "@/sidebar/FixedShortcutsList"; + +describe("FixedShortcutsList", () => { + it("lists every shell shortcut with its keys", () => { + render(); + expect( + screen.getByText("newUi.sidebar.keybindings.fixed.splitRight"), + ).toBeTruthy(); + expect(screen.getAllByText("Shift").length).toBeGreaterThan(3); + expect(fixedShortcuts().map((s) => s.labelKey)).toContain("jumpTab"); + }); +});