diff --git a/src/models/PluginSettingsTab.ts b/src/models/PluginSettingsTab.ts index 26528bc..886360b 100644 --- a/src/models/PluginSettingsTab.ts +++ b/src/models/PluginSettingsTab.ts @@ -7,7 +7,11 @@ export enum SortBy { // eslint-disable-next-line no-unused-vars Alphabetically = "Alphabetically", // eslint-disable-next-line no-unused-vars - ReverseAlphabetically = "Reverse Alphabetically" + ReverseAlphabetically = "Reverse Alphabetically", + // eslint-disable-next-line no-unused-vars + Natural = "Natural", + // eslint-disable-next-line no-unused-vars + ReverseNatural = "Reverse Natural" } export interface PluginSetting { diff --git a/src/types/MarkdownTextRenderer.ts b/src/types/MarkdownTextRenderer.ts index 1a1033e..8d9b647 100644 --- a/src/types/MarkdownTextRenderer.ts +++ b/src/types/MarkdownTextRenderer.ts @@ -199,10 +199,39 @@ export class MarkdownTextRenderer { fileTree.sort((a, b) => a.name.localeCompare(b.name)) } else if (this.plugin.settings.sortIndexFiles === SortBy.ReverseAlphabetically) { fileTree.sort((a, b) => b.name.localeCompare(a.name)) + } else if (this.plugin.settings.sortIndexFiles === SortBy.Natural) { + fileTree.sort((a, b) => this.naturalSort(a.name, b.name)) + } else if (this.plugin.settings.sortIndexFiles === SortBy.ReverseNatural) { + fileTree.sort((a, b) => this.naturalSort(b.name, a.name)) } return fileTree } + private naturalSort(a: string, b: string): number { + const re = /(\d+)|(\D+)/g; + const aParts = a.split(re).filter((item) => item !== undefined && item.length > 0); + const bParts = b.split(re).filter((item) => item !== undefined && item.length > 0) + + for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) { + const aPart = aParts[i]; + const bPart = bParts[i]; + + if (!isNaN(Number(aPart)) && !isNaN(Number(bPart))) { + const numA = Number(aPart); + const numB = Number(bPart); + if (numA !== numB) { + return numA - numB; + } + } else { + if (aPart !== bPart) { + return aPart.localeCompare(bPart); + } + } + } + + return aParts.length - bParts.length; + } + private buildIndentLevel(indentLevel: number): string { let indentText = "" for (let j = 0; j < indentLevel; j++) {