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