Файли
openidea/src/workbench/activate.ts
T
l0ng-ai 2d7726cf53 feat(workbench): Edit single files without opening a project (#145)
Files can now be opened without a project. A file dropped on the Welcome screen, picked with File › Open File…, or passed on the command line or to a second instance opens in a lightweight window: editor tabs only, with no project tree, indexing, language servers, VCS or project tool windows. Syntax highlighting, find, save, undo and Local History still work. More files opened later join the same window as new tabs. Open as Project in the status bar opens the file's directory as a full project, following the open-project policy, and reopens the file there.

Backend: a light session reuses Project with an unindexed index, no LSP or VCS, and a flat watch on each opened file's directory. It is never reused as a project for the same root. Previously a file passed at launch opened its parent directory as a project.
2026-10-28 22:06:35 +08:00

91 рядки
3.4 KiB
TypeScript

/**
* Shell services and built-in contributions. Call before `activateFeatures()`
* so features can rely on the tool window and notification services.
*/
import { setContext } from "@/platform/context";
import { useProject } from "@/platform/project";
import {
provideNotificationService,
provideToolWindowService,
registerOverlay,
registerStatusItem,
registerToolWindow,
} from "./contributions";
import { installBrowserGuards } from "./browserGuards";
import { installDistractionFree } from "./distractionFree";
import { installFileDrop } from "./fileDrop";
import { installFocusTracking } from "./focus";
import { clearNotifications, installNotifyEvents, notificationServiceImpl } from "./notificationStore";
import {
NOTIFICATIONS_TOOL_WINDOW,
NotificationsHeaderActions,
NotificationsToolWindow,
useUnreadNotifications,
} from "./Notifications";
import { loadPlatformInfo } from "@/platform/platformInfo";
import { registerShellActions } from "./shellActions";
import { MainToolbarDialogHost } from "./MainToolbarDialog";
import { StatusInfo, TaskStatus } from "./StatusBar";
import { installTaskEvents } from "./tasks";
import { installToolWindowActions } from "./toolwindows/actions";
import {
installToolWindowLayoutSync,
loadToolWindowLayout,
setFocusedToolWindow,
toolWindowServiceImpl,
} from "./toolwindows/store";
export function activateWorkbench(): () => void {
provideToolWindowService(toolWindowServiceImpl);
provideNotificationService(notificationServiceImpl);
void loadPlatformInfo();
// Synchronous so the frame's first render after opening already has the project's layout.
const onProject = (root: string | null) => {
setContext("projectOpen", root !== null);
setContext("lightEdit", useProject.getState().lightEdit);
if (root !== null) loadToolWindowLayout(root);
};
onProject(useProject.getState().project?.root ?? null);
const unsubProject = useProject.subscribe((s, prev) => {
if (s.project?.root === prev.project?.root && s.lightEdit === prev.lightEdit) return;
// The previous project's notifications (and their actions) no longer apply.
if (prev.project) clearNotifications();
onProject(s.project?.root ?? null);
});
const disposers = [
unsubProject,
registerShellActions(),
installToolWindowActions(),
installToolWindowLayoutSync(),
installDistractionFree(),
installFocusTracking(setFocusedToolWindow),
installTaskEvents(),
installNotifyEvents(),
installBrowserGuards(),
installFileDrop(),
registerOverlay({ id: "workbench.customizeToolbar", component: MainToolbarDialogHost }),
registerStatusItem({ id: "workbench.tasks", align: "right", priority: 0, component: TaskStatus, lightEdit: true }),
registerStatusItem({ id: "workbench.info", align: "left", priority: 5, component: StatusInfo, lightEdit: true }),
registerToolWindow({
id: NOTIFICATIONS_TOOL_WINDOW,
title: "Notifications",
icon: "bell",
anchor: "right",
order: 0,
component: NotificationsToolWindow,
headerActions: NotificationsHeaderActions,
useBadge: useUnreadNotifications,
}),
];
return () => disposers.reverse().forEach((d) => d());
}
/** Shell services for a secondary window (Settings): notifications, platform info, browser guards. */
export function activateSecondaryWindow(): () => void {
provideNotificationService(notificationServiceImpl);
void loadPlatformInfo();
return installBrowserGuards();
}