From d8c6fbfbc4b0edd7b63cb32790aaa73ccf87d7a4 Mon Sep 17 00:00:00 2001 From: jonathan-oron Date: Wed, 21 Jan 2026 15:00:43 +0000 Subject: [PATCH] Add option to sort tours by date Add a new `codetour.sortBy` setting that allows users to sort tours by: - `title` (default, current alphabetical behavior) - `dateModified` (newest modified first) - `dateCreated` (newest created first) Uses VS Code's workspace.fs.stat API for cross-platform compatibility (works in both desktop and web environments). Fixes #317 Co-Authored-By: Claude Opus 4.5 --- package.json | 10 +++++++++ src/store/provider.ts | 48 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-) 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) {