refactor: 删除自定义搜索,统一使用 CodeMirror 6 搜索

删除文件:
- SearchBar/SearchBar.tsx — 自定义搜索栏组件
- stores/searchStore.ts — 自定义搜索状态管理
- lib/searchEngine.ts — 自定义搜索匹配引擎
- types/search.ts — 搜索相关类型定义

清理代码:
- App.tsx:移除 SearchBar 导入和渲染
- useKeyboard.ts:移除 searchStore 引用和搜索快捷键
- Editor.tsx:移除 searchStore 引用和搜索逻辑
- types/index.ts:移除 search 类型导出
- global.css:删除旧搜索栏样式(~113 行)

CodeMirror 6 搜索面板移到顶部:
- .cm-panels { top: 0; bottom: auto; }
- .cm-panels-bottom { top: 0; bottom: auto; }

快捷键(CodeMirror 内置):
- Ctrl+F 搜索
- Ctrl+H 替换
- Enter/Shift+Enter 下一个/上一个
- Alt+C 大小写
- Alt+R 正则
This commit is contained in:
thzxx
2026-05-27 23:54:55 +08:00
parent e40a8bd88e
commit d57a2b2aac
9 changed files with 19 additions and 425 deletions
-12
View File
@@ -1,13 +1,11 @@
import { useEffect, useCallback } from 'react'
import { useTabStore } from '../stores/tabStore'
import { useEditorStore } from '../stores/editorStore'
import { useSearchStore } from '../stores/searchStore'
import type { ViewMode } from '../types/settings'
export function useKeyboard(handleOpenFile: () => void, handleSave: () => void, handleSaveAs: () => void) {
const setViewMode = useEditorStore(s => s.setViewMode)
// M-08: 使用 getState() 而非依赖 tabs/activeTabId 等频繁变化的值
const handleKeydown = useCallback((e: KeyboardEvent) => {
const isCtrl = e.ctrlKey || e.metaKey
@@ -18,7 +16,6 @@ export function useKeyboard(handleOpenFile: () => void, handleSave: () => void,
if (isCtrl && e.key === '2') { e.preventDefault(); setViewMode('editor'); return }
if (isCtrl && e.key === '3') { e.preventDefault(); setViewMode('preview'); return }
// M-08: 通过 getState() 读取最新状态
const tabState = useTabStore.getState()
if (isCtrl && e.key === 't') { e.preventDefault(); tabState.createTab(null, ''); return }
if (isCtrl && e.key === 'w') {
@@ -47,15 +44,6 @@ export function useKeyboard(handleOpenFile: () => void, handleSave: () => void,
}
return
}
// Search & Replace
const searchState = useSearchStore.getState()
if (isCtrl && e.key === 'f') { e.preventDefault(); searchState.setVisible(true); searchState.setShowReplace(false); return }
if (isCtrl && e.key === 'h') { e.preventDefault(); searchState.setVisible(true); searchState.setShowReplace(true); return }
if (e.key === 'Escape' && searchState.isVisible) { e.preventDefault(); searchState.close(); return }
if (e.altKey && e.key === 'c') { e.preventDefault(); searchState.toggleCaseSensitive(); return }
if (e.altKey && e.key === 'r') { e.preventDefault(); searchState.toggleRegex(); return }
if (isCtrl && e.shiftKey && e.key === 'G') { e.preventDefault(); searchState.findPrev(); return }
}, [handleOpenFile, handleSave, handleSaveAs, setViewMode])
useEffect(() => {