diff options
Diffstat (limited to 'src/hooks')
| -rw-r--r-- | src/hooks/useCursorPosition.ts | 8 | ||||
| -rw-r--r-- | src/hooks/useKeyboard.ts | 95 |
2 files changed, 103 insertions, 0 deletions
diff --git a/src/hooks/useCursorPosition.ts b/src/hooks/useCursorPosition.ts new file mode 100644 index 0000000..479598d --- /dev/null +++ b/src/hooks/useCursorPosition.ts @@ -0,0 +1,8 @@ +import { useTabsStore } from '@/stores/useTabsStore' + +export function useCursorPosition() { + const cursorLine = useTabsStore((s) => s.cursorLine) + const cursorCol = useTabsStore((s) => s.cursorCol) + + return { cursorLine, cursorCol } +} diff --git a/src/hooks/useKeyboard.ts b/src/hooks/useKeyboard.ts new file mode 100644 index 0000000..b1ef390 --- /dev/null +++ b/src/hooks/useKeyboard.ts @@ -0,0 +1,95 @@ +import { useEffect } from 'react' +import { useTabsStore } from '@/stores/useTabsStore' +import { useFilesStore } from '@/stores/useFilesStore' +import { useLayoutStore } from '@/stores/useLayoutStore' +import { useCommandStore } from '@/stores/useCommandStore' + +export function useKeyboard() { + const activeTabId = useTabsStore((s) => s.activeTabId) + const saveFile = useTabsStore((s) => s.saveFile) + const closeTab = useTabsStore((s) => s.closeTab) + const tabs = useTabsStore((s) => s.tabs) + const setActiveTab = useTabsStore((s) => s.setActiveTab) + const createUntitledFile = useTabsStore((s) => s.createUntitledFile) + const pickAndOpenFile = useTabsStore((s) => s.pickAndOpenFile) + const openFolder = useFilesStore((s) => s.openFolder) + const toggleSidePanel = useLayoutStore((s) => s.toggleSidePanel) + const toggleCommandPalette = useCommandStore((s) => s.toggle) + + useEffect(() => { + async function handleKeyDown(e: KeyboardEvent) { + const isMod = e.ctrlKey || e.metaKey + if (!isMod) return + + if (e.key === 'p') { + e.preventDefault() + toggleCommandPalette() + return + } + + if (e.key === 'n') { + e.preventDefault() + createUntitledFile() + return + } + + if (e.key === 'o' && e.shiftKey) { + e.preventDefault() + openFolder() + return + } + + if (e.key === 'o') { + e.preventDefault() + pickAndOpenFile() + return + } + + if (e.key === 's') { + e.preventDefault() + if (activeTabId) saveFile(activeTabId) + return + } + + if (e.key === 'w') { + e.preventDefault() + if (activeTabId) closeTab(activeTabId) + return + } + + if (e.key === 'b') { + e.preventDefault() + toggleSidePanel() + return + } + + if (e.shiftKey && e.key === 'Tab') { + e.preventDefault() + if (tabs.length > 1 && activeTabId) { + const idx = tabs.findIndex((t) => t.id === activeTabId) + const prevIdx = idx === 0 ? tabs.length - 1 : idx - 1 + setActiveTab(tabs[prevIdx].id) + } + return + } + + if (e.key === 'Tab' && !e.shiftKey) { + e.preventDefault() + if (tabs.length > 1 && activeTabId) { + const idx = tabs.findIndex((t) => t.id === activeTabId) + const nextIdx = idx === tabs.length - 1 ? 0 : idx + 1 + setActiveTab(tabs[nextIdx].id) + } + return + } + + if (e.key === 'k' && e.shiftKey) { + e.preventDefault() + openFolder() + } + } + + window.addEventListener('keydown', handleKeyDown, true) + return () => window.removeEventListener('keydown', handleKeyDown, true) + }, [activeTabId, saveFile, closeTab, tabs, setActiveTab, createUntitledFile, pickAndOpenFile, openFolder, toggleSidePanel, toggleCommandPalette]) +} |