diff --git a/src/PathUtils.ts b/src/PathUtils.ts index 7c96559a..1d0b9e6e 100644 --- a/src/PathUtils.ts +++ b/src/PathUtils.ts @@ -2,7 +2,9 @@ import path from "node:path"; export function isAbsolutePathLike(value: string): boolean { const trimmed = value.trim(); - return path.isAbsolute(trimmed) || isWindowsAbsolutePath(trimmed); + return path.isAbsolute(trimmed) + || isWindowsAbsolutePath(trimmed) + || isWslWindowsMountPath(trimmed); } export function arePathsEqual(left: string, right: string): boolean { @@ -29,6 +31,11 @@ export function normalizePathForComparison(value: string): string { return trimTrailingPathSeparators(normalized).toLowerCase(); } + if (isWslWindowsMountPath(trimmed)) { + const normalized = path.posix.normalize(trimmed); + return trimTrailingPathSeparators(normalized).toLowerCase(); + } + const pathForComparison = path.isAbsolute(trimmed) ? trimmed : trimmed.replace(/\\/g, "/"); @@ -41,8 +48,15 @@ function isWindowsAbsolutePath(value: string): boolean { return /^[A-Za-z]:\//.test(portableValue) || /^\/\/[^/]+\/[^/]+/.test(portableValue); } +function isWslWindowsMountPath(value: string): boolean { + return /^\/mnt\/[A-Za-z](?:\/|$)/.test(value); +} + function shouldComparePathCaseInsensitive(value: string): boolean { - return isWindowsAbsolutePath(value) || /^[A-Za-z]:/.test(value) || value.includes("\\"); + return isWindowsAbsolutePath(value) + || isWslWindowsMountPath(value) + || /^[A-Za-z]:/.test(value) + || value.includes("\\"); } function trimTrailingPathSeparators(value: string): string { diff --git a/src/__tests__/PathUtils.test.ts b/src/__tests__/PathUtils.test.ts index 78ff173d..4c75d70c 100644 --- a/src/__tests__/PathUtils.test.ts +++ b/src/__tests__/PathUtils.test.ts @@ -21,10 +21,24 @@ describe("PathUtils", () => { expect(arePathsEqual("/repo/project", "/repo/Project")).toBe(false); }); + it("compares WSL Windows mount paths case-insensitively", () => { + expect(arePathsEqual( + "/mnt/c/Users/Me/Notes/MyVault/", + "/mnt/c/users/me/notes/myvault", + )).toBe(true); + expect(normalizePathForComparison("/mnt/c/Users/Me/Notes/MyVault/")) + .toBe("/mnt/c/users/me/notes/myvault"); + expect(arePathBasenamesEqual( + "/mnt/c/Users/Me/Notes/MyVault", + "myvault", + )).toBe(true); + }); + it("detects Windows absolute paths on any host platform", () => { expect(isAbsolutePathLike("D:/workspace/sample-project")).toBe(true); expect(isAbsolutePathLike("D:\\workspace\\sample-project")).toBe(true); expect(isAbsolutePathLike("\\\\Server\\Share\\Project")).toBe(true); + expect(isAbsolutePathLike("/mnt/c/Users/Me/Notes/MyVault")).toBe(true); expect(isAbsolutePathLike("sample-project")).toBe(false); });