Description: ruff_linter,ruff_python_parser: migrate to updated `annotate-snippets` (#84179aaa96)
Index: ruff/crates/ruff_cli/Cargo.toml
===================================================================
--- ruff.orig/crates/ruff_cli/Cargo.toml
+++ ruff/crates/ruff_cli/Cargo.toml
@@ -28,7 +28,7 @@ ruff_python_trivia = { path = "../ruff_p
 ruff_workspace = { path = "../ruff_workspace" }
 ruff_text_size = { path = "../ruff_text_size" }
 
-annotate-snippets = { version = "0.9.1", features = ["color"] }
+annotate-snippets = { version = "0.12" }
 anyhow = { workspace = true }
 argfile = { version = "0.1.6" }
 bincode = { version = "1.3.3" }
Index: ruff/crates/ruff_linter/Cargo.toml
===================================================================
--- ruff.orig/crates/ruff_linter/Cargo.toml
+++ ruff/crates/ruff_linter/Cargo.toml
@@ -29,7 +29,7 @@ ruff_python_parser = { path = "../ruff_p
 ruff_source_file = { path = "../ruff_source_file", features = ["serde"] }
 ruff_text_size = { path = "../ruff_text_size" }
 
-annotate-snippets = { version = "0.9.1", features = ["color"] }
+annotate-snippets = { version = "0.12" }
 anyhow = { workspace = true }
 bitflags = { workspace = true }
 chrono = { workspace = true }
Index: ruff/crates/ruff_linter/src/message/text.rs
===================================================================
--- ruff.orig/crates/ruff_linter/src/message/text.rs
+++ ruff/crates/ruff_linter/src/message/text.rs
@@ -2,8 +2,7 @@ use std::borrow::Cow;
 use std::fmt::{Display, Formatter};
 use std::io::Write;
 
-use annotate_snippets::display_list::{DisplayList, FormatOptions};
-use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation};
+use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet};
 use bitflags::bitflags;
 use colored::Colorize;
 
@@ -171,15 +170,6 @@ impl Display for MessageCodeFrame<'_> {
         } = self.message;
 
         let suggestion = kind.suggestion.as_deref();
-        let footer = if suggestion.is_some() {
-            vec![Annotation {
-                id: None,
-                label: suggestion,
-                annotation_type: AnnotationType::Help,
-            }]
-        } else {
-            Vec::new()
-        };
 
         let source_code = file.to_source_code();
 
@@ -240,47 +230,36 @@ impl Display for MessageCodeFrame<'_> {
             range - start_offset,
         );
 
-        let start_char = source.text[TextRange::up_to(source.annotation_range.start())]
-            .chars()
-            .count();
-
-        let char_length = source.text[source.annotation_range].chars().count();
-
         let label = kind.rule().noqa_code().to_string();
 
-        let snippet = Snippet {
-            title: None,
-            slices: vec![Slice {
-                source: &source.text,
-                line_start: self.notebook_index.map_or_else(
-                    || start_index.get(),
-                    |notebook_index| {
-                        notebook_index
-                            .cell_row(start_index.get())
-                            .unwrap_or_default() as usize
-                    },
-                ),
-                annotations: vec![SourceAnnotation {
-                    label: &label,
-                    annotation_type: AnnotationType::Error,
-                    range: (start_char, start_char + char_length),
-                }],
-                // The origin (file name, line number, and column number) is already encoded
-                // in the `label`.
-                origin: None,
-                fold: false,
-            }],
-            footer,
-            opt: FormatOptions {
-                #[cfg(test)]
-                color: false,
-                #[cfg(not(test))]
-                color: colored::control::SHOULD_COLORIZE.should_colorize(),
-                ..FormatOptions::default()
+        let line_start = self.notebook_index.map_or_else(
+            || start_index.get(),
+            |notebook_index| {
+                notebook_index
+                    .cell_row(start_index.get())
+                    .unwrap_or_default() as usize
             },
-        };
+        );
+
+        let span = usize::from(source.annotation_range.start())
+            ..usize::from(source.annotation_range.end());
+        let annotation = AnnotationKind::Primary.span(span).label(&label);
+        let snippet = Snippet::source(&*source.text)
+            .line_start(line_start)
+            .annotation(annotation)
+            .fold(false);
+        let mut group = Level::ERROR.no_name().primary_title("").element(snippet);
+        if let Some(suggestion) = suggestion {
+            group = group.element(Level::HELP.message(suggestion));
+        }
 
-        writeln!(f, "{message}", message = DisplayList::from(snippet))
+        let renderer = if !cfg!(test) && colored::control::SHOULD_COLORIZE.should_colorize() {
+            Renderer::styled()
+        } else {
+            Renderer::plain()
+        };
+        let rendered = renderer.render(&[group]);
+        writeln!(f, "{rendered}")
     }
 }
 
