diff --git a/README.md b/README.md index 66f10e5..0f22da1 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,28 @@ 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 +--- + +# 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. + +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** diff --git a/main.ts b/main.ts index def93e6..64686ab 100644 --- a/main.ts +++ b/main.ts @@ -1,19 +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 + waypointFlag: string; + stopScanAtFolderNotes: boolean; + showFolderNotes: boolean; + showNonMarkdownFiles: boolean; + debugLogging: boolean; + useWikiLinks: boolean; + showEnclosingNote: boolean; + folderNoteType: string; + waypointPriorityKey: string; } const DEFAULT_SETTINGS: WaypointSettings = { @@ -24,8 +34,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 { static readonly BEGIN_WAYPOINT = "%% Begin Waypoint %%"; @@ -38,37 +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", 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", (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. @@ -84,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.updateParentWaypoint(file.parent, this.settings.folderNoteType === FolderNoteType.OutsideFolder); - return; + 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; } @@ -131,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); @@ -146,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}`; @@ -160,20 +215,43 @@ 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); - 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")); + } } /** @@ -184,22 +262,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 +298,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; } } @@ -237,33 +342,59 @@ 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'}); - }); + 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; } @@ -288,62 +419,78 @@ export default class Waypoint extends Plugin { this.log("Updating changed folders..."); this.foldersWithChanges.forEach((folder) => { this.log("Updating " + folder.path); - this.updateParentWaypoint(folder, true); + 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 the ancestor waypoint (if any) of the given file/folder. + * 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 */ - updateParentWaypoint = async (node: TAbstractFile, includeCurrentNode: boolean) => { - const parentWaypoint = await this.locateParentWaypoint(node, includeCurrentNode); - if (parentWaypoint !== null) { - this.updateWaypoint(parentWaypoint); + 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. + * 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 ancestor waypoint, or null if none was found + * @returns The list of ancestor waypoints, or an empty list if none were found */ - async locateParentWaypoint(node: TAbstractFile, includeCurrentNode: boolean): Promise { - this.log("Locating parent waypoint of " + node.name); + 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) { + 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)) { - this.log("Found parent waypoint!"); - return 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("No parent waypoint found."); - return null; + this.log("Found " + ancestorWaypoints.length + " ancestor waypoints."); + return ancestorWaypoints; } /** @@ -352,7 +499,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 { @@ -360,19 +509,88 @@ export default class Waypoint extends Plugin { } } - log(message: string) { + log(message?: any) { 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() { await this.saveData(this.settings); } + + 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" + ) { + return fileCache.frontmatter[this.settings.waypointPriorityKey]; + } else { + return null; + } + } 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 + ) { + // 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; + } + }; + + sortWithPriority = (a: TAbstractFile, b: TAbstractFile): number => { + 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; + } else if (aPriority !== null) { + // If only `a` has waypointPriority, `a` should come first. + return -1; + } else if (bPriority !== null) { + // If only `b` has waypointPriority, `b` should come first. + return 1; + } else { + // If neither has priority, sort alphabetically. + return a.name.localeCompare(b.name, undefined, { + numeric: true, + sensitivity: "base", + }); + } + }; } class WaypointSettingsTab extends PluginSettingTab { @@ -384,95 +602,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(); + }) ); 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); } } 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-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": { 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