debugger: Parse and highlight text with ANSI escape sequences (#32915)

Relanding #32817 with an improved approach, bugs fixed, and a test.

Release Notes:

- N/A
This commit is contained in:
Cole Miller 2025-06-17 23:39:31 -04:00 committed by GitHub
parent 4da58188fb
commit bfffc293a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 606 additions and 80 deletions

View file

@ -76,11 +76,17 @@ pub enum FoldStatus {
Foldable,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum HighlightKey {
Type(TypeId),
TypePlus(TypeId, usize),
}
pub trait ToDisplayPoint {
fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint;
}
type TextHighlights = TreeMap<TypeId, Arc<(HighlightStyle, Vec<Range<Anchor>>)>>;
type TextHighlights = TreeMap<HighlightKey, Arc<(HighlightStyle, Vec<Range<Anchor>>)>>;
type InlayHighlights = TreeMap<TypeId, TreeMap<InlayId, (HighlightStyle, InlayHighlight)>>;
/// Decides how text in a [`MultiBuffer`] should be displayed in a buffer, handling inlay hints,
@ -473,12 +479,11 @@ impl DisplayMap {
pub fn highlight_text(
&mut self,
type_id: TypeId,
key: HighlightKey,
ranges: Vec<Range<Anchor>>,
style: HighlightStyle,
) {
self.text_highlights
.insert(type_id, Arc::new((style, ranges)));
self.text_highlights.insert(key, Arc::new((style, ranges)));
}
pub(crate) fn highlight_inlays(
@ -501,11 +506,22 @@ impl DisplayMap {
}
pub fn text_highlights(&self, type_id: TypeId) -> Option<(HighlightStyle, &[Range<Anchor>])> {
let highlights = self.text_highlights.get(&type_id)?;
let highlights = self.text_highlights.get(&HighlightKey::Type(type_id))?;
Some((highlights.0, &highlights.1))
}
#[cfg(feature = "test-support")]
pub fn all_text_highlights(
&self,
) -> impl Iterator<Item = &Arc<(HighlightStyle, Vec<Range<Anchor>>)>> {
self.text_highlights.values()
}
pub fn clear_highlights(&mut self, type_id: TypeId) -> bool {
let mut cleared = self.text_highlights.remove(&type_id).is_some();
let mut cleared = self
.text_highlights
.remove(&HighlightKey::Type(type_id))
.is_some();
cleared |= self.inlay_highlights.remove(&type_id).is_some();
cleared
}
@ -1333,7 +1349,9 @@ impl DisplaySnapshot {
&self,
) -> Option<Arc<(HighlightStyle, Vec<Range<Anchor>>)>> {
let type_id = TypeId::of::<Tag>();
self.text_highlights.get(&type_id).cloned()
self.text_highlights
.get(&HighlightKey::Type(type_id))
.cloned()
}
#[allow(unused)]
@ -2294,7 +2312,7 @@ pub mod tests {
// Insert a block in the middle of a multi-line diagnostic.
map.update(cx, |map, cx| {
map.highlight_text(
TypeId::of::<usize>(),
HighlightKey::Type(TypeId::of::<usize>()),
vec![
buffer_snapshot.anchor_before(Point::new(3, 9))
..buffer_snapshot.anchor_after(Point::new(3, 14)),
@ -2616,7 +2634,7 @@ pub mod tests {
map.update(cx, |map, _cx| {
map.highlight_text(
TypeId::of::<MyType>(),
HighlightKey::Type(TypeId::of::<MyType>()),
highlighted_ranges
.into_iter()
.map(|range| {