feat(workbench): Open files from Finder in the single-file window (#152)

On macOS, OpenIDEA is now listed under Finder's Open With for text and source files and for folders. It never becomes the default app for any of them: all document types are declared with rank Alternate, and only in tauri.macos.conf.json, so Windows and Linux installers register nothing.

Files opened from Finder, the Dock or a second instance share one routing path (plan_open). A file inside a local project that is already open, or still opening, goes to that project's window, choosing the deepest root when projects are nested. Any other file goes to the existing single-file window, or to a new one. A folder focuses the window that already has it open, otherwise it opens as a project. Paths that arrive before setup are queued and opened with the first launch.

The single-file window now closes with its last tab, restores its files the next time it opens, and only offers Open File and drop hints when empty. Also fixes a regression: reopening projects on startup no longer replaces a file opened at cold start.

Refs #128
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-10-28 23:56:23 +08:00
1 джерело 2d7726cf53
коміт 1d383e608c
12 files changed
+581 -42

No files matched your search

+19
Переглянути файл
@@ -65,6 +65,25 @@ describe("EditorController", () => {
expect(openFilePaths(useTabs.getState())).toEqual(["/p/a.ts", "/p/b.ts"]);
});
it("reopens the LightEdit files the next time a window switches to LightEdit", async () => {
ctrl = new EditorController(createMemoryBackend({ "/x/a.txt": "a", "/y/b.md": "b" }));
ctrl.start();
useProject.setState({ lightEdit: true });
await ctrl.openFile("/x/a.txt", { focus: false });
await ctrl.openFile("/y/b.md", { focus: false });
// The LightEdit window closes with its tabs open.
useProject.setState({ lightEdit: false });
expect(openFilePaths(useTabs.getState())).toEqual([]);
useProject.setState({ lightEdit: true });
expect(openFilePaths(useTabs.getState())).toEqual(["/x/a.txt", "/y/b.md"]);
// Closing every tab leaves nothing to reopen.
ctrl.closeEverything();
useProject.setState({ lightEdit: false });
useProject.setState({ lightEdit: true });
expect(openFilePaths(useTabs.getState())).toEqual([]);
useProject.setState({ lightEdit: false });
});
it("closes a tab by its input key", async () => {
ctrl = new EditorController(createMemoryBackend());
ctrl.start();