48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
export type WslUncPathInfo = {
|
|
distro: string
|
|
linuxPath: string
|
|
}
|
|
|
|
export function parseWslUncPath(path: string): WslUncPathInfo | null {
|
|
const normalized = path.replace(/\\/g, '/')
|
|
const match = normalized.match(/^\/\/(wsl\.localhost|wsl\$)\/([^/]+)(\/.*)?$/i)
|
|
if (!match) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
distro: match[2],
|
|
linuxPath: match[3] || '/'
|
|
}
|
|
}
|
|
|
|
export function isWslUncPath(path: string): boolean {
|
|
return parseWslUncPath(path) !== null
|
|
}
|
|
|
|
/** Convert an absolute Linux path in a known WSL distro to its Windows form. */
|
|
export function toWindowsWslPath(linuxPath: string, distro: string): string {
|
|
const mntMatch = linuxPath.match(/^\/mnt\/([a-z])(\/.*)?$/)
|
|
if (mntMatch) {
|
|
const rest = (mntMatch[2] || '').replace(/\//g, '\\')
|
|
return `${mntMatch[1].toUpperCase()}:${rest || '\\'}`
|
|
}
|
|
|
|
return `\\\\wsl.localhost\\${distro}${linuxPath.replace(/\//g, '\\')}`
|
|
}
|
|
|
|
// Why: Windows folds the share (\\wsl$ aliases \\wsl.localhost), the distro, and
|
|
// drvfs /mnt/<drive> tails case-insensitively; the rest of the Linux path is not.
|
|
export function foldWslUncPathCaseInsensitiveParts(path: string): string | null {
|
|
const parsed = parseWslUncPath(path)
|
|
if (!parsed) {
|
|
return null
|
|
}
|
|
// Why: the drvfs automount is literally lowercase /mnt — a case-variant like
|
|
// /MNT is an ordinary case-sensitive Linux dir and must not be folded.
|
|
const linuxPath = /^\/mnt\/[a-zA-Z](?:\/|$)/.test(parsed.linuxPath)
|
|
? parsed.linuxPath.toLowerCase()
|
|
: parsed.linuxPath
|
|
return `//wsl.localhost/${parsed.distro.toLowerCase()}${linuxPath === '/' ? '' : linuxPath}`
|
|
}
|