feat: improve error messages with context lines
- Show 2 lines of context before and after errors (dimmed) - Fix guessing_game.lux to be non-interactive for testing - Use binary search simulation to demonstrate game logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -241,50 +241,68 @@ pub fn render_diagnostic(
|
||||
colors::RESET
|
||||
));
|
||||
|
||||
// Source code snippet with line numbers
|
||||
let line_num_width = end_line.to_string().len().max(4);
|
||||
// Source code snippet with line numbers and context
|
||||
let context_lines = 2; // Show 2 lines before and after
|
||||
let start_line = line.saturating_sub(context_lines).max(1);
|
||||
let end_context_line = (end_line + context_lines).min(source.lines().count());
|
||||
let line_num_width = end_context_line.to_string().len().max(4);
|
||||
|
||||
// Show the problematic line(s)
|
||||
for line_num in line..=end_line {
|
||||
// Show context before, error lines, and context after
|
||||
for line_num in start_line..=end_context_line {
|
||||
if let Some(source_line) = get_source_line(source, line_num) {
|
||||
// Line number
|
||||
output.push_str(&format!(
|
||||
"{}{:>width$} │{} ",
|
||||
colors::DIM,
|
||||
line_num,
|
||||
colors::RESET,
|
||||
width = line_num_width
|
||||
));
|
||||
let is_error_line = line_num >= line && line_num <= end_line;
|
||||
|
||||
// Source line
|
||||
output.push_str(source_line);
|
||||
output.push('\n');
|
||||
|
||||
// Underline the error span
|
||||
let underline_start = if line_num == line { col - 1 } else { 0 };
|
||||
let underline_end = if line_num == end_line {
|
||||
end_col - 1
|
||||
// Line number (dimmed for context, normal for error lines)
|
||||
if is_error_line {
|
||||
output.push_str(&format!(
|
||||
"{}{:>width$} │{} ",
|
||||
colors::DIM,
|
||||
line_num,
|
||||
colors::RESET,
|
||||
width = line_num_width
|
||||
));
|
||||
// Source line (normal)
|
||||
output.push_str(source_line);
|
||||
} else {
|
||||
source_line.len()
|
||||
};
|
||||
|
||||
let underline_len = underline_end.saturating_sub(underline_start).max(1);
|
||||
|
||||
output.push_str(&format!(
|
||||
"{}{:>width$} │{} ",
|
||||
colors::DIM,
|
||||
"",
|
||||
colors::RESET,
|
||||
width = line_num_width
|
||||
));
|
||||
output.push_str(&" ".repeat(underline_start));
|
||||
output.push_str(&format!(
|
||||
"{}{}{}",
|
||||
severity_color,
|
||||
"^".repeat(underline_len),
|
||||
colors::RESET
|
||||
));
|
||||
// Context lines are fully dimmed
|
||||
output.push_str(&format!(
|
||||
"{}{:>width$} │ {}{}",
|
||||
colors::DIM,
|
||||
line_num,
|
||||
source_line,
|
||||
colors::RESET,
|
||||
width = line_num_width
|
||||
));
|
||||
}
|
||||
output.push('\n');
|
||||
|
||||
// Underline the error span (only for error lines)
|
||||
if is_error_line {
|
||||
let underline_start = if line_num == line { col - 1 } else { 0 };
|
||||
let underline_end = if line_num == end_line {
|
||||
end_col - 1
|
||||
} else {
|
||||
source_line.len()
|
||||
};
|
||||
|
||||
let underline_len = underline_end.saturating_sub(underline_start).max(1);
|
||||
|
||||
output.push_str(&format!(
|
||||
"{}{:>width$} │{} ",
|
||||
colors::DIM,
|
||||
"",
|
||||
colors::RESET,
|
||||
width = line_num_width
|
||||
));
|
||||
output.push_str(&" ".repeat(underline_start));
|
||||
output.push_str(&format!(
|
||||
"{}{}{}",
|
||||
severity_color,
|
||||
"^".repeat(underline_len),
|
||||
colors::RESET
|
||||
));
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user