Feat: lots of improvements
Some checks failed
Deploy Website / deploy (push) Failing after 4m49s

This commit is contained in:
2026-02-08 13:52:40 +01:00
parent d6bbae173b
commit bc5d12e53a
34 changed files with 333 additions and 123 deletions

View File

@@ -84,6 +84,9 @@ struct ForthHighlighter;
impl CodeHighlighter for ForthHighlighter {
fn highlight(&self, line: &str) -> Vec<(Style, String)> {
highlight::highlight_line(line)
.into_iter()
.map(|(s, t, _)| (s, t))
.collect()
}
}

View File

@@ -202,24 +202,27 @@ fn classify_word(word: &str, user_words: &HashSet<String>) -> (TokenKind, bool)
(TokenKind::Default, false)
}
pub fn highlight_line(line: &str) -> Vec<(Style, String)> {
highlight_line_with_runtime(line, &[], &[], &EMPTY_SET)
pub fn highlight_line(line: &str) -> Vec<(Style, String, bool)> {
highlight_line_with_runtime(line, &[], &[], &[], &EMPTY_SET)
}
pub fn highlight_line_with_runtime(
line: &str,
executed_spans: &[SourceSpan],
selected_spans: &[SourceSpan],
resolved: &[(SourceSpan, String)],
user_words: &HashSet<String>,
) -> Vec<(Style, String)> {
) -> Vec<(Style, String, bool)> {
let tokens = tokenize_line(line, user_words);
let mut result = Vec::new();
let mut last_end = 0;
let gap_style = TokenKind::gap_style();
let theme = theme::get();
let annotation_style = Style::default().fg(theme.ui.text_dim);
for token in tokens {
for token in &tokens {
if token.start > last_end {
result.push((gap_style, line[last_end..token.start].to_string()));
result.push((gap_style, line[last_end..token.start].to_string(), false));
}
let is_selected = selected_spans
@@ -233,19 +236,25 @@ pub fn highlight_line_with_runtime(
if token.varargs {
style = style.add_modifier(Modifier::UNDERLINED);
}
let theme = theme::get();
if is_selected {
style = style.bg(theme.syntax.selected_bg).add_modifier(Modifier::BOLD);
} else if is_executed {
style = style.bg(theme.syntax.executed_bg);
}
result.push((style, line[token.start..token.end].to_string()));
result.push((style, line[token.start..token.end].to_string(), false));
for (span, display) in resolved {
if token.start == span.start as usize {
result.push((annotation_style, format!(" [{display}]"), true));
}
}
last_end = token.end;
}
if last_end < line.len() {
result.push((gap_style, line[last_end..].to_string()));
result.push((gap_style, line[last_end..].to_string(), false));
}
result

View File

@@ -45,6 +45,30 @@ fn adjust_spans_for_line(
.collect()
}
fn adjust_resolved_for_line(
resolved: &[(SourceSpan, String)],
line_start: usize,
line_len: usize,
) -> Vec<(SourceSpan, String)> {
let ls = line_start as u32;
let ll = line_len as u32;
resolved
.iter()
.filter_map(|(s, display)| {
if s.end <= ls || s.start >= ls + ll {
return None;
}
Some((
SourceSpan {
start: s.start.max(ls) - ls,
end: (s.end.min(ls + ll)) - ls,
},
display.clone(),
))
})
.collect()
}
pub fn render(frame: &mut Frame, app: &App, link: &LinkState, snapshot: &SequencerSnapshot, elapsed: Duration) {
let term = frame.area();
@@ -627,6 +651,15 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
None
};
let resolved_display: Vec<(SourceSpan, String)> = trace
.map(|t| {
t.resolved
.iter()
.map(|(s, v)| (*s, v.display()))
.collect()
})
.unwrap_or_default();
let mut line_start = 0usize;
let lines: Vec<Line> = script
.lines()
@@ -642,14 +675,19 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
line_start,
line_str.len(),
);
highlight_line_with_runtime(line_str, &exec, &sel, &user_words)
let res = adjust_resolved_for_line(
&resolved_display,
line_start,
line_str.len(),
);
highlight_line_with_runtime(line_str, &exec, &sel, &res, &user_words)
} else {
highlight_line_with_runtime(line_str, &[], &[], &user_words)
highlight_line_with_runtime(line_str, &[], &[], &[], &user_words)
};
line_start += line_str.len() + 1;
let spans: Vec<Span> = tokens
.into_iter()
.map(|(style, text)| Span::styled(text, style))
.map(|(style, text, _)| Span::styled(text, style))
.collect();
Line::from(spans)
})
@@ -712,16 +750,26 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
offset += line.len() + 1;
}
let highlighter = |row: usize, line: &str| -> Vec<(Style, String)> {
let resolved_display: Vec<(SourceSpan, String)> = trace
.map(|t| {
t.resolved
.iter()
.map(|(s, v)| (*s, v.display()))
.collect()
})
.unwrap_or_default();
let highlighter = |row: usize, line: &str| -> Vec<(Style, String, bool)> {
let line_start = line_offsets[row];
let (exec, sel) = match trace {
let (exec, sel, res) = match trace {
Some(t) => (
adjust_spans_for_line(&t.executed_spans, line_start, line.len()),
adjust_spans_for_line(&t.selected_spans, line_start, line.len()),
adjust_resolved_for_line(&resolved_display, line_start, line.len()),
),
None => (Vec::new(), Vec::new()),
None => (Vec::new(), Vec::new(), Vec::new()),
};
highlight::highlight_line_with_runtime(line, &exec, &sel, &user_words)
highlight::highlight_line_with_runtime(line, &exec, &sel, &res, &user_words)
};
let show_search = app.editor_ctx.editor.search_active()