fix(project-tree): refresh expanded excluded folders when files change

The watcher drops changes inside excluded and ignored folders so the index and
version control don't react to build output. That also kept an expanded `target`
from showing files a build added or removed. Those folders are now reported in
their own event, which only the Project view handles, and only for folders it has
loaded. Changes to existing files aren't reported, since the listing stays the same.
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-10-31 03:21:59 +08:00
1 джерело 00108a669e
коміт fcc36d67e7
7 files changed
+58 -7

No files matched your search

+10 -1
Переглянути файл
@@ -22,7 +22,15 @@ import { ProjectHeaderActions, useProjectHeaderMenu, useProjectTitleMenu } from
import { loadHomeDir } from "./home";
import { selectedNodes } from "./operations";
import { ProjectView } from "./ProjectView";
import { applyFsChange, initProjectTree, reloadAll, setChangedFiles, setOpenFiles, useProjectTree } from "./store";
import {
applyFsChange,
initProjectTree,
reloadAll,
reloadLoadedDirs,
setChangedFiles,
setOpenFiles,
useProjectTree,
} from "./store";
export function activate(): () => void {
loadHomeDir();
@@ -138,6 +146,7 @@ export function activate(): () => void {
.map((n) => n.path),
),
onIdeEvent("fsChanged", (e) => void applyFsChange(e)),
onIdeEvent("excludedDirsChanged", (e) => void reloadLoadedDirs(e.dirs)),
];
return () => {
disposers.reverse().forEach((d) => d());
+15
Переглянути файл
@@ -3,6 +3,7 @@ import { MemoryFs, setProjectFsForTests } from "./fs";
import { visibleInfo } from "./model";
import {
applyFsChange,
reloadLoadedDirs,
currentModel,
expandAll,
initProjectTree,
@@ -75,6 +76,20 @@ describe("lazy loading", () => {
});
});
describe("refresh of excluded folders", () => {
it("reloads only the folders the tree has loaded", async () => {
await loadDir(ROOT);
await loadDir("/p/docs");
const spy = vi.spyOn(fs, "readDir");
await reloadLoadedDirs(["/p/docs", "/p/target/never-opened"]);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith("/p/docs");
spy.mockRestore();
});
});
describe("refresh on fsChanged", () => {
it("reloads affected loaded folders and keeps expansion and selection", async () => {
await loadDir(ROOT);
+6
Переглянути файл
@@ -451,6 +451,12 @@ export async function applyFsChange(event: { created: string[]; modified: string
await Promise.all(plan.reload.map((p) => loadDir(p, true)));
}
/** Re-reads the folders among `dirs` the tree has loaded; the rest stay unread. */
export async function reloadLoadedDirs(dirs: readonly string[]) {
const { listings } = get();
await Promise.all(dirs.filter((p) => listings.has(p)).map((p) => loadDir(p, true)));
}
/** Re-reads every loaded folder (View › Reload from Disk). */
export async function reloadAll() {
const { listings } = get();