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
^^^^^^ underlineThere 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
\tat the same position as in the string above. - When encountering a tab while building the underline, we insert a literal
\tthere 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.
- When encountering a tab while building the indentation, we simply place a