mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
parent
366dc3037a
commit
b65e8397de
6 changed files with 275 additions and 28 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -910,6 +910,7 @@ dependencies = [
|
|||
name = "oxc_diagnostics"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
"miette",
|
||||
"owo-colors",
|
||||
"oxc_ast",
|
||||
|
|
|
|||
|
|
@ -9,14 +9,8 @@ static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
|||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
use oxc_cli::{command, CliRunResult, LintOptions, LintRunner};
|
||||
use oxc_diagnostics::miette;
|
||||
|
||||
fn main() -> CliRunResult {
|
||||
// convert source code with hard tabs into 4 spaces,
|
||||
// otherwise error label spans will have a wrong offset.
|
||||
miette::set_hook(Box::new(|_| Box::new(miette::MietteHandlerOpts::new().tab_width(4).build())))
|
||||
.unwrap();
|
||||
|
||||
let matches = command().get_matches();
|
||||
let Some((subcommand, matches)) = matches.subcommand() else {
|
||||
return CliRunResult::None
|
||||
|
|
|
|||
|
|
@ -18,3 +18,4 @@ miette = { workspace = true }
|
|||
unicode-width = "0.1.10"
|
||||
owo-colors = { version = "3.5.0" }
|
||||
textwrap = { version = "0.16.0" }
|
||||
is-terminal = { version = "0.4.0" }
|
||||
|
|
|
|||
|
|
@ -3,19 +3,19 @@
|
|||
#![allow(clippy::nursery)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
/**
|
||||
* origin file: https://github.com/zkat/miette/blob/78fe18e6990feacc8bdaeeb10e1439a12c111e6e/src/handlers/graphical.rs
|
||||
*/
|
||||
/// origin file: https://github.com/zkat/miette/blob/78fe18e6990feacc8bdaeeb10e1439a12c111e6e/src/handlers/graphical.rs
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
// use miette::diagnostic_chain::DiagnosticChain;
|
||||
use miette::{
|
||||
Diagnostic, GraphicalTheme, LabeledSpan, MietteError, ReportHandler, Severity, SourceCode,
|
||||
SourceSpan, SpanContents,
|
||||
Diagnostic, LabeledSpan, MietteError, ReportHandler, Severity, SourceCode, SourceSpan,
|
||||
SpanContents,
|
||||
};
|
||||
use owo_colors::{OwoColorize, Style};
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
use crate::graphical_theme::GraphicalTheme;
|
||||
|
||||
/**
|
||||
A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a
|
||||
quasi-graphical way, using terminal colors, unicode drawing characters, and
|
||||
|
|
@ -43,6 +43,9 @@ pub(crate) enum LinkStyle {
|
|||
Link,
|
||||
Text,
|
||||
}
|
||||
fn style() -> Style {
|
||||
Style::new()
|
||||
}
|
||||
|
||||
impl GraphicalReportHandler {
|
||||
/// Create a new `GraphicalReportHandler` with the default
|
||||
|
|
@ -50,7 +53,7 @@ impl GraphicalReportHandler {
|
|||
pub fn new() -> Self {
|
||||
Self {
|
||||
links: LinkStyle::Link,
|
||||
termwidth: 200,
|
||||
termwidth: 600, // Changed: origin: 200
|
||||
theme: GraphicalTheme::default(),
|
||||
footer: None,
|
||||
context_lines: 1,
|
||||
|
|
@ -59,19 +62,6 @@ impl GraphicalReportHandler {
|
|||
}
|
||||
}
|
||||
|
||||
///Create a new `GraphicalReportHandler` with a given [`GraphicalTheme`].
|
||||
pub fn new_themed(theme: GraphicalTheme) -> Self {
|
||||
Self {
|
||||
links: LinkStyle::Link,
|
||||
termwidth: 200,
|
||||
theme,
|
||||
footer: None,
|
||||
context_lines: 1,
|
||||
tab_width: 4,
|
||||
with_cause_chain: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the displayed tab width in spaces.
|
||||
pub fn tab_width(mut self, width: usize) -> Self {
|
||||
self.tab_width = width;
|
||||
|
|
@ -214,7 +204,9 @@ impl GraphicalReportHandler {
|
|||
.initial_indent(&initial_indent)
|
||||
.subsequent_indent(&rest_indent);
|
||||
|
||||
writeln!(f, "{}", textwrap::fill(&diagnostic.to_string(), opts))?;
|
||||
let title = format!("{}", diagnostic.to_string().style(severity_style));
|
||||
let title = textwrap::fill(&title, opts);
|
||||
writeln!(f, "{}", title)?;
|
||||
|
||||
// CHANGED: REMOVED
|
||||
// if !self.with_cause_chain {
|
||||
|
|
@ -361,10 +353,10 @@ impl GraphicalReportHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn render_context<'a>(
|
||||
fn render_context(
|
||||
&self,
|
||||
f: &mut impl fmt::Write,
|
||||
source: &'a dyn SourceCode,
|
||||
source: &dyn SourceCode,
|
||||
context: &LabeledSpan,
|
||||
labels: &[LabeledSpan],
|
||||
) -> fmt::Result {
|
||||
|
|
|
|||
258
crates/oxc_diagnostics/src/graphical_theme.rs
Normal file
258
crates/oxc_diagnostics/src/graphical_theme.rs
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
#![allow(clippy::must_use_candidate)]
|
||||
#![allow(clippy::pedantic)]
|
||||
#![allow(clippy::nursery)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
/// origin file: https://github.com/zkat/miette/blob/78fe18e6990feacc8bdaeeb10e1439a12c111e6e/src/handlers/theme.rs
|
||||
use is_terminal::IsTerminal;
|
||||
use owo_colors::{style, Style};
|
||||
|
||||
/**
|
||||
Theme used by [`GraphicalReportHandler`](crate::GraphicalReportHandler) to
|
||||
render fancy [`Diagnostic`](crate::Diagnostic) reports.
|
||||
A theme consists of two things: the set of characters to be used for drawing,
|
||||
and the
|
||||
[`owo_colors::Style`](https://docs.rs/owo-colors/latest/owo_colors/struct.Style.html)s to be used to paint various items.
|
||||
You can create your own custom graphical theme using this type, or you can use
|
||||
one of the predefined ones using the methods below.
|
||||
*/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GraphicalTheme {
|
||||
/// Characters to be used for drawing.
|
||||
pub characters: ThemeCharacters,
|
||||
/// Styles to be used for painting.
|
||||
pub styles: ThemeStyles,
|
||||
}
|
||||
|
||||
impl GraphicalTheme {
|
||||
/// ASCII-art-based graphical drawing, with ANSI styling.
|
||||
pub fn ascii() -> Self {
|
||||
Self { characters: ThemeCharacters::ascii(), styles: ThemeStyles::ansi() }
|
||||
}
|
||||
|
||||
/// Graphical theme that draws using both ansi colors and unicode
|
||||
/// characters.
|
||||
pub fn unicode() -> Self {
|
||||
Self { characters: ThemeCharacters::unicode(), styles: ThemeStyles::rgb() }
|
||||
}
|
||||
|
||||
/// Graphical theme that draws in monochrome, while still using unicode
|
||||
/// characters.
|
||||
pub fn unicode_nocolor() -> Self {
|
||||
Self { characters: ThemeCharacters::unicode(), styles: ThemeStyles::none() }
|
||||
}
|
||||
|
||||
/// A "basic" graphical theme that skips colors and unicode characters and
|
||||
/// just does monochrome ascii art. If you want a completely non-graphical
|
||||
/// rendering of your `Diagnostic`s, check out
|
||||
/// [crate::NarratableReportHandler], or write your own
|
||||
/// [crate::ReportHandler]!
|
||||
pub fn none() -> Self {
|
||||
Self { characters: ThemeCharacters::ascii(), styles: ThemeStyles::none() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GraphicalTheme {
|
||||
fn default() -> Self {
|
||||
match std::env::var("NO_COLOR") {
|
||||
_ if !std::io::stdout().is_terminal() || !std::io::stderr().is_terminal() => {
|
||||
Self::ascii()
|
||||
}
|
||||
Ok(string) if string != "0" => Self::unicode_nocolor(),
|
||||
_ => Self::unicode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Styles for various parts of graphical rendering for the [crate::GraphicalReportHandler].
|
||||
*/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ThemeStyles {
|
||||
/// Style to apply to things highlighted as "error".
|
||||
pub error: Style,
|
||||
/// Style to apply to things highlighted as "warning".
|
||||
pub warning: Style,
|
||||
/// Style to apply to things highlighted as "advice".
|
||||
pub advice: Style,
|
||||
/// Style to apply to the help text.
|
||||
pub help: Style,
|
||||
/// Style to apply to filenames/links/URLs.
|
||||
pub link: Style,
|
||||
/// Style to apply to line numbers.
|
||||
pub linum: Style,
|
||||
/// Styles to cycle through (using `.iter().cycle()`), to render the lines
|
||||
/// and text for diagnostic highlights.
|
||||
pub highlights: Vec<Style>,
|
||||
}
|
||||
|
||||
impl ThemeStyles {
|
||||
/// Nice RGB colors.
|
||||
/// [Credit](http://terminal.sexy/#FRUV0NDQFRUVrEFCkKlZ9L91ap-1qnWfdbWq0NDQUFBQrEFCkKlZ9L91ap-1qnWfdbWq9fX1).
|
||||
pub fn rgb() -> Self {
|
||||
Self {
|
||||
error: style().fg_rgb::<225, 80, 80>().bold(), // CHANGED: <255, 30, 30>
|
||||
warning: style().fg_rgb::<244, 191, 117>(),
|
||||
advice: style().fg_rgb::<106, 159, 181>(),
|
||||
help: style().fg_rgb::<106, 159, 181>(),
|
||||
link: style().fg_rgb::<92, 157, 255>().bold(),
|
||||
linum: style().dimmed(),
|
||||
highlights: vec![
|
||||
style().fg_rgb::<246, 87, 248>(),
|
||||
style().fg_rgb::<30, 201, 212>(),
|
||||
style().fg_rgb::<145, 246, 111>(),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// ANSI color-based styles.
|
||||
pub fn ansi() -> Self {
|
||||
Self {
|
||||
error: style().red(),
|
||||
warning: style().yellow(),
|
||||
advice: style().cyan(),
|
||||
help: style().cyan(),
|
||||
link: style().bold(),
|
||||
linum: style().dimmed(),
|
||||
highlights: vec![
|
||||
style().magenta().bold(),
|
||||
style().yellow().bold(),
|
||||
style().green().bold(),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// No styling. Just regular ol' monochrome.
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
error: style(),
|
||||
warning: style(),
|
||||
advice: style(),
|
||||
help: style(),
|
||||
link: style(),
|
||||
linum: style(),
|
||||
highlights: vec![style()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
// Most of these characters were taken from
|
||||
// https://github.com/zesterer/ariadne/blob/e3cb394cb56ecda116a0a1caecd385a49e7f6662/src/draw.rs
|
||||
|
||||
/// Characters to be used when drawing when using
|
||||
/// [crate::GraphicalReportHandler].
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ThemeCharacters {
|
||||
pub hbar: char,
|
||||
pub vbar: char,
|
||||
pub xbar: char,
|
||||
pub vbar_break: char,
|
||||
|
||||
pub uarrow: char,
|
||||
pub rarrow: char,
|
||||
|
||||
pub ltop: char,
|
||||
pub mtop: char,
|
||||
pub rtop: char,
|
||||
pub lbot: char,
|
||||
pub rbot: char,
|
||||
pub mbot: char,
|
||||
|
||||
pub lbox: char,
|
||||
pub rbox: char,
|
||||
|
||||
pub lcross: char,
|
||||
pub rcross: char,
|
||||
|
||||
pub underbar: char,
|
||||
pub underline: char,
|
||||
|
||||
pub error: String,
|
||||
pub warning: String,
|
||||
pub advice: String,
|
||||
}
|
||||
|
||||
impl ThemeCharacters {
|
||||
/// Fancy unicode-based graphical elements.
|
||||
pub fn unicode() -> Self {
|
||||
Self {
|
||||
hbar: '─',
|
||||
vbar: '│',
|
||||
xbar: '┼',
|
||||
vbar_break: '·',
|
||||
uarrow: '▲',
|
||||
rarrow: '▶',
|
||||
ltop: '╭',
|
||||
mtop: '┬',
|
||||
rtop: '╮',
|
||||
lbot: '╰',
|
||||
mbot: '┴',
|
||||
rbot: '╯',
|
||||
lbox: '[',
|
||||
rbox: ']',
|
||||
lcross: '├',
|
||||
rcross: '┤',
|
||||
underbar: '┬',
|
||||
underline: '─',
|
||||
error: "×".into(),
|
||||
warning: "⚠".into(),
|
||||
advice: "☞".into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Emoji-heavy unicode characters.
|
||||
pub fn emoji() -> Self {
|
||||
Self {
|
||||
hbar: '─',
|
||||
vbar: '│',
|
||||
xbar: '┼',
|
||||
vbar_break: '·',
|
||||
uarrow: '▲',
|
||||
rarrow: '▶',
|
||||
ltop: '╭',
|
||||
mtop: '┬',
|
||||
rtop: '╮',
|
||||
lbot: '╰',
|
||||
mbot: '┴',
|
||||
rbot: '╯',
|
||||
lbox: '[',
|
||||
rbox: ']',
|
||||
lcross: '├',
|
||||
rcross: '┤',
|
||||
underbar: '┬',
|
||||
underline: '─',
|
||||
error: "💥".into(),
|
||||
warning: "⚠️".into(),
|
||||
advice: "💡".into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// ASCII-art-based graphical elements. Works well on older terminals.
|
||||
pub fn ascii() -> Self {
|
||||
Self {
|
||||
hbar: '-',
|
||||
vbar: '|',
|
||||
xbar: '+',
|
||||
vbar_break: ':',
|
||||
uarrow: '^',
|
||||
rarrow: '>',
|
||||
ltop: ',',
|
||||
mtop: 'v',
|
||||
rtop: '.',
|
||||
lbot: '`',
|
||||
mbot: '^',
|
||||
rbot: '\'',
|
||||
lbox: '[',
|
||||
rbox: ']',
|
||||
lcross: '|',
|
||||
rcross: '|',
|
||||
underbar: '|',
|
||||
underline: '^',
|
||||
error: "x".into(),
|
||||
warning: "!".into(),
|
||||
advice: ">".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
//! Exports `thiserror` and `miette`
|
||||
|
||||
mod graphic_reporter;
|
||||
mod graphical_theme;
|
||||
|
||||
use std::{cell::RefCell, ops::Deref, path::PathBuf, rc::Rc};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue