Skip to main content

underline

Function underline 

Source
fn underline(
    src: &str,
    line_start: usize,
    span_start: usize,
    at: usize,
) -> (String, String)
Expand description

Returns the indentation and the underline for the span between span_start and at.

The two returned strings are meant to be concatenated and are followed by the caret that points at the character, which caused the error:

1 |    foo-bar
  |    ~~~~~~^
    ^^^ indentation
       ^^^^^^ underline

There are two scenarios that we need to handle to achieve a correct underline and to place the caret pointer at the correct position:

  • Multi-width UTF-8 graphemes. To handle this, we measure the display width of each character on the error line, and insert the correct amount of spaces/~.

  • Tabs cannot be handled 100% correctly, as their rendered width depends on the terminal’s tab stops. We work around the issue as follows:

    • When encountering a tab while building the indentation, we simply place a \t at the same position as in the string above.
    • When encountering a tab while building the underline, we insert a literal \t there as well. This visually breaks the underline, but as there’s no way to determine its display width, we accept the compromise of a broken indicator line in favor of a correct offset for the pointer.