codeframe.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. const range: number = 2
  2. export function generateCodeFrame(
  3. source: string,
  4. start: number = 0,
  5. end: number = source.length
  6. ): string {
  7. const lines = source.split(/\r?\n/)
  8. let count = 0
  9. const res = []
  10. for (let i = 0; i < lines.length; i++) {
  11. count += lines[i].length + 1
  12. if (count >= start) {
  13. for (let j = i - range; j <= i + range || end > count; j++) {
  14. if (j < 0 || j >= lines.length) continue
  15. res.push(
  16. `${j + 1}${' '.repeat(3 - String(j + 1).length)}| ${lines[j]}`
  17. )
  18. const lineLength = lines[j].length
  19. if (j === i) {
  20. // push underline
  21. const pad = start - (count - lineLength) + 1
  22. const length = end > count ? lineLength - pad : end - start
  23. res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length))
  24. } else if (j > i) {
  25. if (end > count) {
  26. const length = Math.min(end - count, lineLength)
  27. res.push(` | ` + '^'.repeat(length))
  28. }
  29. count += lineLength + 1
  30. }
  31. }
  32. break
  33. }
  34. }
  35. return res.join('\n')
  36. }