From bc2ea2f3d4f8b8b8fa078584793bc6507d6afe82 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Mon, 6 Apr 2020 20:35:24 +0300 Subject: [PATCH] errors: fix caret position on lines with tabs --- vlib/v/util/errors.v | 53 ++++++++++++++++++++++++-------------------- vlib/v/util/util.v | 11 +++++++++ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/vlib/v/util/errors.v b/vlib/v/util/errors.v index cac3979581..433d0e91d5 100644 --- a/vlib/v/util/errors.v +++ b/vlib/v/util/errors.v @@ -65,38 +65,43 @@ pub fn formated_error(kind string /*error or warn*/, emsg string, filepath strin break } } - column = pos.pos - p + column = util.imax(0, pos.pos - p - 1) } position := '${path}:${pos.line_nr+1}:$column:' // - bline := pos.line_nr - error_context_before - aline := pos.line_nr + error_context_after + bline := util.imax(0, pos.line_nr - error_context_before) + aline := util.imin(source_lines.len-1, pos.line_nr + error_context_after) mut clines := []string - for iline, sline in source_lines { - if iline >= bline && iline <= aline { - mut cline := '${iline+1:5d}| $sline' - if iline == pos.line_nr && emanager.support_color { - cline = term.red( cline ) - } - clines << cline - // - if iline == pos.line_nr { - // The pointerline should have the same spaces/tabs as the offending - // line, so that it prints the ^ character exactly on the *same spot* - // where it is needed. That is the reason we can not just - // use strings.repeat(` `, col) to form it. - mut pointerline := []string - for i, c in cline { - if i < column { - x := if c.is_space() { c } else { ` ` } + tab_spaces := ' ' + for iline := bline; iline <= aline; iline++ { + sline := source_lines[iline] + mut cline := '${iline+1:5d}| ' + sline.replace('\t', tab_spaces) + if iline == pos.line_nr && emanager.support_color { + cline = term.red( cline ) + } + clines << cline + // + if iline == pos.line_nr { + // The pointerline should have the same spaces/tabs as the offending + // line, so that it prints the ^ character exactly on the *same spot* + // where it is needed. That is the reason we can not just + // use strings.repeat(` `, col) to form it. + mut pointerline := []string + for i, c in sline { + if i < column { + mut x := c + if x == `\t` { + pointerline << tab_spaces + }else{ + x = if x.is_space() { c } else { ` ` } pointerline << x.str() - continue } - pointerline << if emanager.support_color { term.bold(term.blue('^')) } else { '^' } - break + continue } - clines << ' ' + pointerline.join('') + pointerline << if emanager.support_color { term.bold(term.blue('^')) } else { '^' } + break } + clines << '${0:5d}| ' + pointerline.join('') } } source_context += clines.join('\n') diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 932d40bd0b..a9eab58f18 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -174,3 +174,14 @@ pub fn read_file(file_path string) ?string { } return raw_text } + + +[inline] +fn imin(a, b int) int { + return if a < b { a } else { b } +} + +[inline] +fn imax(a, b int) int { + return if a > b { a } else { b } +}