Improve readability by wrapping error messages and trimming source code.
(
self, messages: list[str], fixed_terminal_width: int | None = None
)
| 748 | ) |
| 749 | |
| 750 | def fit_in_terminal( |
| 751 | self, messages: list[str], fixed_terminal_width: int | None = None |
| 752 | ) -> list[str]: |
| 753 | """Improve readability by wrapping error messages and trimming source code.""" |
| 754 | width = fixed_terminal_width or get_terminal_width() |
| 755 | new_messages = messages.copy() |
| 756 | for i, error in enumerate(messages): |
| 757 | # TODO: detecting source code highlights through an indent can be surprising. |
| 758 | if not error.startswith(CODE_START) and ": error:" in error: |
| 759 | loc, msg = error.split("error:", maxsplit=1) |
| 760 | msg = soft_wrap(msg, width, first_offset=len(loc) + len("error: ")) |
| 761 | new_messages[i] = loc + "error:" + msg |
| 762 | elif error.startswith(CODE_START) and not self.is_marker_line(error): |
| 763 | # Restore original error message and error location. |
| 764 | error = error[DEFAULT_SOURCE_OFFSET:] |
| 765 | marker_line = messages[i + 1] |
| 766 | marker_column = marker_line.index("^") |
| 767 | column = marker_column - DEFAULT_SOURCE_OFFSET |
| 768 | if "~" not in marker_line: |
| 769 | marker = "^" |
| 770 | else: |
| 771 | # +1 because both ends are included |
| 772 | marker = marker_line[marker_column : marker_line.rindex("~") + 1] |
| 773 | |
| 774 | # Let source have some space also on the right side, plus 6 |
| 775 | # to accommodate ... on each side. |
| 776 | max_len = width - DEFAULT_SOURCE_OFFSET - 6 |
| 777 | source_line, offset = trim_source_line(error, max_len, column, MINIMUM_WIDTH) |
| 778 | |
| 779 | new_messages[i] = " " * DEFAULT_SOURCE_OFFSET + source_line |
| 780 | # Also adjust the error marker position and trim error marker is needed. |
| 781 | new_marker_line = " " * (DEFAULT_SOURCE_OFFSET + column - offset) + marker |
| 782 | if len(new_marker_line) > len(new_messages[i]) and len(marker) > 3: |
| 783 | new_marker_line = new_marker_line[: len(new_messages[i]) - 3] + "..." |
| 784 | new_messages[i + 1] = new_marker_line |
| 785 | return new_messages |
| 786 | |
| 787 | def colorize(self, error: str) -> str: |
| 788 | """Colorize an output line by highlighting the status and error code.""" |
no test coverage detected