Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 | 2x 2x 86x 86x 86x 86x 86x 86x 86x 85x 85x 85x 85x 85x 86x 202x 202x 202x 202x 85x 433x 256x 256x 256x 256x 256x 256x 256x 256x 433x 433x 85x 85x 85x 85x 85x 85x 433x 89x 18x 18x 18x 89x 89x 433x 85x 85x 202x 85x 85x | const range: number = 2 export function generateCodeFrame( source: string, start = 0, end: number = source.length, ): string { // Ensure start and end are within the source length start = Math.max(0, Math.min(start, source.length)) end = Math.max(0, Math.min(end, source.length)) if (start > end) return '' // Split the content into individual lines but capture the newline sequence // that separated each line. This is important because the actual sequence is // needed to properly take into account the full line length for offset // comparison let lines = source.split(/(\r?\n)/) // Separate the lines and newline sequences into separate arrays for easier referencing const newlineSequences = lines.filter((_, idx) => idx % 2 === 1) lines = lines.filter((_, idx) => idx % 2 === 0) let count = 0 const res: string[] = [] for (let i = 0; i < lines.length; i++) { count += lines[i].length + ((newlineSequences[i] && newlineSequences[i].length) || 0) if (count >= start) { for (let j = i - range; j <= i + range || end > count; j++) { if (j < 0 || j >= lines.length) continue const line = j + 1 res.push( `${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${ lines[j] }`, ) const lineLength = lines[j].length const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0 if (j === i) { // push underline const pad = start - (count - (lineLength + newLineSeqLength)) const length = Math.max( 1, end > count ? lineLength - pad : end - start, ) res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)) } else if (j > i) { if (end > count) { const length = Math.max(Math.min(end - count, lineLength), 1) res.push(` | ` + '^'.repeat(length)) } count += lineLength + newLineSeqLength } } break } } return res.join('\n') } |