-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlib-file.mts
More file actions
143 lines (129 loc) · 3.89 KB
/
lib-file.mts
File metadata and controls
143 lines (129 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Path handling utilities for implish
// Handles conversion between implish file paths (%file/path) and native OS paths
/**
* Convert implish file path to native OS path
* On Windows: %/d/path → d:/path
* On Unix: %/path → /path
*/
export function toNativePath(implishPath: string): string {
// Strip the leading % if present
let path = implishPath.startsWith('%') ? implishPath.slice(1) : implishPath
// On Windows, convert /d/path to d:/path
if (process.platform === 'win32') {
let driveMatch = path.match(/^\/([a-zA-Z])\/(.*)/)
if (driveMatch) {
return driveMatch[1] + ':/' + driveMatch[2]
}
// Also handle /d (just the drive)
let driveOnlyMatch = path.match(/^\/([a-zA-Z])$/)
if (driveOnlyMatch) {
return driveOnlyMatch[1] + ':/'
}
}
return path
}
/**
* Convert native OS path to implish file path
* On Windows: d:/path → %/d/path or D:\path → %/d/path
* On Unix: /path → %/path
*/
export function toImplishPath(nativePath: string): string {
// On Windows, convert d:/path or d:\path to %/d/path
if (process.platform === 'win32') {
let driveMatch = nativePath.match(/^([a-zA-Z]):[\/\\](.*)/)
if (driveMatch) {
return '%/' + driveMatch[1].toLowerCase() + '/' + driveMatch[2].replace(/\\/g, '/')
}
// Handle bare drive letter d: or d:\
let driveOnlyMatch = nativePath.match(/^([a-zA-Z]):[\/\\]?$/)
if (driveOnlyMatch) {
return '%/' + driveOnlyMatch[1].toLowerCase() + '/'
}
}
// For Unix or relative paths, just prepend %
return '%' + nativePath
}
/**
* Parse a partial implish path for tab completion
* Returns: {nativeDir, prefix, isWindowsDrive, driveLetter, rest}
*/
export function parsePartialPath(partialPath: string): {
nativeDir: string,
prefix: string,
isWindowsDrive: boolean,
driveLetter?: string,
rest?: string
} {
// Strip the % prefix if present
let path = partialPath.startsWith('%') ? partialPath.slice(1) : partialPath
// Windows drive path: /d/ or /d/some/path
if (process.platform === 'win32') {
let match = path.match(/^\/([a-zA-Z])(\/|$)(.*)/)
if (match) {
let driveLetter = match[1]
let rest = match[3] || ''
if (rest.includes('/') || rest.includes('\\')) {
let lastSep = Math.max(rest.lastIndexOf('/'), rest.lastIndexOf('\\'))
return {
nativeDir: driveLetter + ':/' + rest.slice(0, lastSep),
prefix: rest.slice(lastSep + 1),
isWindowsDrive: true,
driveLetter,
rest
}
} else {
return {
nativeDir: driveLetter + ':/',
prefix: rest,
isWindowsDrive: true,
driveLetter,
rest
}
}
}
}
// Regular path
if (path.includes('/') || path.includes('\\')) {
let lastSep = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'))
return {
nativeDir: path.slice(0, lastSep) || '.',
prefix: path.slice(lastSep + 1),
isWindowsDrive: false
}
}
// No directory separator - current directory
return {
nativeDir: '.',
prefix: path,
isWindowsDrive: false
}
}
/**
* Reconstruct an implish path from parsed components
*/
export function reconstructImplishPath(
parsed: ReturnType<typeof parsePartialPath>,
filename: string,
isDirectory: boolean
): string {
let fullPath: string
if (parsed.isWindowsDrive && parsed.driveLetter) {
// Reconstruct as %/d/path
let rest = parsed.rest || ''
let dirPart = rest.includes('/')
? rest.slice(0, rest.lastIndexOf('/') + 1)
: ''
fullPath = '%/' + parsed.driveLetter + '/' + dirPart + filename
} else if (parsed.nativeDir === '.') {
// Current directory
fullPath = '%' + filename
} else {
// Regular path
fullPath = '%' + parsed.nativeDir + '/' + filename
}
// Add trailing / for directories
if (isDirectory && !fullPath.endsWith('/')) {
fullPath += '/'
}
return fullPath
}