Mercurial > obsidian-remember-file-state
comparison src/main.ts @ 8:ec6c48a07b03
Make the plugin data into a dictionary
- Allows for faster lookup of the current file
- Fix sorting bug with trimming excess file data
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Mon, 14 Feb 2022 13:01:23 -0800 |
parents | b1cb0474bb18 |
children | 6f7f35af6335 |
comparison
equal
deleted
inserted
replaced
7:b1cb0474bb18 | 8:ec6c48a07b03 |
---|---|
28 stateData: Object; | 28 stateData: Object; |
29 } | 29 } |
30 | 30 |
31 // Interface for all currently remembered file states. | 31 // Interface for all currently remembered file states. |
32 interface RememberFileStatePluginData { | 32 interface RememberFileStatePluginData { |
33 rememberedFiles: RememberedFileState[]; | 33 rememberedFiles: Object; |
34 } | 34 } |
35 | 35 |
36 // Default empty list of remembered file states. | 36 // Default empty list of remembered file states. |
37 const DEFAULT_DATA: RememberFileStatePluginData = { | 37 const DEFAULT_DATA: RememberFileStatePluginData = { |
38 rememberedFiles: [] | 38 rememberedFiles: {} |
39 }; | 39 }; |
40 | 40 |
41 export default class RememberFileStatePlugin extends Plugin { | 41 export default class RememberFileStatePlugin extends Plugin { |
42 settings: RememberFileStatePluginSettings; | 42 settings: RememberFileStatePluginSettings; |
43 data: RememberFileStatePluginData; | 43 data: RememberFileStatePluginData; |
184 private readonly rememberFileState = async (file: TFile, view: View): Promise<void> => { | 184 private readonly rememberFileState = async (file: TFile, view: View): Promise<void> => { |
185 const scrollInfo = view.editor.getScrollInfo(); | 185 const scrollInfo = view.editor.getScrollInfo(); |
186 const stateSelectionJSON = view.editor.cm.state.selection.toJSON(); | 186 const stateSelectionJSON = view.editor.cm.state.selection.toJSON(); |
187 const stateData = {'scrollInfo': scrollInfo, 'selection': stateSelectionJSON}; | 187 const stateData = {'scrollInfo': scrollInfo, 'selection': stateSelectionJSON}; |
188 | 188 |
189 var existingFile = this.data.rememberedFiles.find( | 189 var existingFile = this.data.rememberedFiles[file.path]; |
190 curFile => curFile.path == file.path | |
191 ); | |
192 | |
193 if (existingFile) { | 190 if (existingFile) { |
194 existingFile.lastSavedTime = Date.now(); | 191 existingFile.lastSavedTime = Date.now(); |
195 existingFile.stateData = stateData; | 192 existingFile.stateData = stateData; |
196 } else { | 193 } else { |
197 let newFileState = { | 194 let newFileState = { |
198 path: file.path, | 195 path: file.path, |
199 lastSavedTime: Date.now(), | 196 lastSavedTime: Date.now(), |
200 stateData: stateData | 197 stateData: stateData |
201 }; | 198 }; |
202 this.data.rememberedFiles.push(newFileState); | 199 this.data.rememberedFiles[file.path] = newFileState; |
203 | 200 |
204 // If we need to keep the number remembered files under a maximum, | 201 // If we need to keep the number remembered files under a maximum, |
205 // do it now. | 202 // do it now. |
206 this.forgetExcessFiles(); | 203 this.forgetExcessFiles(); |
207 } | 204 } |
208 console.debug("Remember file state for:", file.path); | 205 console.debug("Remember file state for:", file.path); |
209 } | 206 } |
210 | 207 |
211 private readonly restoreFileState = function(file: TFile, view: View) { | 208 private readonly restoreFileState = function(file: TFile, view: View) { |
212 const existingFile = this.data.rememberedFiles.find( | 209 const existingFile = this.data.rememberedFiles[file.path]; |
213 (curFile) => curFile.path === file.path | |
214 ); | |
215 if (existingFile) { | 210 if (existingFile) { |
216 console.debug("Restoring file state for:", file.path); | 211 console.debug("Restoring file state for:", file.path); |
217 const stateData = existingFile.stateData; | 212 const stateData = existingFile.stateData; |
218 view.editor.scrollTo(stateData.scrollInfo.left, stateData.scrollInfo.top); | 213 view.editor.scrollTo(stateData.scrollInfo.left, stateData.scrollInfo.top); |
219 var transaction = view.editor.cm.state.update({ | 214 var transaction = view.editor.cm.state.update({ |
226 const keepMax = this.settings.rememberMaxFiles; | 221 const keepMax = this.settings.rememberMaxFiles; |
227 if (keepMax <= 0) { | 222 if (keepMax <= 0) { |
228 return; | 223 return; |
229 } | 224 } |
230 | 225 |
231 this.data.rememberedFiles.sort((a, b) => a.lastSavedTime < b.lastSavedTime); | 226 // Sort newer files first, older files last. |
232 | 227 var filesData = Object.values(this.data.rememberedFiles); |
233 if (this.data.rememberedFiles.length > keepMax) { | 228 filesData.sort((a, b) => { |
234 this.data.rememberedFiles.splice(keepMax); | 229 if (a.lastSavedTime > b.lastSavedTime) return -1; // a before b |
230 if (a.lastSavedTime < b.lastSavedTime) return 1; // b before a | |
231 return 0; | |
232 }); | |
233 | |
234 // Remove older files past the limit. | |
235 for (var i = keepMax; i < filesData.length; ++i) { | |
236 var fileData = filesData[i]; | |
237 delete this.data.rememberedFiles[fileData.path]; | |
235 } | 238 } |
236 } | 239 } |
237 | 240 |
238 private readonly getUniqueViewId = function(view: View, autocreateId: boolean = false) { | 241 private readonly getUniqueViewId = function(view: View, autocreateId: boolean = false) { |
239 if (view.__uniqueId == undefined) { | 242 if (view.__uniqueId == undefined) { |
252 | 255 |
253 private readonly onFileRename = async ( | 256 private readonly onFileRename = async ( |
254 file: TAbstractFile, | 257 file: TAbstractFile, |
255 oldPath: string, | 258 oldPath: string, |
256 ): Promise<void> => { | 259 ): Promise<void> => { |
257 const existingFile = this.data.rememberedFiles.find( | 260 const existingFile = this.data.rememberedFiles[oldPath]; |
258 (curFile) => curFile.path === oldPath | |
259 ); | |
260 if (existingFile) { | 261 if (existingFile) { |
261 existingFile.path = file.path; | 262 existingFile.path = file.path; |
263 delete this.data.rememberedFiles[oldPath]; | |
264 this.data.rememberedFiles[file.path] = existingFile; | |
262 } | 265 } |
263 }; | 266 }; |
264 | 267 |
265 private readonly onFileDelete = async ( | 268 private readonly onFileDelete = async ( |
266 file: TAbstractFile, | 269 file: TAbstractFile, |
267 ): Promise<void> => { | 270 ): Promise<void> => { |
268 this.data.rememberedFiles = this.data.rememberedFiles.filter( | 271 delete this.data.rememberedFiles[file.path]; |
269 (curFile) => curFile.path !== file.path | |
270 ); | |
271 }; | 272 }; |
272 } | 273 } |
273 | 274 |