* Computes visible line indices based on collapsed regions. * Only block regions hide lines; string regions just truncate content. * * @param totalLines - Total number of lines * @param collapsedLines - Set of line indices that are collapsed (start lines of regions) * @param regions - Map of co
( totalLines: number, collapsedLines: Set<number>, regions: Map<number, CollapsibleRegion> )
| 262 | * @returns Sorted array of visible line indices |
| 263 | */ |
| 264 | function computeVisibleLineIndices( |
| 265 | totalLines: number, |
| 266 | collapsedLines: Set<number>, |
| 267 | regions: Map<number, CollapsibleRegion> |
| 268 | ): number[] { |
| 269 | if (collapsedLines.size === 0) { |
| 270 | return Array.from({ length: totalLines }, (_, i) => i) |
| 271 | } |
| 272 | |
| 273 | // Build sorted list of hidden ranges (only for block regions, not string regions) |
| 274 | const hiddenRanges: Array<{ start: number; end: number }> = [] |
| 275 | for (const startLine of collapsedLines) { |
| 276 | const region = regions.get(startLine) |
| 277 | if (region && region.type === 'block' && region.endLine > region.startLine + 1) { |
| 278 | hiddenRanges.push({ start: region.startLine + 1, end: region.endLine - 1 }) |
| 279 | } |
| 280 | } |
| 281 | hiddenRanges.sort((a, b) => a.start - b.start) |
| 282 | |
| 283 | // Merge overlapping ranges |
| 284 | const merged: Array<{ start: number; end: number }> = [] |
| 285 | for (const range of hiddenRanges) { |
| 286 | if (merged.length === 0 || merged[merged.length - 1].end < range.start - 1) { |
| 287 | merged.push(range) |
| 288 | } else { |
| 289 | merged[merged.length - 1].end = Math.max(merged[merged.length - 1].end, range.end) |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | // Build visible indices by skipping hidden ranges |
| 294 | const visible: number[] = [] |
| 295 | let rangeIdx = 0 |
| 296 | for (let i = 0; i < totalLines; i++) { |
| 297 | while (rangeIdx < merged.length && merged[rangeIdx].end < i) { |
| 298 | rangeIdx++ |
| 299 | } |
| 300 | if (rangeIdx < merged.length && i >= merged[rangeIdx].start && i <= merged[rangeIdx].end) { |
| 301 | continue |
| 302 | } |
| 303 | visible.push(i) |
| 304 | } |
| 305 | |
| 306 | return visible |
| 307 | } |
| 308 | |
| 309 | /** |
| 310 | * Truncates a long string value in a JSON line for collapsed display. |
no test coverage detected