Mercurial > obsidian-remember-file-state
annotate src/main.ts @ 43:7e981d54a055
Support state persistence between sessions
There is now an option to save/load file states on disk.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 20 Sep 2023 22:40:25 -0700 |
parents | aa9bc7754c5d |
children | fae202d7b3de |
rev | line source |
---|---|
0 | 1 import { |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
2 App, |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
3 Editor, |
0 | 4 MarkdownView, |
27
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
5 Modal, |
0 | 6 OpenViewState, |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
7 Plugin, |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
8 TAbstractFile, |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
9 TFile, |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
10 Tasks, |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
11 View, |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
12 WorkspaceLeaf |
0 | 13 } from 'obsidian'; |
14 | |
15 import { | |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
16 EditorView |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
17 } from '@codemirror/view'; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
18 |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
19 import { |
2 | 20 EditorState, |
0 | 21 EditorSelection |
22 } from '@codemirror/state'; | |
23 | |
24 import { | |
25 around | |
26 } from 'monkey-around'; | |
27 | |
28 import { | |
29 DEFAULT_SETTINGS, | |
30 RememberFileStatePluginSettings, | |
31 RememberFileStatePluginSettingTab | |
32 } from './settings'; | |
33 | |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
34 declare var app: App; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
35 |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
36 // Interface for CM6 editor view |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
37 interface EditorWithCM6 extends Editor { |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
38 cm: EditorView |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
39 }; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
40 |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
41 // View with unique ID |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
42 interface ViewWithID extends View { |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
43 __uniqueId: number |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
44 }; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
45 |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
46 // Scroll info interface |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
47 interface ScrollInfo { |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
48 top: number, left: number |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
49 }; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
50 |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
51 interface StateData { |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
52 selection: EditorSelection, |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
53 scrollInfo: ScrollInfo |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
54 }; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
55 |
0 | 56 // Interface for a file state. |
57 interface RememberedFileState { | |
58 path: string; | |
59 lastSavedTime: number; | |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
60 stateData: StateData; |
0 | 61 } |
62 | |
63 // Interface for all currently remembered file states. | |
64 interface RememberFileStatePluginData { | |
11
6f7f35af6335
Better type information for the plugin data
Ludovic Chabant <ludovic@chabant.com>
parents:
8
diff
changeset
|
65 rememberedFiles: Record<string, RememberedFileState>; |
0 | 66 } |
67 | |
68 // Default empty list of remembered file states. | |
69 const DEFAULT_DATA: RememberFileStatePluginData = { | |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
70 rememberedFiles: {} |
0 | 71 }; |
72 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
73 // Where to save the states database. |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
74 const STATE_DB_PATH: string = '.obsidian/plugins/obsidian-remember-file-state/states.json'; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
75 |
27
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
76 // Simple warning message. |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
77 class WarningModal extends Modal { |
29
66cada11efb8
Fix typescript warnings
Ludovic Chabant <ludovic@chabant.com>
parents:
28
diff
changeset
|
78 title: string = ""; |
66cada11efb8
Fix typescript warnings
Ludovic Chabant <ludovic@chabant.com>
parents:
28
diff
changeset
|
79 message: string = ""; |
66cada11efb8
Fix typescript warnings
Ludovic Chabant <ludovic@chabant.com>
parents:
28
diff
changeset
|
80 |
27
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
81 constructor(app: App, title: string, message: string) { |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
82 super(app) |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
83 this.title = title; |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
84 this.message = message; |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
85 } |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
86 onOpen() { |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
87 this.contentEl.createEl('h2', {text: this.title}); |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
88 this.contentEl.createEl('p', {text: this.message}); |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
89 } |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
90 }; |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
91 |
0 | 92 export default class RememberFileStatePlugin extends Plugin { |
93 settings: RememberFileStatePluginSettings; | |
94 data: RememberFileStatePluginData; | |
95 | |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
96 // Don't restore state on the next file being opened. |
0 | 97 private _suppressNextFileOpen: boolean = false; |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
98 // Next unique ID to identify views without keeping references to them. |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
99 private _nextUniqueViewId: number = 0; |
0 | 100 |
28
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
101 // Remember last open file in each view. |
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
102 private _lastOpenFiles: Record<string, string> = {}; |
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
103 |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
104 // Functions to unregister any monkey-patched view hooks on plugin unload. |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
105 private _viewUninstallers: Record<string, Function> = {}; |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
106 // Functions to unregister any global callbacks on plugin unload. |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
107 private _globalUninstallers: Function[] = []; |
0 | 108 |
109 async onload() { | |
35
42ff65e35f4f
More standardized logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
29
diff
changeset
|
110 console.log("RememberFileState: loading plugin"); |
0 | 111 |
112 await this.loadSettings(); | |
113 | |
114 this.data = Object.assign({}, DEFAULT_DATA); | |
115 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
116 await this.readStateDatabase(STATE_DB_PATH); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
117 |
0 | 118 this.registerEvent(this.app.workspace.on('file-open', this.onFileOpen)); |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
119 this.registerEvent(this.app.workspace.on('quit', this.onAppQuit)); |
0 | 120 this.registerEvent(this.app.vault.on('rename', this.onFileRename)); |
121 this.registerEvent(this.app.vault.on('delete', this.onFileDelete)); | |
122 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
123 this.app.workspace.onLayoutReady(() => { this.onLayoutReady(); }); |
0 | 124 |
125 const _this = this; | |
126 var uninstall = around(this.app.workspace, { | |
127 openLinkText: function(next) { | |
128 return async function( | |
129 linktext: string, sourcePath: string, | |
130 newLeaf?: boolean, openViewState?: OpenViewState) { | |
131 // When opening a link, we don't want to restore the | |
132 // scroll position/selection/etc because there's a | |
133 // good chance we want to show the file back at the | |
134 // top, or we're going straight to a specific block. | |
135 _this._suppressNextFileOpen = true; | |
136 return await next.call( | |
137 this, linktext, sourcePath, newLeaf, openViewState); | |
138 }; | |
139 } | |
140 }); | |
141 this._globalUninstallers.push(uninstall); | |
142 | |
143 this.addSettingTab(new RememberFileStatePluginSettingTab(this.app, this)); | |
27
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
144 |
29
66cada11efb8
Fix typescript warnings
Ludovic Chabant <ludovic@chabant.com>
parents:
28
diff
changeset
|
145 if ((this.app.vault as any).getConfig('legacyEditor') !== false) { |
27
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
146 new WarningModal( |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
147 this.app, |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
148 "Legacy Editor Not Supported", |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
149 "The 'Remember File State' plugin works only with the new editor. Please turn off 'Legacy Editor' in the options." |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
150 ).open(); |
3d0ac176118f
Show warning message if using the plugin with the legacy editor
Ludovic Chabant <ludovic@chabant.com>
parents:
23
diff
changeset
|
151 } |
0 | 152 } |
153 | |
154 onunload() { | |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
155 // Run view uninstallers on all current views. |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
156 var numViews: number = 0; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
157 this.app.workspace.getLeavesOfType("markdown").forEach( |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
158 (leaf: WorkspaceLeaf) => { |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
159 const filePath = (leaf.view as MarkdownView).file.path; |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
160 const viewId = this.getUniqueViewId(leaf.view as ViewWithID); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
161 if (viewId != undefined) { |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
162 var uninstaller = this._viewUninstallers[viewId]; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
163 if (uninstaller) { |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
164 console.debug(`RememberFileState: uninstalling hooks for view ${viewId}`, filePath); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
165 uninstaller(leaf.view); |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
166 ++numViews; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
167 } else { |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
168 console.debug("RememberFileState: found markdown view without an uninstaller!", filePath); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
169 } |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
170 // Clear the ID so we don't get confused if the plugin |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
171 // is re-enabled later. |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
172 this.clearUniqueViewId(leaf.view as ViewWithID); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
173 } else { |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
174 console.debug("RememberFileState: found markdown view without an ID!", filePath); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
175 } |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
176 }); |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
177 console.debug(`RememberFileState: unregistered ${numViews} view callbacks`); |
0 | 178 this._viewUninstallers = {}; |
28
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
179 this._lastOpenFiles = {}; |
0 | 180 |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
181 // Run global unhooks. |
0 | 182 this._globalUninstallers.forEach((cb) => cb()); |
183 } | |
184 | |
185 async loadSettings() { | |
186 this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); | |
187 } | |
188 | |
189 async saveSettings() { | |
190 await this.saveData(this.settings); | |
191 } | |
192 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
193 private readonly onLayoutReady = function() { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
194 this.app.workspace.getLeavesOfType("markdown").forEach( |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
195 (leaf: WorkspaceLeaf) => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
196 var view = leaf.view as MarkdownView; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
197 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
198 // On startup, assign unique IDs to views and register the |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
199 // unload callback to remember their state. |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
200 this.registerOnUnloadFile(view); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
201 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
202 // Also remember which file is opened in which view. |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
203 const viewId = this.getUniqueViewId(view as ViewWithID); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
204 if (viewId != undefined) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
205 this._lastOpenFiles[viewId] = view.file.path; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
206 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
207 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
208 // Restore state for each opened pane on startup. |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
209 const existingFile = this.data.rememberedFiles[view.file.path]; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
210 if (existingFile) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
211 const savedStateData = existingFile.stateData; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
212 console.debug("RememberFileState: restoring saved state for:", view.file.path, savedStateData); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
213 this.restoreState(savedStateData, view); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
214 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
215 }); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
216 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
217 |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
218 private readonly registerOnUnloadFile = function(view: MarkdownView) { |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
219 var filePath = view.file.path; |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
220 var viewId = this.getUniqueViewId(view as unknown as ViewWithID, true); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
221 if (viewId in this._viewUninstallers) { |
0 | 222 return; |
223 } | |
224 | |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
225 console.debug(`RememberFileState: registering callback on view ${viewId}`, filePath); |
0 | 226 const _this = this; |
227 var uninstall = around(view, { | |
228 onUnloadFile: function(next) { | |
229 return async function (unloaded: TFile) { | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
230 _this.rememberFileState(this, unloaded); |
0 | 231 return await next.call(this, unloaded); |
232 }; | |
233 } | |
234 }); | |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
235 this._viewUninstallers[viewId] = uninstall; |
0 | 236 |
237 view.register(() => { | |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
238 // Don't hold a reference to this plugin here because this callback |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
239 // will outlive it if it gets deactivated. So let's find it, and |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
240 // do nothing if we don't find it. |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
241 // @ts-ignore |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
242 var plugin: RememberFileStatePlugin = app.plugins.getPlugin("obsidian-remember-file-state"); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
243 if (plugin) { |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
244 console.debug(`RememberFileState: unregistering view ${viewId} callback`, filePath); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
245 delete plugin._viewUninstallers[viewId]; |
28
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
246 delete plugin._lastOpenFiles[viewId]; |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
247 uninstall(); |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
248 } else { |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
249 console.debug( |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
250 "RememberFileState: plugin was unloaded, ignoring unregister"); |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
251 } |
0 | 252 }); |
253 } | |
254 | |
255 private readonly onFileOpen = async ( | |
256 openedFile: TFile | |
257 ): Promise<void> => { | |
258 // If `openedFile` is null, it's because the last pane was closed | |
259 // and there is now an empty pane. | |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
260 if (!openedFile) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
261 return; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
262 } |
0 | 263 |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
264 var shouldSuppressThis: bool = this._suppressNextFileOpen; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
265 this._suppressNextFileOpen = false; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
266 if (shouldSuppressThis) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
267 console.debug("RememberFileState: not restoring file state because of explicit suppression"); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
268 return; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
269 } |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
270 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
271 // Check that the file is handled by a markdown editor, which is the |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
272 // only editor we support for now. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
273 var activeView: MarkdownView = this.app.workspace.getActiveViewOfType(MarkdownView); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
274 if (!activeView) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
275 console.debug("RememberFileState: not restoring file state, it's not a markdown view"); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
276 return; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
277 } |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
278 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
279 this.registerOnUnloadFile(activeView); |
28
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
280 |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
281 // Check if this is a genuine file open, and not returning to pane that |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
282 // already had this file opened in it. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
283 var isRealFileOpen = true; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
284 const viewId = this.getUniqueViewId(activeView as unknown as ViewWithID); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
285 if (viewId != undefined) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
286 const lastOpenFileInView = this._lastOpenFiles[viewId]; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
287 isRealFileOpen = (lastOpenFileInView != openedFile.path); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
288 this._lastOpenFiles[viewId] = openedFile.path; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
289 } |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
290 if (!isRealFileOpen) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
291 console.debug("RememberFileState: not restoring file state, that file was already open in this pane."); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
292 return; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
293 } |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
294 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
295 // Restore the state! |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
296 try { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
297 const existingFile = this.data.rememberedFiles[openedFile.path]; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
298 if (existingFile) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
299 const savedStateData = existingFile.stateData; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
300 console.debug("RememberFileState: restoring saved state for:", openedFile.path, savedStateData); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
301 this.restoreState(savedStateData, activeView); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
302 } else { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
303 // If we don't have any saved state for this file, let's see if |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
304 // it's opened in another pane. If so, restore that. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
305 const otherPaneState = this.findFileStateFromOtherPane(openedFile, activeView); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
306 if (otherPaneState) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
307 console.debug("RememberFileState: restoring other pane state for:", openedFile.path, otherPaneState); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
308 this.restoreState(otherPaneState, activeView); |
7
b1cb0474bb18
Fix possible crash when an opened file isn't a markdown file
Ludovic Chabant <ludovic@chabant.com>
parents:
6
diff
changeset
|
309 } |
0 | 310 } |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
311 } catch (err) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
312 console.error("RememberFileState: couldn't restore file state: ", err); |
0 | 313 } |
314 } | |
315 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
316 private readonly rememberFileState = async (view: MarkdownView, file?: TFile): Promise<void> => { |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
317 const stateData = this.getState(view); |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
318 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
319 if (file === undefined) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
320 file = view.file; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
321 } |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
322 var existingFile = this.data.rememberedFiles[file.path]; |
0 | 323 if (existingFile) { |
324 existingFile.lastSavedTime = Date.now(); | |
325 existingFile.stateData = stateData; | |
326 } else { | |
327 let newFileState = { | |
328 path: file.path, | |
329 lastSavedTime: Date.now(), | |
330 stateData: stateData | |
331 }; | |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
332 this.data.rememberedFiles[file.path] = newFileState; |
0 | 333 |
36 | 334 // If we need to keep the number of remembered files under a maximum, |
0 | 335 // do it now. |
336 this.forgetExcessFiles(); | |
337 } | |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
338 console.debug("RememberFileState: remembered state for:", file.path, stateData); |
0 | 339 } |
340 | |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
341 private readonly getState = function(view: MarkdownView) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
342 // Save scrolling position (Obsidian API only gives vertical position). |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
343 const scrollInfo = {top: view.currentMode.getScroll(), left: 0}; |
37
8be02002ed66
Use Obsidian's view APIs for scrolling state
Ludovic Chabant <ludovic@chabant.com>
parents:
36
diff
changeset
|
344 |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
345 // Save current selection. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
346 // If state selection is undefined, we have a legacy editor. Just ignore that part. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
347 const cm6editor = view.editor as EditorWithCM6; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
348 const stateSelection: EditorSelection = cm6editor.cm.state.selection; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
349 const stateSelectionJSON = (stateSelection !== undefined) ? stateSelection.toJSON() : ""; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
350 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
351 const stateData = {'scrollInfo': scrollInfo, 'selection': stateSelectionJSON}; |
37
8be02002ed66
Use Obsidian's view APIs for scrolling state
Ludovic Chabant <ludovic@chabant.com>
parents:
36
diff
changeset
|
352 |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
353 return stateData; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
354 } |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
355 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
356 private readonly restoreState = function(stateData: StateData, view: MarkdownView) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
357 // Restore scrolling position (Obsidian API only allows setting vertical position). |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
358 view.currentMode.applyScroll(stateData.scrollInfo.top); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
359 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
360 // Restore last known selection, if any. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
361 if (stateData.selection != "") { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
362 const cm6editor = view.editor as EditorWithCM6; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
363 var transaction = cm6editor.cm.state.update({ |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
364 selection: EditorSelection.fromJSON(stateData.selection)}) |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
365 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
366 cm6editor.cm.dispatch(transaction); |
0 | 367 } |
368 } | |
22
f7e0926c2500
Don't restore state on a file that's already open in another pane.
Ludovic Chabant <ludovic@chabant.com>
parents:
21
diff
changeset
|
369 |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
370 private readonly findFileStateFromOtherPane = function(file: TFile, activeView: MarkdownView) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
371 var otherView = null; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
372 this.app.workspace.getLeavesOfType("markdown").every( |
22
f7e0926c2500
Don't restore state on a file that's already open in another pane.
Ludovic Chabant <ludovic@chabant.com>
parents:
21
diff
changeset
|
373 (leaf: WorkspaceLeaf) => { |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
374 var curView = leaf.view as MarkdownView; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
375 if (curView != activeView && |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
376 curView.file.path == file.path && |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
377 this.getUniqueViewId(curView) >= 0 // Skip views that have never been activated. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
378 ) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
379 otherView = curView; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
380 return false; // Stop iterating leaves. |
22
f7e0926c2500
Don't restore state on a file that's already open in another pane.
Ludovic Chabant <ludovic@chabant.com>
parents:
21
diff
changeset
|
381 } |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
382 return true; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
383 }, |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
384 this // thisArg |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
385 ); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
386 return otherView ? this.getState(otherView) : null; |
22
f7e0926c2500
Don't restore state on a file that's already open in another pane.
Ludovic Chabant <ludovic@chabant.com>
parents:
21
diff
changeset
|
387 } |
0 | 388 |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
389 private readonly forgetExcessFiles = function() { |
0 | 390 const keepMax = this.settings.rememberMaxFiles; |
391 if (keepMax <= 0) { | |
392 return; | |
393 } | |
394 | |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
395 // Sort newer files first, older files last. |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
396 var filesData: RememberedFileState[] = Object.values(this.data.rememberedFiles); |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
397 filesData.sort((a, b) => { |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
398 if (a.lastSavedTime > b.lastSavedTime) return -1; // a before b |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
399 if (a.lastSavedTime < b.lastSavedTime) return 1; // b before a |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
400 return 0; |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
401 }); |
0 | 402 |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
403 // Remove older files past the limit. |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
404 for (var i = keepMax; i < filesData.length; ++i) { |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
405 var fileData = filesData[i]; |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
406 delete this.data.rememberedFiles[fileData.path]; |
0 | 407 } |
408 } | |
409 | |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
410 private readonly getUniqueViewId = function(view: ViewWithID, autocreateId: boolean = false) { |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
411 if (view.__uniqueId == undefined) { |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
412 if (!autocreateId) { |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
413 return -1; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
414 } |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
415 view.__uniqueId = (this._nextUniqueViewId++); |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
416 return view.__uniqueId; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
417 } |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
418 return view.__uniqueId; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
419 } |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
420 |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
421 private readonly clearUniqueViewId = function(view: ViewWithID) { |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
422 delete view["__uniqueId"]; |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
423 } |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
424 |
0 | 425 private readonly onFileRename = async ( |
426 file: TAbstractFile, | |
427 oldPath: string, | |
428 ): Promise<void> => { | |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
429 const existingFile: RememberedFileState = this.data.rememberedFiles[oldPath]; |
0 | 430 if (existingFile) { |
431 existingFile.path = file.path; | |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
432 delete this.data.rememberedFiles[oldPath]; |
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
433 this.data.rememberedFiles[file.path] = existingFile; |
0 | 434 } |
435 }; | |
436 | |
437 private readonly onFileDelete = async ( | |
438 file: TAbstractFile, | |
439 ): Promise<void> => { | |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
440 delete this.data.rememberedFiles[file.path]; |
0 | 441 }; |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
442 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
443 private readonly onAppQuit = async (tasks: Tasks): Promise<void> => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
444 const _this = this; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
445 tasks.addPromise( |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
446 _this.rememberAllOpenedFileStates() |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
447 .then(_this.writeStateDatabase(STATE_DB_PATH))); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
448 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
449 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
450 private readonly rememberAllOpenedFileStates = async(): Promise<void> => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
451 this.app.workspace.getLeavesOfType("markdown").forEach( |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
452 (leaf: WorkspaceLeaf) => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
453 const view = leaf.view as MarkdownView; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
454 this.rememberFileState(view); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
455 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
456 ); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
457 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
458 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
459 private readonly writeStateDatabase = async(path: string): Promise<void> => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
460 const fs = this.app.vault.adapter; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
461 const jsonDb = JSON.stringify(this.data); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
462 await fs.write(path, jsonDb); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
463 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
464 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
465 private readonly readStateDatabase = async(path: string): Promise<void> => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
466 const fs = this.app.vault.adapter; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
467 if (await fs.exists(path)) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
468 const jsonDb = await fs.read(path); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
469 this.data = JSON.parse(jsonDb); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
470 const numLoaded = Object.keys(this.data.rememberedFiles).length; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
471 console.debug(`RememberFileState: read ${numLoaded} record from state database.`); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
472 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
473 } |
0 | 474 } |
475 |