mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 08:52:12 +00:00
Workspaces open several local project folders in one IDE session (File › New / Open / Manage Workspace…, or Attach when opening a project, which creates a workspace automatically for a plain project window). Member folders are the Project view roots and take part in indexing, Find in Files, Git, language servers, run configurations and builds; agent tasks choose which member they work in. Window › Merge All Project Windows groups project windows into one window with project tabs (switch, reorder, close, move to a new window), restored on reopen. Closes #241 Closes #198 Closes #286
56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
import { create } from "zustand";
|
|
import { call, commands, isTauri, onIdeEvent, type WindowTab } from "./ipc";
|
|
import { startupLaunchHandled, useProject } from "./project";
|
|
import { setContext } from "./context";
|
|
|
|
export const useWindowGroup = create<{ tabs: WindowTab[] }>(() => ({ tabs: [] }));
|
|
|
|
export function reorderedTabs(tabs: readonly WindowTab[], source: string, target: string): string[] {
|
|
const labels = tabs.map((tab) => tab.label);
|
|
const from = labels.indexOf(source);
|
|
const to = labels.indexOf(target);
|
|
if (from < 0 || to < 0 || from === to) return labels;
|
|
labels.splice(to, 0, labels.splice(from, 1)[0]!);
|
|
return labels;
|
|
}
|
|
|
|
export async function refreshWindowGroup() {
|
|
if (!isTauri()) return;
|
|
useWindowGroup.setState({ tabs: await call(commands.windowGroupCurrent()) });
|
|
setContext("windowGrouped", useWindowGroup.getState().tabs.length > 1);
|
|
}
|
|
|
|
export async function selectWindowTab(label: string) {
|
|
await call(commands.windowGroupSelect(label));
|
|
}
|
|
|
|
export async function cycleWindowTab(forward: boolean) {
|
|
const tabs = useWindowGroup.getState().tabs;
|
|
if (tabs.length < 2) return;
|
|
const index = tabs.findIndex((tab) => tab.current);
|
|
await selectWindowTab(tabs[(index + (forward ? 1 : -1) + tabs.length) % tabs.length]!.label);
|
|
}
|
|
|
|
export function installWindowGroups(): () => void {
|
|
if (!isTauri()) return () => {};
|
|
let disposed = false;
|
|
const refresh = () => void refreshWindowGroup().catch(console.warn);
|
|
const restore = async () => {
|
|
await startupLaunchHandled();
|
|
if (disposed || !useProject.getState().project) return;
|
|
await call(commands.windowGroupRestore());
|
|
if (!disposed) await refreshWindowGroup();
|
|
};
|
|
const offEvent = onIdeEvent("windowGroupsChanged", refresh);
|
|
const offProject = useProject.subscribe((state, prev) => {
|
|
if (state.project?.root !== prev.project?.root) void restore().catch(console.warn);
|
|
});
|
|
refresh();
|
|
void restore().catch(console.warn);
|
|
return () => {
|
|
disposed = true;
|
|
offEvent();
|
|
offProject();
|
|
};
|
|
}
|