(filePath: string, maxLen: number = 35)
| 39 | * Example: /path/to/a/very/long/file.txt -> /path/.../long/file.txt |
| 40 | */ |
| 41 | export function shortenPath(filePath: string, maxLen: number = 35): string { |
| 42 | if (filePath.length <= maxLen) { |
| 43 | return filePath; |
| 44 | } |
| 45 | |
| 46 | const parsedPath = path.parse(filePath); |
| 47 | const root = parsedPath.root; |
| 48 | const separator = path.sep; |
| 49 | |
| 50 | // Get segments of the path *after* the root |
| 51 | const relativePath = filePath.substring(root.length); |
| 52 | const segments = relativePath.split(separator).filter((s) => s !== ''); // Filter out empty segments |
| 53 | |
| 54 | // Handle cases with no segments after root (e.g., "/", "C:\") or only one segment |
| 55 | if (segments.length <= 1) { |
| 56 | // Fall back to simple start/end truncation for very short paths or single segments |
| 57 | const keepLen = Math.floor((maxLen - 3) / 2); |
| 58 | // Ensure keepLen is not negative if maxLen is very small |
| 59 | if (keepLen <= 0) { |
| 60 | return filePath.substring(0, maxLen - 3) + '...'; |
| 61 | } |
| 62 | const start = filePath.substring(0, keepLen); |
| 63 | const end = filePath.substring(filePath.length - keepLen); |
| 64 | return `${start}...${end}`; |
| 65 | } |
| 66 | |
| 67 | const firstDir = segments[0]; |
| 68 | const lastSegment = segments[segments.length - 1]; |
| 69 | const startComponent = root + firstDir; |
| 70 | |
| 71 | const endPartSegments: string[] = []; |
| 72 | // Base length: separator + "..." + lastDir |
| 73 | let currentLength = separator.length + lastSegment.length; |
| 74 | |
| 75 | // Iterate backwards through segments (excluding the first one) |
| 76 | for (let i = segments.length - 2; i >= 0; i--) { |
| 77 | const segment = segments[i]; |
| 78 | // Length needed if we add this segment: current + separator + segment |
| 79 | const lengthWithSegment = currentLength + separator.length + segment.length; |
| 80 | |
| 81 | if (lengthWithSegment <= maxLen) { |
| 82 | endPartSegments.unshift(segment); // Add to the beginning of the end part |
| 83 | currentLength = lengthWithSegment; |
| 84 | } else { |
| 85 | break; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | let result = endPartSegments.join(separator) + separator + lastSegment; |
| 90 | |
| 91 | if (currentLength > maxLen) { |
| 92 | return result; |
| 93 | } |
| 94 | |
| 95 | // Construct the final path |
| 96 | result = startComponent + separator + result; |
| 97 | |
| 98 | // As a final check, if the result is somehow still too long |
no outgoing calls
no test coverage detected