This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user