diff --git a/package.json b/package.json index 619cb07..3a665e8 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,16 @@ "type": "string", "default": null, "description": "Specifies a custom location to use when discovering tours." + }, + "codetour.sortBy": { + "type": "string", + "enum": [ + "title", + "dateModified", + "dateCreated" + ], + "default": "title", + "description": "Specifies how to sort tours in the Start Tour dialog." } } }, diff --git a/src/store/provider.ts b/src/store/provider.ts index 72ae4f9..4d4f396 100644 --- a/src/store/provider.ts +++ b/src/store/provider.ts @@ -54,10 +54,52 @@ export async function discoverTours(): Promise { }) ); + const flatTours = tours.flat(); + const sortBy = vscode.workspace + .getConfiguration(EXTENSION_NAME) + .get("sortBy", "title"); + + // Pre-fetch file stats for date-based sorting + const tourStats = new Map(); + if (sortBy === "dateModified" || sortBy === "dateCreated") { + await Promise.all( + flatTours.map(async tour => { + try { + const stat = await vscode.workspace.fs.stat(vscode.Uri.parse(tour.id)); + tourStats.set(tour.id, stat); + } catch { + // Ignore errors - will fall back to title sorting for this tour + } + }) + ); + } + + const sortFn = (a: CodeTour, b: CodeTour) => { + switch (sortBy) { + case "dateModified": { + const aStat = tourStats.get(a.id); + const bStat = tourStats.get(b.id); + if (aStat && bStat) { + return bStat.mtime - aStat.mtime; // newest first + } + return a.title.localeCompare(b.title); + } + case "dateCreated": { + const aStat = tourStats.get(a.id); + const bStat = tourStats.get(b.id); + if (aStat && bStat) { + return bStat.ctime - aStat.ctime; // newest first + } + return a.title.localeCompare(b.title); + } + default: + return a.title.localeCompare(b.title); + } + }; + runInAction(() => { - store.tours = tours - .flat() - .sort((a, b) => a.title.localeCompare(b.title)) + store.tours = flatTours + .sort(sortFn) .filter(tour => !tour.when || jexl.evalSync(tour.when, TOUR_CONTEXT)); if (store.activeTour) {