From bc243e1a7c6c19ea931329582b31f2539d3483a5 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Tue, 16 May 2023 13:40:29 -0300 Subject: [PATCH 01/16] first draft for sorting with waypointPriority --- main.ts | 57 ++++++++++++++++++++++++++++++++++++++++------- package-lock.json | 28 +++++++++++------------ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/main.ts b/main.ts index def93e6..c86686d 100644 --- a/main.ts +++ b/main.ts @@ -13,7 +13,8 @@ interface WaypointSettings { debugLogging: boolean, useWikiLinks: boolean, showEnclosingNote: boolean, - folderNoteType: string + folderNoteType: string, + waypointPriorityKey: string } const DEFAULT_SETTINGS: WaypointSettings = { @@ -24,7 +25,9 @@ const DEFAULT_SETTINGS: WaypointSettings = { debugLogging: false, useWikiLinks: true, showEnclosingNote: false, - folderNoteType: FolderNoteType.InsideFolder + folderNoteType: FolderNoteType.InsideFolder, + waypointPriorityKey: "waypointPriority" + } export default class Waypoint extends Plugin { @@ -187,7 +190,7 @@ export default class Waypoint extends Plugin { async getFileTreeRepresentation(rootNode: TFolder, node: TAbstractFile, indentLevel: number, topLevel = false): Promise|null { const bullet = " ".repeat(indentLevel) + "-"; if (node instanceof TFile) { - console.log(node) + this.log(node) // Print the file name if (node.extension == "md") { if (this.settings.useWikiLinks) { @@ -237,9 +240,8 @@ export default class Waypoint extends Plugin { if (node.children && node.children.length > 0) { // Print the files and nested folders within the folder let children = node.children; - children = children.sort((a, b) => { - return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); - }); + this.log(`node: ${node.name}, children: ${children.map(c => c.name)}`) + children = children.sort(this.sortWithPriority); if (!this.settings.showFolderNotes) { if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { children = children.filter(child => this.settings.showFolderNotes || child.name !== node.name + ".md"); @@ -360,9 +362,9 @@ export default class Waypoint extends Plugin { } } - log(message: string) { + log(message?: any) { if (this.settings.debugLogging) { - console.log(message); + console.log(message); } } @@ -373,6 +375,45 @@ export default class Waypoint extends Plugin { async saveSettings() { await this.saveData(this.settings); } + + getWaypointPriority = (a: TAbstractFile): number | null => { + if (a instanceof TFile) { + let fileCache = this.app.metadataCache.getFileCache(a as TFile) + if (fileCache && fileCache.frontmatter && typeof fileCache.frontmatter.waypointPriority === 'number') { + return fileCache.frontmatter.waypointPriority; + } else { + return null; + } + } else { + return null; + } + } + + sortWithPriority = (a: TAbstractFile, b: TAbstractFile): number => { + this.log(`comparing ${a.name} and ${b.name}`) + let aPriority = this.getWaypointPriority(a) + let bPriority = this.getWaypointPriority(b) + this.log(`aPriority ${aPriority} bPriority ${bPriority}`) + + if (aPriority !== null && bPriority !== null) { + // If both have waypointPriority, the one with a lower priority number should come first. + this.log(`${aPriority - bPriority}`) + return aPriority - bPriority + } else if (aPriority !== null) { + // If only `a` has waypointPriority, `a` should come first. + this.log(-1) + return -1 + } else if (bPriority !== null) { + // If only `b` has waypointPriority, `b` should come first. + this.log(1) + return 1 + } else { + // If neither has priority, sort alphabetically. + this.log(`${a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'})}`) + return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); + } + } + } class WaypointSettingsTab extends PluginSettingTab { diff --git a/package-lock.json b/package-lock.json index 9a588c8..4eaf7ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "waypoint", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "waypoint", - "version": "1.3.0", + "version": "1.4.0", "license": "MIT", "devDependencies": { "@types/codemirror": "^5.60.5", @@ -1832,9 +1832,9 @@ } }, "node_modules/style-mod": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz", - "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.3.tgz", + "integrity": "sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==", "dev": true }, "node_modules/supports-color": { @@ -1932,9 +1932,9 @@ "peer": true }, "node_modules/w3c-keyname": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz", - "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.7.tgz", + "integrity": "sha512-XB8aa62d4rrVfoZYQaYNy3fy+z4nrfy2ooea3/0BnBzXW0tSdZ+lRgjzBZhk0La0H6h8fVyYCxx/qkQcAIuvfg==", "dev": true }, "node_modules/which": { @@ -3276,9 +3276,9 @@ "peer": true }, "style-mod": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz", - "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.3.tgz", + "integrity": "sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==", "dev": true }, "supports-color": { @@ -3354,9 +3354,9 @@ "peer": true }, "w3c-keyname": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz", - "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.7.tgz", + "integrity": "sha512-XB8aa62d4rrVfoZYQaYNy3fy+z4nrfy2ooea3/0BnBzXW0tSdZ+lRgjzBZhk0La0H6h8fVyYCxx/qkQcAIuvfg==", "dev": true }, "which": { From 97e3d9f61b1f1564132a7e1a7dda2b44649c52f7 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Wed, 17 May 2023 23:33:41 -0300 Subject: [PATCH 02/16] replace space with tabs --- main.ts | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/main.ts b/main.ts index c86686d..091a991 100644 --- a/main.ts +++ b/main.ts @@ -389,30 +389,30 @@ export default class Waypoint extends Plugin { } } - sortWithPriority = (a: TAbstractFile, b: TAbstractFile): number => { - this.log(`comparing ${a.name} and ${b.name}`) - let aPriority = this.getWaypointPriority(a) - let bPriority = this.getWaypointPriority(b) - this.log(`aPriority ${aPriority} bPriority ${bPriority}`) - - if (aPriority !== null && bPriority !== null) { - // If both have waypointPriority, the one with a lower priority number should come first. - this.log(`${aPriority - bPriority}`) - return aPriority - bPriority - } else if (aPriority !== null) { - // If only `a` has waypointPriority, `a` should come first. - this.log(-1) - return -1 - } else if (bPriority !== null) { - // If only `b` has waypointPriority, `b` should come first. - this.log(1) - return 1 - } else { - // If neither has priority, sort alphabetically. - this.log(`${a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'})}`) - return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); - } - } + sortWithPriority = (a: TAbstractFile, b: TAbstractFile): number => { + this.log(`comparing ${a.name} and ${b.name}`) + let aPriority = this.getWaypointPriority(a) + let bPriority = this.getWaypointPriority(b) + this.log(`aPriority ${aPriority} bPriority ${bPriority}`) + + if (aPriority !== null && bPriority !== null) { + // If both have waypointPriority, the one with a lower priority number should come first. + this.log(`${aPriority - bPriority}`) + return aPriority - bPriority + } else if (aPriority !== null) { + // If only `a` has waypointPriority, `a` should come first. + this.log(-1) + return -1 + } else if (bPriority !== null) { + // If only `b` has waypointPriority, `b` should come first. + this.log(1) + return 1 + } else { + // If neither has priority, sort alphabetically. + this.log(`${a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'})}`) + return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); + } + } } From 834a405aaabe9a8632a62fec7a731d8e7f750265 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Sat, 20 May 2023 00:30:08 -0300 Subject: [PATCH 03/16] scheduleUpdate on modify event (frontmatter could be taken in account) --- main.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main.ts b/main.ts index 091a991..9097ac3 100644 --- a/main.ts +++ b/main.ts @@ -63,7 +63,12 @@ export default class Waypoint extends Plugin { } this.scheduleUpdate(); })); - this.registerEvent(this.app.vault.on("modify", this.detectWaypointFlag)); + this.registerEvent(this.app.vault.on("modify", (file) => { + this.log("modify " + file.name); + this.foldersWithChanges.add(file.parent); + this.scheduleUpdate(); + this.detectWaypointFlag(file as TFile) + })); }); // This adds a settings tab so the user can configure various aspects of the plugin From c9a5dc89daf017d102e617ae7d15483facf26cba Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Sat, 20 May 2023 17:49:55 -0300 Subject: [PATCH 04/16] Update `updateWaypoint` so it will only modify waypoint if there are changes --- main.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/main.ts b/main.ts index 9097ac3..d411885 100644 --- a/main.ts +++ b/main.ts @@ -93,7 +93,7 @@ export default class Waypoint extends Plugin { this.log("Found waypoint flag in folder note!"); await this.updateWaypoint(file); await this.updateParentWaypoint(file.parent, this.settings.folderNoteType === FolderNoteType.OutsideFolder); - return; + return; } else if (file.parent.isRoot()) { this.log("Found waypoint flag in root folder."); this.printWaypointError(file, `%% Error: Cannot create a waypoint in the root folder of your vault. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%`); @@ -180,8 +180,15 @@ export default class Waypoint extends Plugin { return; } this.log("Waypoint found at " + waypointStart + " to " + waypointEnd); - lines.splice(waypointStart, waypointEnd !== -1 ? waypointEnd - waypointStart + 1 : 1, waypoint); - await this.app.vault.modify(file, lines.join("\n")); + + // Get the current waypoint block from lines and join it to form a string + let currentWaypoint = waypointEnd !== -1 ? lines.slice(waypointStart, waypointEnd + 1).join("\n") : lines[waypointStart]; + // Only splice and modify if waypoint differs from the current block + if (currentWaypoint !== waypoint) { + this.log("Waypoint content changed, updating") + lines.splice(waypointStart, waypointEnd !== -1 ? waypointEnd - waypointStart + 1 : 1, waypoint); + await this.app.vault.modify(file, lines.join("\n")); + } } /** From cd90c67698730046ae8ce152796431f25945b328 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Sat, 20 May 2023 21:36:56 -0300 Subject: [PATCH 05/16] draft on getting folder priority with "InsideFolder" setting --- main.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/main.ts b/main.ts index d411885..3c696e2 100644 --- a/main.ts +++ b/main.ts @@ -396,7 +396,12 @@ export default class Waypoint extends Plugin { } else { return null; } - } else { + } else if (a instanceof TFolder) { + if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { + let foldernote: TAbstractFile | null = a.children.find(child => child instanceof TFile && child.basename === a.name); + return foldernote ? this.getWaypointPriority(foldernote) : null + } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + } return null; } } @@ -405,23 +410,20 @@ export default class Waypoint extends Plugin { this.log(`comparing ${a.name} and ${b.name}`) let aPriority = this.getWaypointPriority(a) let bPriority = this.getWaypointPriority(b) - this.log(`aPriority ${aPriority} bPriority ${bPriority}`) - if (aPriority !== null && bPriority !== null) { // If both have waypointPriority, the one with a lower priority number should come first. - this.log(`${aPriority - bPriority}`) return aPriority - bPriority } else if (aPriority !== null) { // If only `a` has waypointPriority, `a` should come first. - this.log(-1) + this.log(`${a.name}`) return -1 } else if (bPriority !== null) { // If only `b` has waypointPriority, `b` should come first. - this.log(1) + this.log(`${b.name}`) return 1 } else { // If neither has priority, sort alphabetically. - this.log(`${a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'})}`) + this.log(`alphabetical`) return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); } } From d1cb69332c606ab6433244e97027b8bf4aa67770 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Sun, 21 May 2023 22:26:40 -0300 Subject: [PATCH 06/16] simple workaround to make priority reflect on "grand-parent" notes --- main.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.ts b/main.ts index 3c696e2..7496dbf 100644 --- a/main.ts +++ b/main.ts @@ -302,7 +302,10 @@ export default class Waypoint extends Plugin { this.log("Updating changed folders..."); this.foldersWithChanges.forEach((folder) => { this.log("Updating " + folder.path); - this.updateParentWaypoint(folder, true); + // Development note: simplified way of making changes in a note reflect in "grandparent" folder + // example change in a folder note priority say c/arrays/arrays.md And I would like this + // to take effect on `c` waypoint + this.updateParentWaypoint(folder.parent, true); }); this.foldersWithChanges.clear(); } From 4aadccc4af3e00620821219d177562bfa8270805 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Mon, 22 May 2023 16:58:08 -0300 Subject: [PATCH 07/16] implement `updateAncestorWaypoints` method to simplify propagation --- main.ts | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/main.ts b/main.ts index 7496dbf..92ba977 100644 --- a/main.ts +++ b/main.ts @@ -92,7 +92,7 @@ export default class Waypoint extends Plugin { if (this.isFolderNote(file)) { this.log("Found waypoint flag in folder note!"); await this.updateWaypoint(file); - await this.updateParentWaypoint(file.parent, this.settings.folderNoteType === FolderNoteType.OutsideFolder); + await this.updateAncestorWaypoints(file.parent, this.settings.folderNoteType === FolderNoteType.OutsideFolder); return; } else if (file.parent.isRoot()) { this.log("Found waypoint flag in root folder."); @@ -302,10 +302,7 @@ export default class Waypoint extends Plugin { this.log("Updating changed folders..."); this.foldersWithChanges.forEach((folder) => { this.log("Updating " + folder.path); - // Development note: simplified way of making changes in a note reflect in "grandparent" folder - // example change in a folder note priority say c/arrays/arrays.md And I would like this - // to take effect on `c` waypoint - this.updateParentWaypoint(folder.parent, true); + this.updateAncestorWaypoints(folder, true); }); this.foldersWithChanges.clear(); } @@ -331,6 +328,18 @@ export default class Waypoint extends Plugin { } } + /** + * Update all ancestor waypoints (if any) of the given file/folder. + * @param node The node to start the search from + * @param includeCurrentNode Whether to include the given folder in the search + */ + updateAncestorWaypoints = async (node: TAbstractFile, includeCurrentNode: boolean) => { + const ancestorWaypoints = await this.locateAncestorWaypoints(node, includeCurrentNode); + for (let waypoint of ancestorWaypoints) { + this.updateWaypoint(waypoint); + } + } + /** * Locate the ancestor waypoint (if any) of the given file/folder. * @param node The node to start the search from @@ -363,6 +372,40 @@ export default class Waypoint extends Plugin { return null; } + /** + * Locate all ancestor waypoints (if any) of the given file/folder. + * @param node The node to start the search from + * @param includeCurrentNode Whether to include the given folder in the search + * @returns The list of ancestor waypoints, or an empty list if none were found + */ + async locateAncestorWaypoints(node: TAbstractFile, includeCurrentNode: boolean): Promise { + this.log("Locating all ancestor waypoints of " + node.name); + let folder = includeCurrentNode ? node : node.parent; + let ancestorWaypoints = []; + + while (folder) { + let folderNote; + if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { + folderNote = this.app.vault.getAbstractFileByPath(folder.path + "/" + folder.name + ".md"); + } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + if (folder.parent) { + folderNote = this.app.vault.getAbstractFileByPath(this.getCleanParentPath(folder) + folder.name + ".md"); + } + } + if (folderNote instanceof TFile) { + this.log("Found folder note: " + folderNote.path); + const text = await this.app.vault.cachedRead(folderNote); + if (text.includes(Waypoint.BEGIN_WAYPOINT) || text.includes(this.settings.waypointFlag)) { + this.log("Found ancestor waypoint!"); + ancestorWaypoints.push(folderNote); + } + } + folder = folder.parent; + } + this.log("Found " + ancestorWaypoints.length + " ancestor waypoints."); + return ancestorWaypoints; + } + /** * Get the parent folder of the given filepath if it exists. * @param path The filepath to search From e92d22e026824e2eae740a4c80c205749fd89c76 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Mon, 5 Jun 2023 23:22:20 -0300 Subject: [PATCH 08/16] remove logs --- main.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/main.ts b/main.ts index 92ba977..77938bc 100644 --- a/main.ts +++ b/main.ts @@ -202,7 +202,6 @@ export default class Waypoint extends Plugin { async getFileTreeRepresentation(rootNode: TFolder, node: TAbstractFile, indentLevel: number, topLevel = false): Promise|null { const bullet = " ".repeat(indentLevel) + "-"; if (node instanceof TFile) { - this.log(node) // Print the file name if (node.extension == "md") { if (this.settings.useWikiLinks) { @@ -252,7 +251,6 @@ export default class Waypoint extends Plugin { if (node.children && node.children.length > 0) { // Print the files and nested folders within the folder let children = node.children; - this.log(`node: ${node.name}, children: ${children.map(c => c.name)}`) children = children.sort(this.sortWithPriority); if (!this.settings.showFolderNotes) { if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { @@ -453,7 +451,6 @@ export default class Waypoint extends Plugin { } sortWithPriority = (a: TAbstractFile, b: TAbstractFile): number => { - this.log(`comparing ${a.name} and ${b.name}`) let aPriority = this.getWaypointPriority(a) let bPriority = this.getWaypointPriority(b) if (aPriority !== null && bPriority !== null) { @@ -461,15 +458,12 @@ export default class Waypoint extends Plugin { return aPriority - bPriority } else if (aPriority !== null) { // If only `a` has waypointPriority, `a` should come first. - this.log(`${a.name}`) return -1 } else if (bPriority !== null) { // If only `b` has waypointPriority, `b` should come first. - this.log(`${b.name}`) return 1 } else { // If neither has priority, sort alphabetically. - this.log(`alphabetical`) return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); } } From 5ffe43cc33b0b27053093943c3a35f81fd3c1507 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Thu, 8 Jun 2023 15:10:08 -0300 Subject: [PATCH 09/16] remove updateParentWaypoint and locateParentWaypoint --- main.ts | 45 +-------------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/main.ts b/main.ts index 77938bc..a972fcd 100644 --- a/main.ts +++ b/main.ts @@ -314,18 +314,6 @@ export default class Waypoint extends Plugin { true ); - /** - * Update the ancestor waypoint (if any) of the given file/folder. - * @param node The node to start the search from - * @param includeCurrentNode Whether to include the given folder in the search - */ - updateParentWaypoint = async (node: TAbstractFile, includeCurrentNode: boolean) => { - const parentWaypoint = await this.locateParentWaypoint(node, includeCurrentNode); - if (parentWaypoint !== null) { - this.updateWaypoint(parentWaypoint); - } - } - /** * Update all ancestor waypoints (if any) of the given file/folder. * @param node The node to start the search from @@ -338,38 +326,6 @@ export default class Waypoint extends Plugin { } } - /** - * Locate the ancestor waypoint (if any) of the given file/folder. - * @param node The node to start the search from - * @param includeCurrentNode Whether to include the given folder in the search - * @returns The ancestor waypoint, or null if none was found - */ - async locateParentWaypoint(node: TAbstractFile, includeCurrentNode: boolean): Promise { - this.log("Locating parent waypoint of " + node.name); - let folder = includeCurrentNode ? node : node.parent; - while (folder) { - let folderNote; - if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - folderNote = this.app.vault.getAbstractFileByPath(folder.path + "/" + folder.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { - if (folder.parent) { - folderNote = this.app.vault.getAbstractFileByPath(this.getCleanParentPath(folder) + folder.name + ".md"); - } - } - if (folderNote instanceof TFile) { - this.log("Found folder note: " + folderNote.path); - const text = await this.app.vault.cachedRead(folderNote); - if (text.includes(Waypoint.BEGIN_WAYPOINT) || text.includes(this.settings.waypointFlag)) { - this.log("Found parent waypoint!"); - return folderNote; - } - } - folder = folder.parent; - } - this.log("No parent waypoint found."); - return null; - } - /** * Locate all ancestor waypoints (if any) of the given file/folder. * @param node The node to start the search from @@ -445,6 +401,7 @@ export default class Waypoint extends Plugin { let foldernote: TAbstractFile | null = a.children.find(child => child instanceof TFile && child.basename === a.name); return foldernote ? this.getWaypointPriority(foldernote) : null } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + // Development note: Implemenent for "outside folder" use case } return null; } From 28b25b059b480677ee93d765033593c7a02b5720 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Thu, 8 Jun 2023 16:47:37 -0300 Subject: [PATCH 10/16] Implement outside folder option --- main.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/main.ts b/main.ts index a972fcd..c16c364 100644 --- a/main.ts +++ b/main.ts @@ -388,20 +388,27 @@ export default class Waypoint extends Plugin { await this.saveData(this.settings); } - getWaypointPriority = (a: TAbstractFile): number | null => { - if (a instanceof TFile) { - let fileCache = this.app.metadataCache.getFileCache(a as TFile) + getWaypointPriority = (file: TAbstractFile): number | null => { + if (file instanceof TFile) { + let fileCache = this.app.metadataCache.getFileCache(file as TFile) if (fileCache && fileCache.frontmatter && typeof fileCache.frontmatter.waypointPriority === 'number') { return fileCache.frontmatter.waypointPriority; } else { return null; } - } else if (a instanceof TFolder) { + } else if (file instanceof TFolder) { if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - let foldernote: TAbstractFile | null = a.children.find(child => child instanceof TFile && child.basename === a.name); + // If file is a folder and folder note is an inside note, attempt to find a child note with the same name. + let foldernote: TAbstractFile | null = file.children.find(child => child instanceof TFile && child.basename === file.name); return foldernote ? this.getWaypointPriority(foldernote) : null } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { - // Development note: Implemenent for "outside folder" use case + // If file is a folder and folder note is an outside note, attempt to find a sibling note with the same name. + if (!file.isRoot()) { + let foldernote: TAbstractFile | null = file.parent.children.find(child => child instanceof TFile && child.basename === file.name); + return foldernote ? this.getWaypointPriority(foldernote) : null; + } else { + return null; // Handle case when the file is the root folder. + } } return null; } From e05fcbdff2c5ff6007682df0e0e705eb9b636b14 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Thu, 8 Jun 2023 17:19:34 -0300 Subject: [PATCH 11/16] use waypointPriorityKey setting and setting UI --- main.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/main.ts b/main.ts index c16c364..3fb2335 100644 --- a/main.ts +++ b/main.ts @@ -391,8 +391,8 @@ export default class Waypoint extends Plugin { getWaypointPriority = (file: TAbstractFile): number | null => { if (file instanceof TFile) { let fileCache = this.app.metadataCache.getFileCache(file as TFile) - if (fileCache && fileCache.frontmatter && typeof fileCache.frontmatter.waypointPriority === 'number') { - return fileCache.frontmatter.waypointPriority; + if (fileCache && fileCache.frontmatter && typeof fileCache.frontmatter[this.settings.waypointPriorityKey] === 'number') { + return fileCache.frontmatter[this.settings.waypointPriorityKey]; } else { return null; } @@ -524,6 +524,17 @@ class WaypointSettingsTab extends PluginSettingTab { await this.plugin.saveSettings(); }) ); + new Setting(containerEl) + .setName("Frontmatter key for note priority") + .setDesc("The frontmatter key to set the note order piority when listed in a Waypoint.") + .addText(text => text + .setPlaceholder(DEFAULT_SETTINGS.waypointPriorityKey) + .setValue(this.plugin.settings.waypointPriorityKey) + .onChange(async (value) => { + this.plugin.settings.waypointPriorityKey = value; + await this.plugin.saveSettings() + }) + ); const postscriptElement = containerEl.createEl("div", { cls: "setting-item", }); From 831422f21d353fee1b8dc6a5b9186c49a6cf378f Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Thu, 8 Jun 2023 22:10:08 -0300 Subject: [PATCH 12/16] Add sorting instructions on README --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 66f10e5..deaa716 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,23 @@ Waypoint is an Obsidian plugin that automatically generates tables of contents/M Note that since waypoints can only be generated in folder notes, **it is highly recommended that you install a plugin like [Folder Note](https://github.com/xpgo/obsidian-folder-note-plugin)** to ensure that folder notes don't get lost after folder renames and other actions that change the file tree. If a folder note containing a waypoint is renamed to something other than the folder's name, the waypoint will no longer be updated. +### Ordering Notes on Waypoint + +By default, notes in Waypoint are sorted alphabetically. However, you can organize your notes in a specific order by setting up their Waypoint priorities. To do this, you would add an entry in your [note metadata](https://help.obsidian.md/Editing+and+formatting/Metadata) with a numeric value, such as: + +```markdown +--- +waypointPriority: 0 +--- +``` + +Waypoint will then sort the notes based on the numeric value assigned to `waypointPriority`. Smaller values correspond to higher priority, so a note with `waypointPriority: 0` will appear above a note with `waypointPriority: 1`. If two notes have the same priority, they will be sorted alphabetically. + +In case a note does not have a `waypointPriority` defined, it will fall back to the default alphabetical sorting strategy. + +The `waypointPriority` key can be customized to a different key label in the Waypoint settings. This functionality works for both regulat notes and folder notes. + + ## Current Limitations - **Waypoints can only be created within a folder note** From 433bd3659ffd460ad761e024204d0a9f6ee5a8d5 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Thu, 8 Jun 2023 22:16:26 -0300 Subject: [PATCH 13/16] Slight improve on `waypointPriority` example --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index deaa716..0f22da1 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,11 @@ By default, notes in Waypoint are sorted alphabetically. However, you can organi --- waypointPriority: 0 --- + +# My note + +... + ``` Waypoint will then sort the notes based on the numeric value assigned to `waypointPriority`. Smaller values correspond to higher priority, so a note with `waypointPriority: 0` will appear above a note with `waypointPriority: 1`. If two notes have the same priority, they will be sorted alphabetically. From dae4a810f97ceeeb330e93c91262a9700a739369 Mon Sep 17 00:00:00 2001 From: Daniel Plucenio Date: Sun, 11 Jun 2023 20:35:52 -0300 Subject: [PATCH 14/16] bump version to 1.5.0 --- manifest.json | 2 +- package.json | 2 +- versions.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index bb92187..6ba8d10 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "waypoint", "name": "Waypoint", - "version": "1.4.0", + "version": "1.5.0", "minAppVersion": "0.12.0", "description": "Easily generate dynamic content maps in your folder notes. Enables folders to show up in the graph view and removes the need for messy tags!", "author": "Idrees Hassan", diff --git a/package.json b/package.json index 67315e9..8f6da2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "waypoint", - "version": "1.4.0", + "version": "1.5.0", "description": "Easily generate dynamic content maps in your folder notes. Enables folders to show up in the graph view and removes the need for messy tags!", "main": "main.js", "scripts": { diff --git a/versions.json b/versions.json index 68be0cc..017643b 100644 --- a/versions.json +++ b/versions.json @@ -3,5 +3,6 @@ "1.1.0": "0.12.0", "1.2.0": "0.12.0", "1.3.0": "0.12.0", - "1.4.0": "0.12.0" + "1.4.0": "0.12.0", + "1.5.0": "0.12.0" } \ No newline at end of file From b0b7f3992ca662a71ad227dd7a76363e864fd8d4 Mon Sep 17 00:00:00 2001 From: Valerie Burzynski Date: Mon, 31 Jul 2023 21:30:46 -0500 Subject: [PATCH 15/16] chore: format main.ts with prettier --- main.ts | 492 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 339 insertions(+), 153 deletions(-) diff --git a/main.ts b/main.ts index def93e6..95b7639 100644 --- a/main.ts +++ b/main.ts @@ -1,19 +1,28 @@ -import { App, debounce, Plugin, PluginSettingTab, Setting, TAbstractFile, TFile, TFolder } from 'obsidian'; +import { + App, + debounce, + Plugin, + PluginSettingTab, + Setting, + TAbstractFile, + TFile, + TFolder, +} from "obsidian"; enum FolderNoteType { InsideFolder = "INSIDE_FOLDER", - OutsideFolder = "OUTSIDE_FOLDER" + OutsideFolder = "OUTSIDE_FOLDER", } interface WaypointSettings { - waypointFlag: string - stopScanAtFolderNotes: boolean, - showFolderNotes: boolean, - showNonMarkdownFiles: boolean, - debugLogging: boolean, - useWikiLinks: boolean, - showEnclosingNote: boolean, - folderNoteType: string + waypointFlag: string; + stopScanAtFolderNotes: boolean; + showFolderNotes: boolean; + showNonMarkdownFiles: boolean; + debugLogging: boolean; + useWikiLinks: boolean; + showEnclosingNote: boolean; + folderNoteType: string; } const DEFAULT_SETTINGS: WaypointSettings = { @@ -24,8 +33,8 @@ const DEFAULT_SETTINGS: WaypointSettings = { debugLogging: false, useWikiLinks: true, showEnclosingNote: false, - folderNoteType: FolderNoteType.InsideFolder -} + folderNoteType: FolderNoteType.InsideFolder, +}; export default class Waypoint extends Plugin { static readonly BEGIN_WAYPOINT = "%% Begin Waypoint %%"; @@ -38,37 +47,44 @@ export default class Waypoint extends Plugin { await this.loadSettings(); this.app.workspace.onLayoutReady(async () => { // Register events after layout is built to avoid initial wave of 'create' events - this.registerEvent(this.app.vault.on("create", (file) => { - this.log("create " + file.name); - this.foldersWithChanges.add(file.parent); - this.scheduleUpdate(); - })); - this.registerEvent(this.app.vault.on("delete", (file) => { - this.log("delete " + file.name); - const parentFolder = this.getParentFolder(file.path); - if (parentFolder !== null) { - this.foldersWithChanges.add(parentFolder); + this.registerEvent( + this.app.vault.on("create", (file) => { + this.log("create " + file.name); + this.foldersWithChanges.add(file.parent); this.scheduleUpdate(); - } - })); - this.registerEvent(this.app.vault.on("rename", (file, oldPath) => { - this.log("rename " + file.name); - this.foldersWithChanges.add(file.parent); - const parentFolder = this.getParentFolder(oldPath); - if (parentFolder !== null) { - this.foldersWithChanges.add(parentFolder); - } - this.scheduleUpdate(); - })); - this.registerEvent(this.app.vault.on("modify", this.detectWaypointFlag)); + }) + ); + this.registerEvent( + this.app.vault.on("delete", (file) => { + this.log("delete " + file.name); + const parentFolder = this.getParentFolder(file.path); + if (parentFolder !== null) { + this.foldersWithChanges.add(parentFolder); + this.scheduleUpdate(); + } + }) + ); + this.registerEvent( + this.app.vault.on("rename", (file, oldPath) => { + this.log("rename " + file.name); + this.foldersWithChanges.add(file.parent); + const parentFolder = this.getParentFolder(oldPath); + if (parentFolder !== null) { + this.foldersWithChanges.add(parentFolder); + } + this.scheduleUpdate(); + }) + ); + this.registerEvent( + this.app.vault.on("modify", this.detectWaypointFlag) + ); }); // This adds a settings tab so the user can configure various aspects of the plugin this.addSettingTab(new WaypointSettingsTab(this.app, this)); } - onunload() { - } + onunload() {} /** * Scan the given file for the waypoint flag. If found, update the waypoint. @@ -84,28 +100,44 @@ export default class Waypoint extends Plugin { if (this.isFolderNote(file)) { this.log("Found waypoint flag in folder note!"); await this.updateWaypoint(file); - await this.updateParentWaypoint(file.parent, this.settings.folderNoteType === FolderNoteType.OutsideFolder); - return; + await this.updateParentWaypoint( + file.parent, + this.settings.folderNoteType === + FolderNoteType.OutsideFolder + ); + return; } else if (file.parent.isRoot()) { this.log("Found waypoint flag in root folder."); - this.printWaypointError(file, `%% Error: Cannot create a waypoint in the root folder of your vault. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%`); + this.printWaypointError( + file, + `%% Error: Cannot create a waypoint in the root folder of your vault. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%` + ); return; } else { this.log("Found waypoint flag in invalid note."); - this.printWaypointError(file, `%% Error: Cannot create a waypoint in a note that's not the folder note. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%`); + this.printWaypointError( + file, + `%% Error: Cannot create a waypoint in a note that's not the folder note. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%` + ); return; } } } this.log("No waypoint flags found."); - } + }; isFolderNote(file: TFile): boolean { if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { return file.basename == file.parent.name; - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { if (file.parent) { - return this.app.vault.getAbstractFileByPath(this.getCleanParentPath(file) + file.basename) instanceof TFolder; + return ( + this.app.vault.getAbstractFileByPath( + this.getCleanParentPath(file) + file.basename + ) instanceof TFolder + ); } return false; } @@ -131,7 +163,9 @@ export default class Waypoint extends Plugin { } } if (waypointIndex === -1) { - console.error("Error: No waypoint flag found while trying to print error."); + console.error( + "Error: No waypoint flag found while trying to print error." + ); return; } lines.splice(waypointIndex, 1, error); @@ -146,11 +180,25 @@ export default class Waypoint extends Plugin { this.log("Updating waypoint in " + file.path); let fileTree; if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - fileTree = await this.getFileTreeRepresentation(file.parent, file.parent, 0, true); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { - const folder = this.app.vault.getAbstractFileByPath(this.getCleanParentPath(file) + file.basename); + fileTree = await this.getFileTreeRepresentation( + file.parent, + file.parent, + 0, + true + ); + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { + const folder = this.app.vault.getAbstractFileByPath( + this.getCleanParentPath(file) + file.basename + ); if (folder instanceof TFolder) { - fileTree = await this.getFileTreeRepresentation(file.parent, folder, 0, true); + fileTree = await this.getFileTreeRepresentation( + file.parent, + folder, + 0, + true + ); } } const waypoint = `${Waypoint.BEGIN_WAYPOINT}\n${fileTree}\n\n${Waypoint.END_WAYPOINT}`; @@ -160,19 +208,32 @@ export default class Waypoint extends Plugin { let waypointEnd = -1; for (let i = 0; i < lines.length; i++) { const trimmed = lines[i].trim(); - if (waypointStart === -1 && (trimmed === this.settings.waypointFlag || trimmed === Waypoint.BEGIN_WAYPOINT)) { + if ( + waypointStart === -1 && + (trimmed === this.settings.waypointFlag || + trimmed === Waypoint.BEGIN_WAYPOINT) + ) { waypointStart = i; - } else if (waypointStart !== -1 && trimmed === (Waypoint.END_WAYPOINT)) { + } else if ( + waypointStart !== -1 && + trimmed === Waypoint.END_WAYPOINT + ) { waypointEnd = i; break; } } if (waypointStart === -1) { - console.error("Error: No waypoint found while trying to update " + file.path); + console.error( + "Error: No waypoint found while trying to update " + file.path + ); return; } this.log("Waypoint found at " + waypointStart + " to " + waypointEnd); - lines.splice(waypointStart, waypointEnd !== -1 ? waypointEnd - waypointStart + 1 : 1, waypoint); + lines.splice( + waypointStart, + waypointEnd !== -1 ? waypointEnd - waypointStart + 1 : 1, + waypoint + ); await this.app.vault.modify(file, lines.join("\n")); } @@ -184,22 +245,33 @@ export default class Waypoint extends Plugin { * @param topLevel Whether this is the top level of the tree or not * @returns The string representation of the tree, or null if the node is not a file or folder */ - async getFileTreeRepresentation(rootNode: TFolder, node: TAbstractFile, indentLevel: number, topLevel = false): Promise|null { + async getFileTreeRepresentation( + rootNode: TFolder, + node: TAbstractFile, + indentLevel: number, + topLevel = false + ): Promise | null { const bullet = " ".repeat(indentLevel) + "-"; if (node instanceof TFile) { - console.log(node) + console.log(node); // Print the file name if (node.extension == "md") { if (this.settings.useWikiLinks) { return `${bullet} [[${node.basename}]]`; } else { - return `${bullet} [${node.basename}](${this.getEncodedUri(rootNode, node)})`; + return `${bullet} [${node.basename}](${this.getEncodedUri( + rootNode, + node + )})`; } } else if (this.settings.showNonMarkdownFiles) { if (this.settings.useWikiLinks) { return `${bullet} [[${node.name}]]`; } else { - return `${bullet} [${node.name}](${this.getEncodedUri(rootNode, node)})`; + return `${bullet} [${node.name}](${this.getEncodedUri( + rootNode, + node + )})`; } } return null; @@ -209,25 +281,41 @@ export default class Waypoint extends Plugin { // Print the folder name text = `${bullet} **${node.name}**`; let folderNote; - if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - folderNote = this.app.vault.getAbstractFileByPath(node.path + "/" + node.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + if ( + this.settings.folderNoteType === FolderNoteType.InsideFolder + ) { + folderNote = this.app.vault.getAbstractFileByPath( + node.path + "/" + node.name + ".md" + ); + } else if ( + this.settings.folderNoteType === + FolderNoteType.OutsideFolder + ) { if (node.parent) { - folderNote = this.app.vault.getAbstractFileByPath(node.parent.path + "/" + node.name + ".md"); + folderNote = this.app.vault.getAbstractFileByPath( + node.parent.path + "/" + node.name + ".md" + ); } } if (folderNote instanceof TFile) { if (this.settings.useWikiLinks) { text = `${bullet} **[[${folderNote.basename}]]**`; } else { - text = `${bullet} **[${folderNote.basename}](${this.getEncodedUri(rootNode, folderNote)})**`; + text = `${bullet} **[${ + folderNote.basename + }](${this.getEncodedUri(rootNode, folderNote)})**`; } if (!topLevel) { if (this.settings.stopScanAtFolderNotes) { return text; } else { - const content = await this.app.vault.cachedRead(folderNote); - if (content.includes(Waypoint.BEGIN_WAYPOINT) || content.includes(this.settings.waypointFlag)) { + const content = await this.app.vault.cachedRead( + folderNote + ); + if ( + content.includes(Waypoint.BEGIN_WAYPOINT) || + content.includes(this.settings.waypointFlag) + ) { return text; } } @@ -238,32 +326,63 @@ export default class Waypoint extends Plugin { // Print the files and nested folders within the folder let children = node.children; children = children.sort((a, b) => { - return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); + return a.name.localeCompare(b.name, undefined, { + numeric: true, + sensitivity: "base", + }); }); if (!this.settings.showFolderNotes) { - if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - children = children.filter(child => this.settings.showFolderNotes || child.name !== node.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + if ( + this.settings.folderNoteType === + FolderNoteType.InsideFolder + ) { + children = children.filter( + (child) => + this.settings.showFolderNotes || + child.name !== node.name + ".md" + ); + } else if ( + this.settings.folderNoteType === + FolderNoteType.OutsideFolder + ) { const folderNames = new Set(); for (const element of children) { if (element instanceof TFolder) { folderNames.add(element.name + ".md"); } } - children = children.filter(child => child instanceof TFolder || !folderNames.has(child.name)); + children = children.filter( + (child) => + child instanceof TFolder || + !folderNames.has(child.name) + ); } } if (children.length > 0) { - const nextIndentLevel = (topLevel && !this.settings.showEnclosingNote) ? indentLevel : indentLevel + 1; - text += (text === "" ? "" : "\n") + (await Promise.all(children.map(child => this.getFileTreeRepresentation(rootNode, child, nextIndentLevel)))) - .filter(Boolean) - .join("\n"); + const nextIndentLevel = + topLevel && !this.settings.showEnclosingNote + ? indentLevel + : indentLevel + 1; + text += + (text === "" ? "" : "\n") + + ( + await Promise.all( + children.map((child) => + this.getFileTreeRepresentation( + rootNode, + child, + nextIndentLevel + ) + ) + ) + ) + .filter(Boolean) + .join("\n"); } return text; } else { return `${bullet} **${node.name}**`; } - } return null; } @@ -291,28 +410,30 @@ export default class Waypoint extends Plugin { this.updateParentWaypoint(folder, true); }); this.foldersWithChanges.clear(); - } + }; /** * Schedule an update for the changed folders after debouncing to prevent excessive updates. */ - scheduleUpdate = debounce( - this.updateChangedFolders.bind(this), - 500, - true - ); + scheduleUpdate = debounce(this.updateChangedFolders.bind(this), 500, true); /** * Update the ancestor waypoint (if any) of the given file/folder. * @param node The node to start the search from * @param includeCurrentNode Whether to include the given folder in the search */ - updateParentWaypoint = async (node: TAbstractFile, includeCurrentNode: boolean) => { - const parentWaypoint = await this.locateParentWaypoint(node, includeCurrentNode); + updateParentWaypoint = async ( + node: TAbstractFile, + includeCurrentNode: boolean + ) => { + const parentWaypoint = await this.locateParentWaypoint( + node, + includeCurrentNode + ); if (parentWaypoint !== null) { this.updateWaypoint(parentWaypoint); } - } + }; /** * Locate the ancestor waypoint (if any) of the given file/folder. @@ -320,22 +441,34 @@ export default class Waypoint extends Plugin { * @param includeCurrentNode Whether to include the given folder in the search * @returns The ancestor waypoint, or null if none was found */ - async locateParentWaypoint(node: TAbstractFile, includeCurrentNode: boolean): Promise { + async locateParentWaypoint( + node: TAbstractFile, + includeCurrentNode: boolean + ): Promise { this.log("Locating parent waypoint of " + node.name); let folder = includeCurrentNode ? node : node.parent; while (folder) { let folderNote; if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - folderNote = this.app.vault.getAbstractFileByPath(folder.path + "/" + folder.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + folderNote = this.app.vault.getAbstractFileByPath( + folder.path + "/" + folder.name + ".md" + ); + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { if (folder.parent) { - folderNote = this.app.vault.getAbstractFileByPath(this.getCleanParentPath(folder) + folder.name + ".md"); + folderNote = this.app.vault.getAbstractFileByPath( + this.getCleanParentPath(folder) + folder.name + ".md" + ); } } if (folderNote instanceof TFile) { this.log("Found folder note: " + folderNote.path); const text = await this.app.vault.cachedRead(folderNote); - if (text.includes(Waypoint.BEGIN_WAYPOINT) || text.includes(this.settings.waypointFlag)) { + if ( + text.includes(Waypoint.BEGIN_WAYPOINT) || + text.includes(this.settings.waypointFlag) + ) { this.log("Found parent waypoint!"); return folderNote; } @@ -352,7 +485,9 @@ export default class Waypoint extends Plugin { * @returns The parent folder, or null if none exists */ getParentFolder(path: string): TFolder { - const abstractFile = this.app.vault.getAbstractFileByPath(path.split("/").slice(0, -1).join("/")); + const abstractFile = this.app.vault.getAbstractFileByPath( + path.split("/").slice(0, -1).join("/") + ); if (abstractFile instanceof TFolder) { return abstractFile; } else { @@ -362,12 +497,16 @@ export default class Waypoint extends Plugin { log(message: string) { if (this.settings.debugLogging) { - console.log(message); + console.log(message); } } async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + this.settings = Object.assign( + {}, + DEFAULT_SETTINGS, + await this.loadData() + ); } async saveSettings() { @@ -384,95 +523,142 @@ class WaypointSettingsTab extends PluginSettingTab { } display(): void { - const {containerEl} = this; + const { containerEl } = this; containerEl.empty(); - containerEl.createEl('h2', {text: 'Waypoint Settings'}); + containerEl.createEl("h2", { text: "Waypoint Settings" }); new Setting(this.containerEl) .setName("Folder Note Style") .setDesc("Select the style of folder note used.") - .addDropdown((dropdown) => dropdown - .addOption(FolderNoteType.InsideFolder, "Folder Name Inside") - .addOption(FolderNoteType.OutsideFolder, "Folder Name Outside") - .setValue(this.plugin.settings.folderNoteType) - .onChange(async (value) => { - this.plugin.settings.folderNoteType = value; - await this.plugin.saveSettings(); - }) + .addDropdown((dropdown) => + dropdown + .addOption( + FolderNoteType.InsideFolder, + "Folder Name Inside" + ) + .addOption( + FolderNoteType.OutsideFolder, + "Folder Name Outside" + ) + .setValue(this.plugin.settings.folderNoteType) + .onChange(async (value) => { + this.plugin.settings.folderNoteType = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Show Folder Notes") - .setDesc("If enabled, folder notes will be listed alongside other notes in the generated waypoints.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showFolderNotes) - .onChange(async (value) => { - this.plugin.settings.showFolderNotes = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, folder notes will be listed alongside other notes in the generated waypoints." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.showFolderNotes) + .onChange(async (value) => { + this.plugin.settings.showFolderNotes = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Show Non-Markdown Files") - .setDesc("If enabled, non-Markdown files will be listed alongside other notes in the generated waypoints.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showNonMarkdownFiles) - .onChange(async (value) => { - this.plugin.settings.showNonMarkdownFiles = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, non-Markdown files will be listed alongside other notes in the generated waypoints." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.showNonMarkdownFiles) + .onChange(async (value) => { + this.plugin.settings.showNonMarkdownFiles = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Show Enclosing Note") - .setDesc("If enabled, the name of the folder note containing the waypoint will be listed at the top of the generated waypoints.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showEnclosingNote) - .onChange(async (value) => { - this.plugin.settings.showEnclosingNote = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, the name of the folder note containing the waypoint will be listed at the top of the generated waypoints." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.showEnclosingNote) + .onChange(async (value) => { + this.plugin.settings.showEnclosingNote = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Stop Scan at Folder Notes") - .setDesc("If enabled, the waypoint generator will stop scanning nested folders when it encounters a folder note. Otherwise, it will only stop if the folder note contains a waypoint.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.stopScanAtFolderNotes) - .onChange(async (value) => { - this.plugin.settings.stopScanAtFolderNotes = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, the waypoint generator will stop scanning nested folders when it encounters a folder note. Otherwise, it will only stop if the folder note contains a waypoint." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.stopScanAtFolderNotes) + .onChange(async (value) => { + this.plugin.settings.stopScanAtFolderNotes = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Use WikiLinks") - .setDesc("If enabled, links will be generated like [[My Page]] instead of [My Page](../Folder/My%Page.md).") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.useWikiLinks) - .onChange(async (value) => { - this.plugin.settings.useWikiLinks = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, links will be generated like [[My Page]] instead of [My Page](../Folder/My%Page.md)." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.useWikiLinks) + .onChange(async (value) => { + this.plugin.settings.useWikiLinks = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Waypoint Flag") - .setDesc("Text flag that triggers waypoint generation in a folder note. Must be surrounded by double-percent signs.") - .addText(text => text - .setPlaceholder(DEFAULT_SETTINGS.waypointFlag) - .setValue(this.plugin.settings.waypointFlag) - .onChange(async (value) => { - if (value && value.startsWith("%%") && value.endsWith("%%") && value !== "%%" && value !== "%%%" && value !== "%%%%") { - this.plugin.settings.waypointFlag = value; - } else { - this.plugin.settings.waypointFlag = DEFAULT_SETTINGS.waypointFlag; - console.error("Error: Waypoint flag must be surrounded by double-percent signs."); - } - await this.plugin.saveSettings(); - }) + .setDesc( + "Text flag that triggers waypoint generation in a folder note. Must be surrounded by double-percent signs." + ) + .addText((text) => + text + .setPlaceholder(DEFAULT_SETTINGS.waypointFlag) + .setValue(this.plugin.settings.waypointFlag) + .onChange(async (value) => { + if ( + value && + value.startsWith("%%") && + value.endsWith("%%") && + value !== "%%" && + value !== "%%%" && + value !== "%%%%" + ) { + this.plugin.settings.waypointFlag = value; + } else { + this.plugin.settings.waypointFlag = + DEFAULT_SETTINGS.waypointFlag; + console.error( + "Error: Waypoint flag must be surrounded by double-percent signs." + ); + } + await this.plugin.saveSettings(); + }) ); const postscriptElement = containerEl.createEl("div", { cls: "setting-item", }); - const descriptionElement = postscriptElement.createDiv({cls: "setting-item-description"}); - descriptionElement.createSpan({text: "For instructions on how to use this plugin, check out the README on "}); - descriptionElement.createEl("a", { attr: { "href": "https://github.com/IdreesInc/Waypoint" }, text: "GitHub" }); - descriptionElement.createSpan({text: " or get in touch with the author "}); - descriptionElement.createEl("a", { attr: { "href": "https://twitter.com/IdreesInc" }, text: "@IdreesInc" }); + const descriptionElement = postscriptElement.createDiv({ + cls: "setting-item-description", + }); + descriptionElement.createSpan({ + text: "For instructions on how to use this plugin, check out the README on ", + }); + descriptionElement.createEl("a", { + attr: { href: "https://github.com/IdreesInc/Waypoint" }, + text: "GitHub", + }); + descriptionElement.createSpan({ + text: " or get in touch with the author ", + }); + descriptionElement.createEl("a", { + attr: { href: "https://twitter.com/IdreesInc" }, + text: "@IdreesInc", + }); postscriptElement.appendChild(descriptionElement); } } From 4d7d3a2d098c05cf0af6b62fc95ac6d2627d1b50 Mon Sep 17 00:00:00 2001 From: Valerie Burzynski Date: Mon, 31 Jul 2023 22:00:20 -0500 Subject: [PATCH 16/16] chore: format code with prettier --- main.ts | 580 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 394 insertions(+), 186 deletions(-) diff --git a/main.ts b/main.ts index 3fb2335..59b1767 100644 --- a/main.ts +++ b/main.ts @@ -1,20 +1,29 @@ -import { App, debounce, Plugin, PluginSettingTab, Setting, TAbstractFile, TFile, TFolder } from 'obsidian'; +import { + App, + debounce, + Plugin, + PluginSettingTab, + Setting, + TAbstractFile, + TFile, + TFolder, +} from "obsidian"; enum FolderNoteType { InsideFolder = "INSIDE_FOLDER", - OutsideFolder = "OUTSIDE_FOLDER" + OutsideFolder = "OUTSIDE_FOLDER", } interface WaypointSettings { - waypointFlag: string - stopScanAtFolderNotes: boolean, - showFolderNotes: boolean, - showNonMarkdownFiles: boolean, - debugLogging: boolean, - useWikiLinks: boolean, - showEnclosingNote: boolean, - folderNoteType: string, - waypointPriorityKey: string + waypointFlag: string; + stopScanAtFolderNotes: boolean; + showFolderNotes: boolean; + showNonMarkdownFiles: boolean; + debugLogging: boolean; + useWikiLinks: boolean; + showEnclosingNote: boolean; + folderNoteType: string; + waypointPriorityKey: string; } const DEFAULT_SETTINGS: WaypointSettings = { @@ -26,9 +35,8 @@ const DEFAULT_SETTINGS: WaypointSettings = { useWikiLinks: true, showEnclosingNote: false, folderNoteType: FolderNoteType.InsideFolder, - waypointPriorityKey: "waypointPriority" - -} + waypointPriorityKey: "waypointPriority", +}; export default class Waypoint extends Plugin { static readonly BEGIN_WAYPOINT = "%% Begin Waypoint %%"; @@ -41,42 +49,49 @@ export default class Waypoint extends Plugin { await this.loadSettings(); this.app.workspace.onLayoutReady(async () => { // Register events after layout is built to avoid initial wave of 'create' events - this.registerEvent(this.app.vault.on("create", (file) => { - this.log("create " + file.name); - this.foldersWithChanges.add(file.parent); - this.scheduleUpdate(); - })); - this.registerEvent(this.app.vault.on("delete", (file) => { - this.log("delete " + file.name); - const parentFolder = this.getParentFolder(file.path); - if (parentFolder !== null) { - this.foldersWithChanges.add(parentFolder); + this.registerEvent( + this.app.vault.on("create", (file) => { + this.log("create " + file.name); + this.foldersWithChanges.add(file.parent); this.scheduleUpdate(); - } - })); - this.registerEvent(this.app.vault.on("rename", (file, oldPath) => { - this.log("rename " + file.name); - this.foldersWithChanges.add(file.parent); - const parentFolder = this.getParentFolder(oldPath); - if (parentFolder !== null) { - this.foldersWithChanges.add(parentFolder); - } - this.scheduleUpdate(); - })); - this.registerEvent(this.app.vault.on("modify", (file) => { - this.log("modify " + file.name); - this.foldersWithChanges.add(file.parent); - this.scheduleUpdate(); - this.detectWaypointFlag(file as TFile) - })); + }) + ); + this.registerEvent( + this.app.vault.on("delete", (file) => { + this.log("delete " + file.name); + const parentFolder = this.getParentFolder(file.path); + if (parentFolder !== null) { + this.foldersWithChanges.add(parentFolder); + this.scheduleUpdate(); + } + }) + ); + this.registerEvent( + this.app.vault.on("rename", (file, oldPath) => { + this.log("rename " + file.name); + this.foldersWithChanges.add(file.parent); + const parentFolder = this.getParentFolder(oldPath); + if (parentFolder !== null) { + this.foldersWithChanges.add(parentFolder); + } + this.scheduleUpdate(); + }) + ); + this.registerEvent( + this.app.vault.on("modify", (file) => { + this.log("modify " + file.name); + this.foldersWithChanges.add(file.parent); + this.scheduleUpdate(); + this.detectWaypointFlag(file as TFile); + }) + ); }); // This adds a settings tab so the user can configure various aspects of the plugin this.addSettingTab(new WaypointSettingsTab(this.app, this)); } - onunload() { - } + onunload() {} /** * Scan the given file for the waypoint flag. If found, update the waypoint. @@ -92,28 +107,44 @@ export default class Waypoint extends Plugin { if (this.isFolderNote(file)) { this.log("Found waypoint flag in folder note!"); await this.updateWaypoint(file); - await this.updateAncestorWaypoints(file.parent, this.settings.folderNoteType === FolderNoteType.OutsideFolder); + await this.updateAncestorWaypoints( + file.parent, + this.settings.folderNoteType === + FolderNoteType.OutsideFolder + ); return; } else if (file.parent.isRoot()) { this.log("Found waypoint flag in root folder."); - this.printWaypointError(file, `%% Error: Cannot create a waypoint in the root folder of your vault. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%`); + this.printWaypointError( + file, + `%% Error: Cannot create a waypoint in the root folder of your vault. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%` + ); return; } else { this.log("Found waypoint flag in invalid note."); - this.printWaypointError(file, `%% Error: Cannot create a waypoint in a note that's not the folder note. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%`); + this.printWaypointError( + file, + `%% Error: Cannot create a waypoint in a note that's not the folder note. For more information, check the instructions [here](https://github.com/IdreesInc/Waypoint) %%` + ); return; } } } this.log("No waypoint flags found."); - } + }; isFolderNote(file: TFile): boolean { if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { return file.basename == file.parent.name; - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { if (file.parent) { - return this.app.vault.getAbstractFileByPath(this.getCleanParentPath(file) + file.basename) instanceof TFolder; + return ( + this.app.vault.getAbstractFileByPath( + this.getCleanParentPath(file) + file.basename + ) instanceof TFolder + ); } return false; } @@ -139,7 +170,9 @@ export default class Waypoint extends Plugin { } } if (waypointIndex === -1) { - console.error("Error: No waypoint flag found while trying to print error."); + console.error( + "Error: No waypoint flag found while trying to print error." + ); return; } lines.splice(waypointIndex, 1, error); @@ -154,11 +187,25 @@ export default class Waypoint extends Plugin { this.log("Updating waypoint in " + file.path); let fileTree; if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - fileTree = await this.getFileTreeRepresentation(file.parent, file.parent, 0, true); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { - const folder = this.app.vault.getAbstractFileByPath(this.getCleanParentPath(file) + file.basename); + fileTree = await this.getFileTreeRepresentation( + file.parent, + file.parent, + 0, + true + ); + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { + const folder = this.app.vault.getAbstractFileByPath( + this.getCleanParentPath(file) + file.basename + ); if (folder instanceof TFolder) { - fileTree = await this.getFileTreeRepresentation(file.parent, folder, 0, true); + fileTree = await this.getFileTreeRepresentation( + file.parent, + folder, + 0, + true + ); } } const waypoint = `${Waypoint.BEGIN_WAYPOINT}\n${fileTree}\n\n${Waypoint.END_WAYPOINT}`; @@ -168,25 +215,41 @@ export default class Waypoint extends Plugin { let waypointEnd = -1; for (let i = 0; i < lines.length; i++) { const trimmed = lines[i].trim(); - if (waypointStart === -1 && (trimmed === this.settings.waypointFlag || trimmed === Waypoint.BEGIN_WAYPOINT)) { + if ( + waypointStart === -1 && + (trimmed === this.settings.waypointFlag || + trimmed === Waypoint.BEGIN_WAYPOINT) + ) { waypointStart = i; - } else if (waypointStart !== -1 && trimmed === (Waypoint.END_WAYPOINT)) { + } else if ( + waypointStart !== -1 && + trimmed === Waypoint.END_WAYPOINT + ) { waypointEnd = i; break; } } if (waypointStart === -1) { - console.error("Error: No waypoint found while trying to update " + file.path); + console.error( + "Error: No waypoint found while trying to update " + file.path + ); return; } this.log("Waypoint found at " + waypointStart + " to " + waypointEnd); // Get the current waypoint block from lines and join it to form a string - let currentWaypoint = waypointEnd !== -1 ? lines.slice(waypointStart, waypointEnd + 1).join("\n") : lines[waypointStart]; + let currentWaypoint = + waypointEnd !== -1 + ? lines.slice(waypointStart, waypointEnd + 1).join("\n") + : lines[waypointStart]; // Only splice and modify if waypoint differs from the current block if (currentWaypoint !== waypoint) { - this.log("Waypoint content changed, updating") - lines.splice(waypointStart, waypointEnd !== -1 ? waypointEnd - waypointStart + 1 : 1, waypoint); + this.log("Waypoint content changed, updating"); + lines.splice( + waypointStart, + waypointEnd !== -1 ? waypointEnd - waypointStart + 1 : 1, + waypoint + ); await this.app.vault.modify(file, lines.join("\n")); } } @@ -199,7 +262,12 @@ export default class Waypoint extends Plugin { * @param topLevel Whether this is the top level of the tree or not * @returns The string representation of the tree, or null if the node is not a file or folder */ - async getFileTreeRepresentation(rootNode: TFolder, node: TAbstractFile, indentLevel: number, topLevel = false): Promise|null { + async getFileTreeRepresentation( + rootNode: TFolder, + node: TAbstractFile, + indentLevel: number, + topLevel = false + ): Promise | null { const bullet = " ".repeat(indentLevel) + "-"; if (node instanceof TFile) { // Print the file name @@ -207,13 +275,19 @@ export default class Waypoint extends Plugin { if (this.settings.useWikiLinks) { return `${bullet} [[${node.basename}]]`; } else { - return `${bullet} [${node.basename}](${this.getEncodedUri(rootNode, node)})`; + return `${bullet} [${node.basename}](${this.getEncodedUri( + rootNode, + node + )})`; } } else if (this.settings.showNonMarkdownFiles) { if (this.settings.useWikiLinks) { return `${bullet} [[${node.name}]]`; } else { - return `${bullet} [${node.name}](${this.getEncodedUri(rootNode, node)})`; + return `${bullet} [${node.name}](${this.getEncodedUri( + rootNode, + node + )})`; } } return null; @@ -223,25 +297,41 @@ export default class Waypoint extends Plugin { // Print the folder name text = `${bullet} **${node.name}**`; let folderNote; - if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - folderNote = this.app.vault.getAbstractFileByPath(node.path + "/" + node.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + if ( + this.settings.folderNoteType === FolderNoteType.InsideFolder + ) { + folderNote = this.app.vault.getAbstractFileByPath( + node.path + "/" + node.name + ".md" + ); + } else if ( + this.settings.folderNoteType === + FolderNoteType.OutsideFolder + ) { if (node.parent) { - folderNote = this.app.vault.getAbstractFileByPath(node.parent.path + "/" + node.name + ".md"); + folderNote = this.app.vault.getAbstractFileByPath( + node.parent.path + "/" + node.name + ".md" + ); } } if (folderNote instanceof TFile) { if (this.settings.useWikiLinks) { text = `${bullet} **[[${folderNote.basename}]]**`; } else { - text = `${bullet} **[${folderNote.basename}](${this.getEncodedUri(rootNode, folderNote)})**`; + text = `${bullet} **[${ + folderNote.basename + }](${this.getEncodedUri(rootNode, folderNote)})**`; } if (!topLevel) { if (this.settings.stopScanAtFolderNotes) { return text; } else { - const content = await this.app.vault.cachedRead(folderNote); - if (content.includes(Waypoint.BEGIN_WAYPOINT) || content.includes(this.settings.waypointFlag)) { + const content = await this.app.vault.cachedRead( + folderNote + ); + if ( + content.includes(Waypoint.BEGIN_WAYPOINT) || + content.includes(this.settings.waypointFlag) + ) { return text; } } @@ -253,29 +343,57 @@ export default class Waypoint extends Plugin { let children = node.children; children = children.sort(this.sortWithPriority); if (!this.settings.showFolderNotes) { - if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - children = children.filter(child => this.settings.showFolderNotes || child.name !== node.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + if ( + this.settings.folderNoteType === + FolderNoteType.InsideFolder + ) { + children = children.filter( + (child) => + this.settings.showFolderNotes || + child.name !== node.name + ".md" + ); + } else if ( + this.settings.folderNoteType === + FolderNoteType.OutsideFolder + ) { const folderNames = new Set(); for (const element of children) { if (element instanceof TFolder) { folderNames.add(element.name + ".md"); } } - children = children.filter(child => child instanceof TFolder || !folderNames.has(child.name)); + children = children.filter( + (child) => + child instanceof TFolder || + !folderNames.has(child.name) + ); } } if (children.length > 0) { - const nextIndentLevel = (topLevel && !this.settings.showEnclosingNote) ? indentLevel : indentLevel + 1; - text += (text === "" ? "" : "\n") + (await Promise.all(children.map(child => this.getFileTreeRepresentation(rootNode, child, nextIndentLevel)))) - .filter(Boolean) - .join("\n"); + const nextIndentLevel = + topLevel && !this.settings.showEnclosingNote + ? indentLevel + : indentLevel + 1; + text += + (text === "" ? "" : "\n") + + ( + await Promise.all( + children.map((child) => + this.getFileTreeRepresentation( + rootNode, + child, + nextIndentLevel + ) + ) + ) + ) + .filter(Boolean) + .join("\n"); } return text; } else { return `${bullet} **${node.name}**`; } - } return null; } @@ -303,28 +421,30 @@ export default class Waypoint extends Plugin { this.updateAncestorWaypoints(folder, true); }); this.foldersWithChanges.clear(); - } + }; /** * Schedule an update for the changed folders after debouncing to prevent excessive updates. */ - scheduleUpdate = debounce( - this.updateChangedFolders.bind(this), - 500, - true - ); + scheduleUpdate = debounce(this.updateChangedFolders.bind(this), 500, true); /** * Update all ancestor waypoints (if any) of the given file/folder. * @param node The node to start the search from * @param includeCurrentNode Whether to include the given folder in the search */ - updateAncestorWaypoints = async (node: TAbstractFile, includeCurrentNode: boolean) => { - const ancestorWaypoints = await this.locateAncestorWaypoints(node, includeCurrentNode); + updateAncestorWaypoints = async ( + node: TAbstractFile, + includeCurrentNode: boolean + ) => { + const ancestorWaypoints = await this.locateAncestorWaypoints( + node, + includeCurrentNode + ); for (let waypoint of ancestorWaypoints) { this.updateWaypoint(waypoint); } - } + }; /** * Locate all ancestor waypoints (if any) of the given file/folder. @@ -332,7 +452,10 @@ export default class Waypoint extends Plugin { * @param includeCurrentNode Whether to include the given folder in the search * @returns The list of ancestor waypoints, or an empty list if none were found */ - async locateAncestorWaypoints(node: TAbstractFile, includeCurrentNode: boolean): Promise { + async locateAncestorWaypoints( + node: TAbstractFile, + includeCurrentNode: boolean + ): Promise { this.log("Locating all ancestor waypoints of " + node.name); let folder = includeCurrentNode ? node : node.parent; let ancestorWaypoints = []; @@ -340,16 +463,25 @@ export default class Waypoint extends Plugin { while (folder) { let folderNote; if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { - folderNote = this.app.vault.getAbstractFileByPath(folder.path + "/" + folder.name + ".md"); - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + folderNote = this.app.vault.getAbstractFileByPath( + folder.path + "/" + folder.name + ".md" + ); + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { if (folder.parent) { - folderNote = this.app.vault.getAbstractFileByPath(this.getCleanParentPath(folder) + folder.name + ".md"); + folderNote = this.app.vault.getAbstractFileByPath( + this.getCleanParentPath(folder) + folder.name + ".md" + ); } } if (folderNote instanceof TFile) { this.log("Found folder note: " + folderNote.path); const text = await this.app.vault.cachedRead(folderNote); - if (text.includes(Waypoint.BEGIN_WAYPOINT) || text.includes(this.settings.waypointFlag)) { + if ( + text.includes(Waypoint.BEGIN_WAYPOINT) || + text.includes(this.settings.waypointFlag) + ) { this.log("Found ancestor waypoint!"); ancestorWaypoints.push(folderNote); } @@ -366,7 +498,9 @@ export default class Waypoint extends Plugin { * @returns The parent folder, or null if none exists */ getParentFolder(path: string): TFolder { - const abstractFile = this.app.vault.getAbstractFileByPath(path.split("/").slice(0, -1).join("/")); + const abstractFile = this.app.vault.getAbstractFileByPath( + path.split("/").slice(0, -1).join("/") + ); if (abstractFile instanceof TFolder) { return abstractFile; } else { @@ -381,7 +515,11 @@ export default class Waypoint extends Plugin { } async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + this.settings = Object.assign( + {}, + DEFAULT_SETTINGS, + await this.loadData() + ); } async saveSettings() { @@ -390,8 +528,14 @@ export default class Waypoint extends Plugin { getWaypointPriority = (file: TAbstractFile): number | null => { if (file instanceof TFile) { - let fileCache = this.app.metadataCache.getFileCache(file as TFile) - if (fileCache && fileCache.frontmatter && typeof fileCache.frontmatter[this.settings.waypointPriorityKey] === 'number') { + let fileCache = this.app.metadataCache.getFileCache(file as TFile); + if ( + fileCache && + fileCache.frontmatter && + typeof fileCache.frontmatter[ + this.settings.waypointPriorityKey + ] === "number" + ) { return fileCache.frontmatter[this.settings.waypointPriorityKey]; } else { return null; @@ -399,39 +543,53 @@ export default class Waypoint extends Plugin { } else if (file instanceof TFolder) { if (this.settings.folderNoteType === FolderNoteType.InsideFolder) { // If file is a folder and folder note is an inside note, attempt to find a child note with the same name. - let foldernote: TAbstractFile | null = file.children.find(child => child instanceof TFile && child.basename === file.name); - return foldernote ? this.getWaypointPriority(foldernote) : null - } else if (this.settings.folderNoteType === FolderNoteType.OutsideFolder) { + let foldernote: TAbstractFile | null = file.children.find( + (child) => + child instanceof TFile && child.basename === file.name + ); + return foldernote ? this.getWaypointPriority(foldernote) : null; + } else if ( + this.settings.folderNoteType === FolderNoteType.OutsideFolder + ) { // If file is a folder and folder note is an outside note, attempt to find a sibling note with the same name. - if (!file.isRoot()) { - let foldernote: TAbstractFile | null = file.parent.children.find(child => child instanceof TFile && child.basename === file.name); - return foldernote ? this.getWaypointPriority(foldernote) : null; - } else { - return null; // Handle case when the file is the root folder. - } + if (!file.isRoot()) { + let foldernote: TAbstractFile | null = + file.parent.children.find( + (child) => + child instanceof TFile && + child.basename === file.name + ); + return foldernote + ? this.getWaypointPriority(foldernote) + : null; + } else { + return null; // Handle case when the file is the root folder. + } } return null; } - } + }; sortWithPriority = (a: TAbstractFile, b: TAbstractFile): number => { - let aPriority = this.getWaypointPriority(a) - let bPriority = this.getWaypointPriority(b) + let aPriority = this.getWaypointPriority(a); + let bPriority = this.getWaypointPriority(b); if (aPriority !== null && bPriority !== null) { // If both have waypointPriority, the one with a lower priority number should come first. - return aPriority - bPriority + return aPriority - bPriority; } else if (aPriority !== null) { // If only `a` has waypointPriority, `a` should come first. - return -1 + return -1; } else if (bPriority !== null) { // If only `b` has waypointPriority, `b` should come first. - return 1 + return 1; } else { // If neither has priority, sort alphabetically. - return a.name.localeCompare(b.name, undefined, {numeric: true, sensitivity: 'base'}); + return a.name.localeCompare(b.name, undefined, { + numeric: true, + sensitivity: "base", + }); } - } - + }; } class WaypointSettingsTab extends PluginSettingTab { @@ -443,106 +601,156 @@ class WaypointSettingsTab extends PluginSettingTab { } display(): void { - const {containerEl} = this; + const { containerEl } = this; containerEl.empty(); - containerEl.createEl('h2', {text: 'Waypoint Settings'}); + containerEl.createEl("h2", { text: "Waypoint Settings" }); new Setting(this.containerEl) .setName("Folder Note Style") .setDesc("Select the style of folder note used.") - .addDropdown((dropdown) => dropdown - .addOption(FolderNoteType.InsideFolder, "Folder Name Inside") - .addOption(FolderNoteType.OutsideFolder, "Folder Name Outside") - .setValue(this.plugin.settings.folderNoteType) - .onChange(async (value) => { - this.plugin.settings.folderNoteType = value; - await this.plugin.saveSettings(); - }) + .addDropdown((dropdown) => + dropdown + .addOption( + FolderNoteType.InsideFolder, + "Folder Name Inside" + ) + .addOption( + FolderNoteType.OutsideFolder, + "Folder Name Outside" + ) + .setValue(this.plugin.settings.folderNoteType) + .onChange(async (value) => { + this.plugin.settings.folderNoteType = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Show Folder Notes") - .setDesc("If enabled, folder notes will be listed alongside other notes in the generated waypoints.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showFolderNotes) - .onChange(async (value) => { - this.plugin.settings.showFolderNotes = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, folder notes will be listed alongside other notes in the generated waypoints." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.showFolderNotes) + .onChange(async (value) => { + this.plugin.settings.showFolderNotes = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Show Non-Markdown Files") - .setDesc("If enabled, non-Markdown files will be listed alongside other notes in the generated waypoints.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showNonMarkdownFiles) - .onChange(async (value) => { - this.plugin.settings.showNonMarkdownFiles = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, non-Markdown files will be listed alongside other notes in the generated waypoints." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.showNonMarkdownFiles) + .onChange(async (value) => { + this.plugin.settings.showNonMarkdownFiles = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Show Enclosing Note") - .setDesc("If enabled, the name of the folder note containing the waypoint will be listed at the top of the generated waypoints.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showEnclosingNote) - .onChange(async (value) => { - this.plugin.settings.showEnclosingNote = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, the name of the folder note containing the waypoint will be listed at the top of the generated waypoints." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.showEnclosingNote) + .onChange(async (value) => { + this.plugin.settings.showEnclosingNote = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Stop Scan at Folder Notes") - .setDesc("If enabled, the waypoint generator will stop scanning nested folders when it encounters a folder note. Otherwise, it will only stop if the folder note contains a waypoint.") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.stopScanAtFolderNotes) - .onChange(async (value) => { - this.plugin.settings.stopScanAtFolderNotes = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, the waypoint generator will stop scanning nested folders when it encounters a folder note. Otherwise, it will only stop if the folder note contains a waypoint." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.stopScanAtFolderNotes) + .onChange(async (value) => { + this.plugin.settings.stopScanAtFolderNotes = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Use WikiLinks") - .setDesc("If enabled, links will be generated like [[My Page]] instead of [My Page](../Folder/My%Page.md).") - .addToggle(toggle => toggle - .setValue(this.plugin.settings.useWikiLinks) - .onChange(async (value) => { - this.plugin.settings.useWikiLinks = value; - await this.plugin.saveSettings(); - }) + .setDesc( + "If enabled, links will be generated like [[My Page]] instead of [My Page](../Folder/My%Page.md)." + ) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.useWikiLinks) + .onChange(async (value) => { + this.plugin.settings.useWikiLinks = value; + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Waypoint Flag") - .setDesc("Text flag that triggers waypoint generation in a folder note. Must be surrounded by double-percent signs.") - .addText(text => text - .setPlaceholder(DEFAULT_SETTINGS.waypointFlag) - .setValue(this.plugin.settings.waypointFlag) - .onChange(async (value) => { - if (value && value.startsWith("%%") && value.endsWith("%%") && value !== "%%" && value !== "%%%" && value !== "%%%%") { - this.plugin.settings.waypointFlag = value; - } else { - this.plugin.settings.waypointFlag = DEFAULT_SETTINGS.waypointFlag; - console.error("Error: Waypoint flag must be surrounded by double-percent signs."); - } - await this.plugin.saveSettings(); - }) + .setDesc( + "Text flag that triggers waypoint generation in a folder note. Must be surrounded by double-percent signs." + ) + .addText((text) => + text + .setPlaceholder(DEFAULT_SETTINGS.waypointFlag) + .setValue(this.plugin.settings.waypointFlag) + .onChange(async (value) => { + if ( + value && + value.startsWith("%%") && + value.endsWith("%%") && + value !== "%%" && + value !== "%%%" && + value !== "%%%%" + ) { + this.plugin.settings.waypointFlag = value; + } else { + this.plugin.settings.waypointFlag = + DEFAULT_SETTINGS.waypointFlag; + console.error( + "Error: Waypoint flag must be surrounded by double-percent signs." + ); + } + await this.plugin.saveSettings(); + }) ); new Setting(containerEl) .setName("Frontmatter key for note priority") - .setDesc("The frontmatter key to set the note order piority when listed in a Waypoint.") - .addText(text => text - .setPlaceholder(DEFAULT_SETTINGS.waypointPriorityKey) - .setValue(this.plugin.settings.waypointPriorityKey) - .onChange(async (value) => { - this.plugin.settings.waypointPriorityKey = value; - await this.plugin.saveSettings() - }) + .setDesc( + "The frontmatter key to set the note order piority when listed in a Waypoint." + ) + .addText((text) => + text + .setPlaceholder(DEFAULT_SETTINGS.waypointPriorityKey) + .setValue(this.plugin.settings.waypointPriorityKey) + .onChange(async (value) => { + this.plugin.settings.waypointPriorityKey = value; + await this.plugin.saveSettings(); + }) ); const postscriptElement = containerEl.createEl("div", { cls: "setting-item", }); - const descriptionElement = postscriptElement.createDiv({cls: "setting-item-description"}); - descriptionElement.createSpan({text: "For instructions on how to use this plugin, check out the README on "}); - descriptionElement.createEl("a", { attr: { "href": "https://github.com/IdreesInc/Waypoint" }, text: "GitHub" }); - descriptionElement.createSpan({text: " or get in touch with the author "}); - descriptionElement.createEl("a", { attr: { "href": "https://twitter.com/IdreesInc" }, text: "@IdreesInc" }); + const descriptionElement = postscriptElement.createDiv({ + cls: "setting-item-description", + }); + descriptionElement.createSpan({ + text: "For instructions on how to use this plugin, check out the README on ", + }); + descriptionElement.createEl("a", { + attr: { href: "https://github.com/IdreesInc/Waypoint" }, + text: "GitHub", + }); + descriptionElement.createSpan({ + text: " or get in touch with the author ", + }); + descriptionElement.createEl("a", { + attr: { href: "https://twitter.com/IdreesInc" }, + text: "@IdreesInc", + }); postscriptElement.appendChild(descriptionElement); } }