mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
feat: add terminal keyboard shortcuts with cross-platform support
- Add splitTerminalRight, splitTerminalDown, closeTerminal to KeyboardShortcuts - Wire up shortcuts in terminal view (Cmd+D, Cmd+Shift+D, Cmd+W on Mac) - Auto-detect platform and use Ctrl instead of Cmd on Linux/Windows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
import {
|
import {
|
||||||
Terminal as TerminalIcon,
|
Terminal as TerminalIcon,
|
||||||
Plus,
|
Plus,
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
SquarePlus,
|
SquarePlus,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useAppStore, type TerminalPanelContent, type TerminalTab } from "@/store/app-store";
|
import { useAppStore, type TerminalPanelContent, type TerminalTab } from "@/store/app-store";
|
||||||
|
import { useKeyboardShortcutsConfig, type KeyboardShortcut } from "@/hooks/use-keyboard-shortcuts";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
@@ -338,6 +339,60 @@ export function TerminalView() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get keyboard shortcuts config
|
||||||
|
const shortcuts = useKeyboardShortcutsConfig();
|
||||||
|
|
||||||
|
// Handle terminal-specific keyboard shortcuts
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
// Only handle shortcuts when terminal is unlocked and has an active session
|
||||||
|
if (!terminalState.isUnlocked || !terminalState.activeSessionId) return;
|
||||||
|
|
||||||
|
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
||||||
|
const cmdOrCtrl = isMac ? e.metaKey : e.ctrlKey;
|
||||||
|
|
||||||
|
// Parse shortcut string to check for match
|
||||||
|
const matchesShortcut = (shortcutStr: string) => {
|
||||||
|
const parts = shortcutStr.toLowerCase().split('+');
|
||||||
|
const key = parts[parts.length - 1];
|
||||||
|
const needsCmd = parts.includes('cmd');
|
||||||
|
const needsShift = parts.includes('shift');
|
||||||
|
const needsAlt = parts.includes('alt');
|
||||||
|
|
||||||
|
return (
|
||||||
|
e.key.toLowerCase() === key &&
|
||||||
|
cmdOrCtrl === needsCmd &&
|
||||||
|
e.shiftKey === needsShift &&
|
||||||
|
e.altKey === needsAlt
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Split terminal right (Cmd+D / Ctrl+D)
|
||||||
|
if (matchesShortcut(shortcuts.splitTerminalRight)) {
|
||||||
|
e.preventDefault();
|
||||||
|
createTerminal("horizontal", terminalState.activeSessionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split terminal down (Cmd+Shift+D / Ctrl+Shift+D)
|
||||||
|
if (matchesShortcut(shortcuts.splitTerminalDown)) {
|
||||||
|
e.preventDefault();
|
||||||
|
createTerminal("vertical", terminalState.activeSessionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close terminal (Cmd+W / Ctrl+W)
|
||||||
|
if (matchesShortcut(shortcuts.closeTerminal)) {
|
||||||
|
e.preventDefault();
|
||||||
|
killTerminal(terminalState.activeSessionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
}, [terminalState.isUnlocked, terminalState.activeSessionId, shortcuts]);
|
||||||
|
|
||||||
// Get a stable key for a panel
|
// Get a stable key for a panel
|
||||||
const getPanelKey = (panel: TerminalPanelContent): string => {
|
const getPanelKey = (panel: TerminalPanelContent): string => {
|
||||||
if (panel.type === "terminal") {
|
if (panel.type === "terminal") {
|
||||||
|
|||||||
@@ -160,6 +160,11 @@ export interface KeyboardShortcuts {
|
|||||||
cyclePrevProject: string;
|
cyclePrevProject: string;
|
||||||
cycleNextProject: string;
|
cycleNextProject: string;
|
||||||
addProfile: string;
|
addProfile: string;
|
||||||
|
|
||||||
|
// Terminal shortcuts
|
||||||
|
splitTerminalRight: string;
|
||||||
|
splitTerminalDown: string;
|
||||||
|
closeTerminal: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default keyboard shortcuts
|
// Default keyboard shortcuts
|
||||||
@@ -188,6 +193,11 @@ export const DEFAULT_KEYBOARD_SHORTCUTS: KeyboardShortcuts = {
|
|||||||
cyclePrevProject: "Q", // Global shortcut
|
cyclePrevProject: "Q", // Global shortcut
|
||||||
cycleNextProject: "E", // Global shortcut
|
cycleNextProject: "E", // Global shortcut
|
||||||
addProfile: "N", // Only active in profiles view
|
addProfile: "N", // Only active in profiles view
|
||||||
|
|
||||||
|
// Terminal shortcuts (only active in terminal view)
|
||||||
|
splitTerminalRight: "Cmd+D",
|
||||||
|
splitTerminalDown: "Cmd+Shift+D",
|
||||||
|
closeTerminal: "Cmd+W",
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ImageAttachment {
|
export interface ImageAttachment {
|
||||||
|
|||||||
Reference in New Issue
Block a user