debugger: Process ANSI color escape codes in console (#32817)

- [x] foreground highlights
- [x] background highlights
- [x] advertise support in DAP capabilities

Closes #31372

Release Notes:

- Debugger Beta: added basic support for highlighting in the console
based on ANSI escape codes.
This commit is contained in:
Cole Miller 2025-06-16 17:39:53 -04:00 committed by GitHub
parent 1f457169ba
commit ffc6218349
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 558 additions and 234 deletions

View file

@ -80,7 +80,7 @@ pub trait ToDisplayPoint {
fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint;
}
type TextHighlights = TreeMap<TypeId, Arc<(HighlightStyle, Vec<Range<Anchor>>)>>;
type TextHighlights = TreeMap<TypeId, Vec<(Range<Anchor>, HighlightStyle)>>;
type InlayHighlights = TreeMap<TypeId, TreeMap<InlayId, (HighlightStyle, InlayHighlight)>>;
/// Decides how text in a [`MultiBuffer`] should be displayed in a buffer, handling inlay hints,
@ -474,11 +474,9 @@ impl DisplayMap {
pub fn highlight_text(
&mut self,
type_id: TypeId,
ranges: Vec<Range<Anchor>>,
style: HighlightStyle,
ranges: Vec<(Range<Anchor>, HighlightStyle)>,
) {
self.text_highlights
.insert(type_id, Arc::new((style, ranges)));
self.text_highlights.insert(type_id, ranges);
}
pub(crate) fn highlight_inlays(
@ -500,16 +498,25 @@ impl DisplayMap {
}
}
pub fn text_highlights(&self, type_id: TypeId) -> Option<(HighlightStyle, &[Range<Anchor>])> {
let highlights = self.text_highlights.get(&type_id)?;
Some((highlights.0, &highlights.1))
pub fn text_highlights(&self, type_id: TypeId) -> Option<&[(Range<Anchor>, HighlightStyle)]> {
self.text_highlights
.get(&type_id)
.map(|highlights| highlights.as_slice())
}
pub fn clear_highlights(&mut self, type_id: TypeId) -> bool {
let mut cleared = self.text_highlights.remove(&type_id).is_some();
cleared |= self.inlay_highlights.remove(&type_id).is_some();
cleared
}
pub fn remove_text_highlights(
&mut self,
type_id: TypeId,
) -> Option<Vec<(Range<Anchor>, HighlightStyle)>> {
self.text_highlights.remove(&type_id)
}
pub fn set_font(&self, font: Font, font_size: Pixels, cx: &mut Context<Self>) -> bool {
self.wrap_map
.update(cx, |map, cx| map.set_font_with_size(font, font_size, cx))
@ -1331,7 +1338,7 @@ impl DisplaySnapshot {
#[cfg(any(test, feature = "test-support"))]
pub fn text_highlight_ranges<Tag: ?Sized + 'static>(
&self,
) -> Option<Arc<(HighlightStyle, Vec<Range<Anchor>>)>> {
) -> Option<Vec<(Range<Anchor>, HighlightStyle)>> {
let type_id = TypeId::of::<Tag>();
self.text_highlights.get(&type_id).cloned()
}
@ -2296,12 +2303,17 @@ pub mod tests {
map.highlight_text(
TypeId::of::<usize>(),
vec![
buffer_snapshot.anchor_before(Point::new(3, 9))
..buffer_snapshot.anchor_after(Point::new(3, 14)),
buffer_snapshot.anchor_before(Point::new(3, 17))
..buffer_snapshot.anchor_after(Point::new(3, 18)),
(
buffer_snapshot.anchor_before(Point::new(3, 9))
..buffer_snapshot.anchor_after(Point::new(3, 14)),
red.into(),
),
(
buffer_snapshot.anchor_before(Point::new(3, 17))
..buffer_snapshot.anchor_after(Point::new(3, 18)),
red.into(),
),
],
red.into(),
);
map.insert_blocks(
[BlockProperties {
@ -2620,11 +2632,13 @@ pub mod tests {
highlighted_ranges
.into_iter()
.map(|range| {
buffer_snapshot.anchor_before(range.start)
..buffer_snapshot.anchor_before(range.end)
(
buffer_snapshot.anchor_before(range.start)
..buffer_snapshot.anchor_before(range.end),
style,
)
})
.collect(),
style,
);
});