Mercurial > obsidian-remember-file-state
annotate src/main.ts @ 59:1d6fe880946f 1.1.2
Bump to version 1.1.2
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 21 Nov 2023 17:17:52 -0800 |
parents | 4f6cbc0b339c |
children |
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 |
51
e932f1b73133
Pass `this` as the context for various callbacks.
Ludovic Chabant <ludovic@chabant.com>
parents:
50
diff
changeset
|
129 this.registerEvent(this.app.workspace.on('file-open', this.onFileOpen, this)); |
e932f1b73133
Pass `this` as the context for various callbacks.
Ludovic Chabant <ludovic@chabant.com>
parents:
50
diff
changeset
|
130 this.registerEvent(this.app.workspace.on('quit', this.onAppQuit, this)); |
e932f1b73133
Pass `this` as the context for various callbacks.
Ludovic Chabant <ludovic@chabant.com>
parents:
50
diff
changeset
|
131 this.registerEvent(this.app.vault.on('rename', this.onFileRename, this)); |
e932f1b73133
Pass `this` as the context for various callbacks.
Ludovic Chabant <ludovic@chabant.com>
parents:
50
diff
changeset
|
132 this.registerEvent(this.app.vault.on('delete', this.onFileDelete, this)); |
0 | 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)); | |
155 } | |
156 | |
157 onunload() { | |
52
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
158 console.log("RememberFileState: unloading plugin"); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
159 |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
160 // Unregister unload callbacks on all views. |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
161 this.unregisterAllViews(); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
162 |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
163 // Forget which files are opened in which views. |
28
fbaf7c7126be
Don't restore file state if we're just switching to another pane
Ludovic Chabant <ludovic@chabant.com>
parents:
27
diff
changeset
|
164 this._lastOpenFiles = {}; |
0 | 165 |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
166 // Run global unhooks. |
0 | 167 this._globalUninstallers.forEach((cb) => cb()); |
168 } | |
169 | |
170 async loadSettings() { | |
171 this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); | |
172 } | |
173 | |
174 async saveSettings() { | |
175 await this.saveData(this.settings); | |
176 } | |
177 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
178 private readonly onLayoutReady = function() { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
179 this.app.workspace.getLeavesOfType("markdown").forEach( |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
180 (leaf: WorkspaceLeaf) => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
181 var view = leaf.view as MarkdownView; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
182 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
183 // 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
|
184 // unload callback to remember their state. |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
185 this.registerOnUnloadFile(view); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
186 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
187 // 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
|
188 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
|
189 if (viewId != undefined) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
190 this._lastOpenFiles[viewId] = view.file.path; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
191 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
192 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
193 // Restore state for each opened pane on startup. |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
194 const existingFile = this.data.rememberedFiles[view.file.path]; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
195 if (existingFile) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
196 const savedStateData = existingFile.stateData; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
197 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
|
198 this.restoreState(savedStateData, view); |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
199 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
200 }); |
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 |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
203 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
|
204 var filePath = view.file.path; |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
205 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
|
206 if (viewId in this._viewUninstallers) { |
0 | 207 return; |
208 } | |
209 | |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
210 console.debug(`RememberFileState: registering callback on view ${viewId}`, filePath); |
0 | 211 const _this = this; |
212 var uninstall = around(view, { | |
213 onUnloadFile: function(next) { | |
214 return async function (unloaded: TFile) { | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
215 _this.rememberFileState(this, unloaded); |
0 | 216 return await next.call(this, unloaded); |
217 }; | |
218 } | |
219 }); | |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
220 this._viewUninstallers[viewId] = uninstall; |
0 | 221 |
222 view.register(() => { | |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
223 // 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
|
224 // 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
|
225 // do nothing if we don't find it. |
21
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
226 // @ts-ignore |
815b93d13e0f
Improve typescript compliance
Ludovic Chabant <ludovic@chabant.com>
parents:
16
diff
changeset
|
227 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
|
228 if (plugin) { |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
229 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
|
230 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
|
231 delete plugin._lastOpenFiles[viewId]; |
6
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
232 uninstall(); |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
233 } else { |
114d7e6d2633
Fix various issues around keeping references to editor objects
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
234 console.debug( |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
235 "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
|
236 } |
0 | 237 }); |
238 } | |
239 | |
52
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
240 private readonly unregisterAllViews = function() { |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
241 // Run view uninstallers on all current views. |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
242 var numViews: number = 0; |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
243 this.app.workspace.getLeavesOfType("markdown").forEach( |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
244 (leaf: WorkspaceLeaf) => { |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
245 const filePath = (leaf.view as MarkdownView).file.path; |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
246 const viewId = this.getUniqueViewId(leaf.view as ViewWithID); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
247 if (viewId != undefined) { |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
248 var uninstaller = this._viewUninstallers[viewId]; |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
249 if (uninstaller) { |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
250 console.debug(`RememberFileState: uninstalling hooks for view ${viewId}`, filePath); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
251 uninstaller(leaf.view); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
252 ++numViews; |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
253 } else { |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
254 console.debug("RememberFileState: found markdown view without an uninstaller!", filePath); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
255 } |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
256 // Clear the ID so we don't get confused if the plugin |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
257 // is re-enabled later. |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
258 this.clearUniqueViewId(leaf.view as ViewWithID); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
259 } else { |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
260 console.debug("RememberFileState: found markdown view without an ID!", filePath); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
261 } |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
262 }); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
263 console.debug(`RememberFileState: unregistered ${numViews} view callbacks`); |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
264 this._viewUninstallers = {}; |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
265 } |
586f857a98dd
Move unregistering of all views into a reusable function.
Ludovic Chabant <ludovic@chabant.com>
parents:
51
diff
changeset
|
266 |
0 | 267 private readonly onFileOpen = async ( |
268 openedFile: TFile | |
269 ): Promise<void> => { | |
270 // If `openedFile` is null, it's because the last pane was closed | |
271 // 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
|
272 if (!openedFile) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
273 return; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
274 } |
0 | 275 |
44
fae202d7b3de
Fix Typescript warnings and errors
Ludovic Chabant <ludovic@chabant.com>
parents:
43
diff
changeset
|
276 var shouldSuppressThis: boolean = this._suppressNextFileOpen; |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
277 this._suppressNextFileOpen = false; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
278 if (shouldSuppressThis) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
279 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
|
280 return; |
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 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
283 // 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
|
284 // only editor we support for now. |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
285 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
|
286 if (!activeView) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
287 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
|
288 return; |
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 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
291 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
|
292 |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
293 // 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
|
294 // 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
|
295 var isRealFileOpen = true; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
296 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
|
297 if (viewId != undefined) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
298 const lastOpenFileInView = this._lastOpenFiles[viewId]; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
299 isRealFileOpen = (lastOpenFileInView != openedFile.path); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
300 this._lastOpenFiles[viewId] = openedFile.path; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
301 } |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
302 if (!isRealFileOpen) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
303 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
|
304 return; |
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 |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
307 // Restore the state! |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
308 try { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
309 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
|
310 if (existingFile) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
311 const savedStateData = existingFile.stateData; |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
312 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
|
313 this.restoreState(savedStateData, activeView); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
314 } else { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
315 // 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
|
316 // 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
|
317 const otherPaneState = this.findFileStateFromOtherPane(openedFile, activeView); |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
318 if (otherPaneState) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
319 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
|
320 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
|
321 } |
0 | 322 } |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
323 } catch (err) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
324 console.error("RememberFileState: couldn't restore file state: ", err); |
0 | 325 } |
326 } | |
327 | |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
328 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
|
329 const stateData = this.getState(view); |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
330 |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
331 if (file === undefined) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
332 file = view.file; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
333 } |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
334 var existingFile = this.data.rememberedFiles[file.path]; |
0 | 335 if (existingFile) { |
336 existingFile.lastSavedTime = Date.now(); | |
337 existingFile.stateData = stateData; | |
338 } else { | |
339 let newFileState = { | |
340 path: file.path, | |
341 lastSavedTime: Date.now(), | |
342 stateData: stateData | |
343 }; | |
8
ec6c48a07b03
Make the plugin data into a dictionary
Ludovic Chabant <ludovic@chabant.com>
parents:
7
diff
changeset
|
344 this.data.rememberedFiles[file.path] = newFileState; |
0 | 345 |
36 | 346 // If we need to keep the number of remembered files under a maximum, |
0 | 347 // do it now. |
348 this.forgetExcessFiles(); | |
349 } | |
41
aa9bc7754c5d
Fix typos in debug log messages
Ludovic Chabant <ludovic@chabant.com>
parents:
40
diff
changeset
|
350 console.debug("RememberFileState: remembered state for:", file.path, stateData); |
0 | 351 } |
352 | |
40
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
353 private readonly getState = function(view: MarkdownView) { |
96e86650043b
Fix issues with files opened in multiple panes.
Ludovic Chabant <ludovic@chabant.com>
parents:
37
diff
changeset
|
354 // 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
|
355 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
|
356 |
44
fae202d7b3de
Fix Typescript warnings and errors
Ludovic Chabant <ludovic@chabant.com>
parents:
43
diff
changeset
|
357 // 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
|
358 // 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
|
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; |
58
4f6cbc0b339c
Remove checks for legacy editor.
Ludovic Chabant <ludovic@chabant.com>
parents:
55
diff
changeset
|
361 const stateSelectionJSON = stateSelection.toJSON(); |
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 |
54
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
455 private readonly onAppQuit = function(tasks: Tasks) { |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
456 this.unregisterAllViews(); |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
457 this.rememberAllOpenedFileStates(); |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
458 this.writeStateDatabase(STATE_DB_PATH); |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
459 console.log("RememberFileState: done with app-quit cleanup."); |
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 |
54
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
462 private readonly rememberAllOpenedFileStates = function() { |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
463 console.log("RememberFileState: remembering all opened file states..."); |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
464 this.app.workspace.getLeavesOfType("markdown").forEach( |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
465 (leaf: WorkspaceLeaf) => { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
466 const view = leaf.view as MarkdownView; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
467 this.rememberFileState(view); |
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 |
54
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
472 private readonly writeStateDatabase = function(path: string) { |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
473 const fs = this.app.vault.adapter; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
474 const jsonDb = JSON.stringify(this.data); |
54
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
475 console.log("RememberFileState: writing state database..."); |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
476 fs.write(path, jsonDb) |
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
477 .then(() => { console.log("RememberFileState: wrote state database."); }); |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
478 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
479 |
54
06504ceb3283
Make all shutdown logic synchronous.
Ludovic Chabant <ludovic@chabant.com>
parents:
53
diff
changeset
|
480 private readonly readStateDatabase = async function(path: string): Promise<void> { |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
481 const fs = this.app.vault.adapter; |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
482 if (await fs.exists(path)) { |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
483 const jsonDb = await fs.read(path); |
53
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
484 try |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
485 { |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
486 this.data = JSON.parse(jsonDb); |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
487 const numLoaded = Object.keys(this.data.rememberedFiles).length; |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
488 console.debug(`RememberFileState: read ${numLoaded} record from state database.`); |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
489 } catch (err) { |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
490 console.error("RememberFileState: error loading state database:", err); |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
491 console.error(jsonDb); |
f2e066bbe343
Handle errors around reading the state database file.
Ludovic Chabant <ludovic@chabant.com>
parents:
52
diff
changeset
|
492 } |
43
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
493 } |
7e981d54a055
Support state persistence between sessions
Ludovic Chabant <ludovic@chabant.com>
parents:
41
diff
changeset
|
494 } |
50
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
495 |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
496 private readonly setupLogFile = function(outLogPath: string) { |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
497 console.log("RememberFileState: setting up log file: ", outLogPath); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
498 |
55
388eb78ef4b7
Typescript compliance.
Ludovic Chabant <ludovic@chabant.com>
parents:
54
diff
changeset
|
499 const makeWrapper = function(origFunc: () => void) { |
388eb78ef4b7
Typescript compliance.
Ludovic Chabant <ludovic@chabant.com>
parents:
54
diff
changeset
|
500 return function () { |
50
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
501 origFunc.apply(console, arguments); |
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 var text: string = ""; |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
504 for (var i: number = 0; i < arguments.length; i++) { |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
505 if (i > 0) text += " "; |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
506 text += arguments[i].toString(); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
507 } |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
508 text += "\n"; |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
509 fs.appendFileSync(outLogPath, text); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
510 }; |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
511 }; |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
512 console.log = makeWrapper(console.log); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
513 console.debug = makeWrapper(console.debug); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
514 console.info = makeWrapper(console.info); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
515 console.warn = makeWrapper(console.warn); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
516 console.error = makeWrapper(console.error); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
517 |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
518 const banner: string = "\n\nDebug log start\n===============\n"; |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
519 fs.appendFileSync(outLogPath, banner); |
1fe2cd2c603f
Add optional file logging.
Ludovic Chabant <ludovic@chabant.com>
parents:
44
diff
changeset
|
520 } |
0 | 521 } |
522 |