perf(diagnostics): use fixed ANSI styles (#26130)

Replace dynamic diagnostic styles with fixed ANSI prefixes, reducing `oxfmt` and `oxlint` release text size.

AI assistance: Codex was used. The contributor remains responsible for this change.
This commit is contained in:
Boshen committed 2026-08-27 05:19:35 +00:00
1 parent 07a07933c7
commit ac4785a139
10 files changed
+101 -48

No files matched your search

Generated
-1
View File
@@ -1992,7 +1992,6 @@ dependencies = [
"cow-utils",
"itoa",
"memchr",
"owo-colors",
"oxc_span",
"percent-encoding",
"smallvec",
-1
View File
@@ -243,7 +243,6 @@ oxc-css-parser = "0.0.11" # CSS/SCSS/Less parser (raffia 0.12.3 fork: adds `temp
oxc-graphql-parser = "0.0.9" # GraphQL parser (direct AST; apollo-parser 0.8.6 fork aligned with graphql-js 17 syntax)
oxc-toml = "0.14.5" # TOML formatter
oxc-yaml-parser = "0.0.5" # YAML 1.2 parser (comment-preserving typed AST, node naming from `yaml-unist-parser`)
owo-colors = "4.3.0" # Terminal colors
papaya = "0.2.4" # Concurrent hash map
percent-encoding = "2.3.2" # URL encoding
petgraph = { version = "0.8.3", default-features = false } # Graph data structures
+4 -4
View File
@@ -223,16 +223,16 @@ impl WalkRunner {
// Color support is detected the same way as `GraphicalReportHandler` used by `DefaultReporter`,
// and when colors are disabled, every style is empty and renders nothing.
// `ListDifferent` mode output is meant for piping, keep it style-free.
let warning_style = matches!(format_mode, OutputMode::Check)
.then(|| GraphicalTheme::default().warning_style());
let warning_theme =
matches!(format_mode, OutputMode::Check).then(GraphicalTheme::default);
let mut output = String::new();
for (idx, (path, elapsed)) in changed_paths.into_iter().enumerate() {
if idx != 0 {
output.push('\n');
}
match warning_style {
match &warning_theme {
// Style per line, some log viewers reset ANSI state on line breaks
Some(style) => write!(output, "{}", style.style(&path)).unwrap(),
Some(theme) => theme.write_warning(&mut output, &path).unwrap(),
None => output.push_str(&path),
}
if let Some(elapsed) = elapsed {
-1
View File
@@ -23,7 +23,6 @@ bytecount = { workspace = true }
cow-utils = { workspace = true }
itoa = { workspace = true }
memchr = { workspace = true }
owo-colors = { workspace = true }
percent-encoding = { workspace = true }
smallvec = { workspace = true }
textwrap = { workspace = true }
@@ -8,14 +8,13 @@
use std::fmt::{self, Write};
use owo_colors::OwoColorize;
use super::{
handler::GraphicalReportHandler,
label::write_repeated_char,
line::Line,
span::{FancySpan, LabelRenderMode},
};
use crate::handlers::theme::DiagnosticColorize;
impl GraphicalReportHandler {
pub(super) fn write_linum(
@@ -9,7 +9,6 @@
use std::{cmp::max, fmt};
use owo_colors::{OwoColorize, Style};
use smallvec::SmallVec;
use super::{
@@ -17,7 +16,7 @@ use super::{
line::Line,
span::{FancySpan, LabelRenderMode},
};
use crate::handlers::theme::ThemeCharacters;
use crate::handlers::theme::{DiagnosticColorize, Style, ThemeCharacters};
struct Underline {
padding: usize,
@@ -351,7 +350,7 @@ mod tests {
let label = LabelText {
chars: &theme.characters,
label: "plain label",
style: Style::new(),
style: Style::Plain,
render_mode,
};
output.clear();
@@ -9,11 +9,10 @@
use std::fmt::{self, Write as _};
use owo_colors::OwoColorize;
use smallvec::SmallVec;
use super::handler::{GraphicalReportHandler, LinkStyle};
use crate::{Diagnostic, Severity, source_impls::SpanScanner};
use crate::{Diagnostic, Severity, handlers::theme::DiagnosticColorize, source_impls::SpanScanner};
struct TitleBuffer(SmallVec<[u8; 128]>);
@@ -10,7 +10,6 @@
use std::{borrow::Cow, cmp::max, fmt};
use owo_colors::OwoColorize;
use smallvec::SmallVec;
use super::{
@@ -20,6 +19,7 @@ use super::{
};
use crate::{
Diagnostic, LabeledSpan,
handlers::theme::DiagnosticColorize,
source_impls::{SpanContents, SpanScanner},
};
@@ -4,10 +4,10 @@
//! it will be drawn in. Label text stays borrowed and is split into display
//! lines only when it is drawn.
use owo_colors::Style;
use oxc_span::Span;
use crate::handlers::theme::Style;
/// How a label is being drawn on the current output line.
///
/// A label can be a single trailing line, or a block that spans several output
+90 -31
View File
@@ -1,10 +1,8 @@
use std::{
env,
env, fmt,
io::{self, IsTerminal},
};
use owo_colors::Style;
/// Theme used by [`GraphicalReportHandler`](crate::GraphicalReportHandler).
///
/// Use one of the predefined constructors below.
@@ -66,13 +64,82 @@ impl GraphicalTheme {
Self { characters: ThemeCharacters::ascii(), styles: ThemeStyles::none() }
}
/// Style used for warning text.
#[must_use]
pub const fn warning_style(&self) -> Style {
self.styles.warning
/// Write text using the theme's warning style.
///
/// # Errors
///
/// Returns an error when writing the text fails.
pub fn write_warning(&self, f: &mut impl fmt::Write, value: impl fmt::Display) -> fmt::Result {
self.styles.warning.write(f, value)
}
}
const ANSI_RESET: &str = "\x1b[0m";
const ANSI_PREFIXES: [&str; 9] = [
"",
"\x1b[38;2;225;80;80;1m",
"\x1b[38;2;244;191;117;1m",
"\x1b[38;2;106;159;181m",
"\x1b[38;2;92;157;255;1m",
"\x1b[2m",
"\x1b[38;2;246;87;248m",
"\x1b[38;2;30;201;212m",
"\x1b[38;2;145;246;111m",
];
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u8)]
pub(super) enum Style {
Plain,
Error,
Warning,
Info,
Link,
LineNumber,
Highlight1,
Highlight2,
Highlight3,
}
impl Style {
const fn prefix(self) -> &'static str {
ANSI_PREFIXES[self as usize]
}
pub(super) const fn is_plain(self) -> bool {
matches!(self, Self::Plain)
}
fn write(self, f: &mut impl fmt::Write, value: impl fmt::Display) -> fmt::Result {
let prefix = self.prefix();
f.write_str(prefix)?;
write!(f, "{value}")?;
if self.is_plain() { Ok(()) } else { f.write_str(ANSI_RESET) }
}
}
pub(super) struct Styled<T> {
target: T,
style: Style,
}
impl<T: fmt::Display> fmt::Display for Styled<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let prefix = self.style.prefix();
f.write_str(prefix)?;
self.target.fmt(f)?;
if self.style.is_plain() { Ok(()) } else { f.write_str(ANSI_RESET) }
}
}
pub(super) trait DiagnosticColorize: Sized {
fn style(self, style: Style) -> Styled<Self> {
Styled { target: self, style }
}
}
impl<T> DiagnosticColorize for T {}
#[derive(Debug, Clone)]
pub(super) struct ThemeStyles {
pub(super) error: Style,
@@ -85,38 +152,30 @@ pub(super) struct ThemeStyles {
pub(super) highlights: [Style; 3],
}
fn style() -> Style {
Style::new()
}
impl ThemeStyles {
fn rgb() -> Self {
Self {
error: style().fg_rgb::<225, 80, 80>().bold(),
warning: style().fg_rgb::<244, 191, 117>().bold(),
advice: style().fg_rgb::<106, 159, 181>(),
help: style().fg_rgb::<106, 159, 181>(),
note: style().fg_rgb::<106, 159, 181>(),
link: style().fg_rgb::<92, 157, 255>().bold(),
linum: style().dimmed(),
highlights: [
style().fg_rgb::<246, 87, 248>(),
style().fg_rgb::<30, 201, 212>(),
style().fg_rgb::<145, 246, 111>(),
],
error: Style::Error,
warning: Style::Warning,
advice: Style::Info,
help: Style::Info,
note: Style::Info,
link: Style::Link,
linum: Style::LineNumber,
highlights: [Style::Highlight1, Style::Highlight2, Style::Highlight3],
}
}
fn none() -> Self {
Self {
error: style(),
warning: style(),
advice: style(),
help: style(),
note: style(),
link: style(),
linum: style(),
highlights: [style(); 3],
error: Style::Plain,
warning: Style::Plain,
advice: Style::Plain,
help: Style::Plain,
note: Style::Plain,
link: Style::Plain,
linum: Style::Plain,
highlights: [Style::Plain; 3],
}
}
}