vxx2 / vlib / v3 / errors / details.v
41 lines · 39 sloc · 1.13 KB · 6c4d26f1f98c5464b012a375667ab345e462f7e0
Raw
1module errors
2
3import os
4import v3.token
5
6// details supports details handling for errors.
7pub fn details(file &token.File, pos token.Position, row_padding int) string {
8 if file.name == '' {
9 return 'at ${pos.line}:${pos.column}'
10 }
11 src := os.read_file(file.name) or { return 'at ${pos.line}:${pos.column} in `${file.name}`' }
12 line_start := if pos.line - row_padding - 1 > 0 {
13 file.line_start(pos.line - row_padding)
14 } else {
15 0
16 }
17 mut line_end := pos.offset + 1
18 for i := 0; line_end < src.len; {
19 if src[line_end] == `\n` {
20 i++
21 if i == row_padding + 1 {
22 break
23 }
24 }
25 line_end++
26 }
27 lines_src := src[line_start..line_end].split('\n')
28 line_no_start, _ := file.find_line_and_column(line_start)
29 mut lines_src_formatted := []string{}
30 for i in 0 .. lines_src.len {
31 line_no := line_no_start + i
32 line_src := lines_src[i]
33 line_spaces := line_src.replace('\t', ' ')
34 lines_src_formatted << '${line_no:5d} | ' + line_spaces
35 if line_no == pos.line {
36 space_diff := line_spaces.len - line_src.len
37 lines_src_formatted << ' ' + ' '.repeat(space_diff + pos.column - 1) + '^'
38 }
39 }
40 return lines_src_formatted.join('\n')
41}
42