diff --git a/src/main.ts b/src/main.ts index 9086b2d..8668a22 100644 --- a/src/main.ts +++ b/src/main.ts @@ -366,16 +366,29 @@ export default class WorkspacesPlus extends Plugin { if (!this.isNativePluginEnabled) return; this.setWorkspaceName(); this.registerWorkspaceHotkeys(); + if (!customSettings) { customSettings = this.utils.getWorkspaceSettings(workspaceName); } else { customSettings = this.utils.setWorkspaceSettings(workspaceName, customSettings); } + + // Capture currently open files if tracking is enabled + if (this.settings.trackOpenFiles) { + const currentWorkspace = this.workspacePlugin.workspaces[workspaceName]; + if (currentWorkspace) { + const openFiles = this.utils.captureOpenFiles(currentWorkspace); + customSettings.trackedFiles = openFiles; + } + } + if (this.settings.workspaceSettings && this.utils.isMode(workspaceName)) { customSettings.app = this.app.vault.config; } + let explorerFoldState = await this.app.loadLocalStorage("file-explorer-unfold"); if (explorerFoldState) customSettings.explorerFoldState = explorerFoldState; + this.workspacePlugin.saveData(); }; @@ -525,24 +538,33 @@ export default class WorkspacesPlus extends Plugin { if (!workspaceName || !plugin.isNativePluginEnabled) return; plugin.setLoadingStatus(); let result; + if (plugin.settings.workspaceSettings && plugin.utils.isMode(workspaceName)) { // if the workspace being loaded is a mode, invoke the mode loader let modeName = workspaceName; workspaceName = plugin.utils.activeWorkspace; result = plugin.utils.loadMode(workspaceName, modeName); } else { - // result = old.call(this, workspaceName, ...etc); const workspace = this.workspaces[workspaceName]; if (workspace) { - // TODO: Ensure this stays in sync with the native Obsidian function this.activeWorkspace = workspaceName; try { - plugin.utils.applyFileOverrides(workspaceName, workspace).then(() => { - this.app.workspace.changeLayout(workspace); - this.saveData(); - }); - } catch { - console.log("failed to apply overrides"); + // Restore tracked files along with overrides + if (plugin.settings.trackOpenFiles) { + plugin.utils.restoreOpenFiles(workspaceName, workspace).then(() => { + plugin.utils.applyFileOverrides(workspaceName, workspace).then(() => { + this.app.workspace.changeLayout(workspace); + this.saveData(); + }); + }); + } else { + plugin.utils.applyFileOverrides(workspaceName, workspace).then(() => { + this.app.workspace.changeLayout(workspace); + this.saveData(); + }); + } + } catch (e) { + console.log("failed to restore files:", e); this.app.workspace.changeLayout(workspace); this.saveData(); } @@ -555,4 +577,4 @@ export default class WorkspacesPlus extends Plugin { }) ); } -} +} \ No newline at end of file diff --git a/src/settings.ts b/src/settings.ts index 8bbe5de..f0b4567 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -17,6 +17,7 @@ export class WorkspacesPlusSettings { workspaceSwitcherRibbon: boolean; modeSwitcherRibbon: boolean; replaceNativeRibbon: boolean; + trackOpenFiles: boolean; } export const DEFAULT_SETTINGS: WorkspacesPlusSettings = { @@ -33,6 +34,7 @@ export const DEFAULT_SETTINGS: WorkspacesPlusSettings = { workspaceSwitcherRibbon: false, modeSwitcherRibbon: false, replaceNativeRibbon: false, + trackOpenFiles: true, }; function getChildIds (split: any, leafs: any[] = []): any[] { @@ -169,6 +171,19 @@ export class WorkspacesPlusSettingsTab extends PluginSettingTab { }) ); + new Setting(containerEl) + .setName("Automatically track and restore open files") + .setDesc( + `When enabled, workspaces will remember which files were open and restore them when you switch back. ` + + `This preserves your exact layout and open notes across workspace switches.` + ) + .addToggle(toggle => + toggle.setValue(this.plugin.settings.trackOpenFiles).onChange(value => { + this.plugin.settings.trackOpenFiles = value; + this.plugin.saveData(this.plugin.settings); + }) + ); + new Setting(containerEl) .setName("Respect system dark mode setting") .setClass("requires-workspace-modes") @@ -333,4 +348,4 @@ export class WorkspacesPlusSettingsTab extends PluginSettingTab { // "is-collapsed", // !setting.settingEl.hasClass("is-collapsed") // ); -// }); +// }); \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index aa95f18..edbd484 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -205,6 +205,47 @@ export default class Utils { } } + captureOpenFiles(workspace: any): { [key: string]: string } { + const openFiles: { [key: string]: string } = {}; + + function extractFiles(split: any): void { + if (split.type === "leaf") { + const file = split.state?.state?.file; + if (file && split.id) { + openFiles[split.id] = file; + } + } else if (split.type === "split" || split.type === "tabs") { + split.children?.forEach((child: any) => { + extractFiles(child); + }); + } + } + + if (workspace?.main) { + extractFiles(workspace.main); + } + + return openFiles; + } + + async restoreOpenFiles(workspaceName: string, workspace: any): Promise { + const workspaceSettings = this.getWorkspaceSettings(workspaceName); + const trackedFiles = workspaceSettings?.trackedFiles; + + if (!trackedFiles) return; + + for (const [leafId, filePath] of Object.entries(trackedFiles)) { + const file = this.app.vault.getAbstractFileByPath(normalizePath(filePath as string)) as TFile; + if (file) { + // FIle is found, set it + this.setChildId(workspace.main, leafId, file.path); + } else { + // File not found, is not found, create a new one to keep layout intact + this.setChildId(workspace.main, leafId, null); + } + } + } + getModeSettings (name: string) { if (this.isMode(name)) return this.getWorkspaceSettings(name); } @@ -257,4 +298,4 @@ export default class Utils { .replace(/{{\s*yesterday\s*}}/gi, date.clone().subtract(1, "day").format(dateFormat)) .replace(/{{\s*tomorrow\s*}}/gi, date.clone().add(1, "d").format(dateFormat))); } -} +} \ No newline at end of file