fix(editor): open the launched file when the window restores its last tabs (#1594)

Starting OpenIDEA with a file showed the last session's tabs without the file: restoring the saved tabs counted as the user activating another tab, so the pending open of the launched file was dropped as superseded. Restoring a session no longer counts as an activation; the launched file opens next to the restored tabs and becomes active (also for a file opened with its project at startup).
This commit is contained in:
l0ng-ai
2026-11-06 00:58:18 +08:00
committed by GitHub
parent 7a715758a6
commit f68d8f499a
2 changed files with 27 additions and 1 deletions
+18
View File
@@ -262,6 +262,24 @@ describe("EditorController", () => {
useProject.setState({ lightEdit: false });
});
it("opens a file requested while the LightEdit session is being restored", async () => {
ctrl = new EditorController(createMemoryBackend({ "/x/a.txt": "a", "/y/b.md": "b", "/z/launch.lua": "l" }));
ctrl.start();
useProject.setState({ lightEdit: true });
await ctrl.openFile("/x/a.txt", { focus: false });
await ctrl.openFile("/y/b.md", { focus: false });
useProject.setState({ lightEdit: false });
// A launch with a file path: LightEdit starts and the file opens before the old tabs are back.
useProject.setState({ lightEdit: true });
await ctrl.openFile("/z/launch.lua", { focus: false });
expect(openFilePaths(useTabs.getState())).toEqual(["/x/a.txt", "/y/b.md", "/z/launch.lua"]);
const s = useTabs.getState();
const active = s.panes[s.activePane]!;
expect(active.tabs.find((t) => t.id === active.active)?.input.path).toBe("/z/launch.lua");
await ctrl.closeEverything();
useProject.setState({ lightEdit: false });
});
it("closes a tab by its input key", async () => {
ctrl = new EditorController(createMemoryBackend());
ctrl.start();
+9 -1
View File
@@ -237,6 +237,8 @@ export class EditorController implements SlotHost {
private selectionRequests = new Map<string, number>();
private activationGeneration = 0;
private admitting = false;
/** Tabs restored from a saved session: not a user's activation, so a pending open still activates its tab. */
private restoring = false;
private closeRequests = 0;
private projectTransition: Promise<void> = Promise.resolve();
@@ -269,6 +271,7 @@ export class EditorController implements SlotHost {
prevTabs = s;
if (
!this.admitting &&
!this.restoring &&
(s.activePane !== prev.activePane || s.panes[s.activePane]?.active !== prev.panes[prev.activePane]?.active)
)
++this.activationGeneration;
@@ -486,7 +489,12 @@ export class EditorController implements SlotHost {
pane.tabs = pane.tabs.map((tab) => (documentLifecycle(tab.input, kinds) ? { ...tab, preview: false } : tab));
this.restoredViews = new Map(Object.entries(session.files));
this.restoredTabs = new Set(Object.values(state.panes).flatMap((p) => p.tabs.map((t) => t.id)));
useTabs.setState(state, true);
this.restoring = true;
try {
useTabs.setState(state, true);
} finally {
this.restoring = false;
}
for (const pane of Object.values(state.panes)) if (pane.active) void this.ensureSlot(pane.active);
}