feat: 打开文件时自动展开目录树到该文件所在位置

场景:已打开文件夹 /project,通过 Ctrl+O 打开
      /project/src/components/App.tsx,目录树自动展开
      src/ 和 components/ 目录,高亮显示该文件。

实现:
- sidebarStore 新增 expandDirs(paths) 方法,批量展开目录
- Sidebar 组件监听 activeFilePath 变化
- 提取文件的所有父目录路径(从文件到 rootPath)
- 自动调用 expandDirs 展开所有父目录
This commit is contained in:
thzxx
2026-05-27 21:07:18 +08:00
parent 8db6396fc7
commit 679cd4b0a0
2 changed files with 32 additions and 0 deletions
@@ -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)
+13
View File
@@ -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 })
}))