feat: 打开文件时自动展开目录树到该文件所在位置
场景:已打开文件夹 /project,通过 Ctrl+O 打开
/project/src/components/App.tsx,目录树自动展开
src/ 和 components/ 目录,高亮显示该文件。
实现:
- sidebarStore 新增 expandDirs(paths) 方法,批量展开目录
- Sidebar 组件监听 activeFilePath 变化
- 提取文件的所有父目录路径(从文件到 rootPath)
- 自动调用 expandDirs 展开所有父目录
This commit is contained in:
@@ -17,10 +17,29 @@ export function Sidebar() {
|
||||
const setRootPath = useSidebarStore(s => s.setRootPath)
|
||||
const setTree = useSidebarStore(s => s.setTree)
|
||||
const isVisible = useSidebarStore(s => s.isVisible)
|
||||
const expandDirs = useSidebarStore(s => s.expandDirs)
|
||||
|
||||
// 计算当前活动标签的文件路径(用于文件树高亮)
|
||||
const activeFilePath = tabs.find(t => t.id === activeTabId)?.filePath ?? null
|
||||
|
||||
// 自动展开到活动文件所在的目录
|
||||
useEffect(() => {
|
||||
if (!activeFilePath || !rootPath) return
|
||||
if (!activeFilePath.startsWith(rootPath)) return
|
||||
|
||||
// 提取文件的所有父目录路径
|
||||
const dirsToExpand: string[] = []
|
||||
let dir = activeFilePath.replace(/[/\\][^/\\]+$/, '') // 移除文件名
|
||||
while (dir && dir.length >= rootPath.length && dir !== rootPath) {
|
||||
dirsToExpand.push(dir)
|
||||
dir = dir.replace(/[/\\][^/\\]+$/, '')
|
||||
}
|
||||
|
||||
if (dirsToExpand.length > 0) {
|
||||
expandDirs(dirsToExpand)
|
||||
}
|
||||
}, [activeFilePath, rootPath, expandDirs])
|
||||
|
||||
const [isResizing, setIsResizing] = useState(false)
|
||||
const sidebarRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ interface SidebarState {
|
||||
setRootPath: (path: string | null) => void
|
||||
setTree: (tree: FileNode[]) => void
|
||||
toggleDir: (path: string) => void
|
||||
expandDirs: (paths: string[]) => void
|
||||
setSidebarWidth: (width: number) => void
|
||||
}
|
||||
|
||||
@@ -35,5 +36,17 @@ export const useSidebarStore = create<SidebarState>((set) => ({
|
||||
}
|
||||
return { expandedDirs: newSet }
|
||||
}),
|
||||
expandDirs: (paths) =>
|
||||
set(state => {
|
||||
const newSet = new Set(state.expandedDirs)
|
||||
let changed = false
|
||||
for (const p of paths) {
|
||||
if (!newSet.has(p)) {
|
||||
newSet.add(p)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
return changed ? { expandedDirs: newSet } : state
|
||||
}),
|
||||
setSidebarWidth: (width) => set({ sidebarWidth: width })
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user