1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- /* @flow */
-
- const range = 2
-
- export function generateCodeFrame (
- source: string,
- start: number = 0,
- end: number = source.length
- ): string {
- const lines = source.split(/\r?\n/)
- let count = 0
- const res = []
- for (let i = 0; i < lines.length; i++) {
- count += lines[i].length + 1
- if (count >= start) {
- for (let j = i - range; j <= i + range || end > count; j++) {
- if (j < 0 || j >= lines.length) continue
- res.push(`${j + 1}${repeat(` `, 3 - String(j + 1).length)}| ${lines[j]}`)
- const lineLength = lines[j].length
- if (j === i) {
- // push underline
- const pad = start - (count - lineLength) + 1
- const length = end > count ? lineLength - pad : end - start
- res.push(` | ` + repeat(` `, pad) + repeat(`^`, length))
- } else if (j > i) {
- if (end > count) {
- const length = Math.min(end - count, lineLength)
- res.push(` | ` + repeat(`^`, length))
- }
- count += lineLength + 1
- }
- }
- break
- }
- }
- return res.join('\n')
- }
-
- function repeat (str, n) {
- let result = ''
- if (n > 0) {
- while (true) { // eslint-disable-line
- if (n & 1) result += str
- n >>>= 1
- if (n <= 0) break
- str += str
- }
- }
- return result
- }
|