mirror of
https://github.com/crate-ci/typos.git
synced 2024-11-29 12:31:01 -05:00
Merge pull request #864 from epage/color
fix(cli): Improve color formatting
This commit is contained in:
commit
6a7b7d0777
4 changed files with 55 additions and 120 deletions
|
@ -13,21 +13,11 @@ pub enum Format {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format {
|
impl Format {
|
||||||
pub(crate) fn reporter(
|
pub(crate) fn reporter(self) -> Box<dyn typos_cli::report::Report> {
|
||||||
self,
|
|
||||||
stdout_palette: crate::report::Palette,
|
|
||||||
stderr_palette: crate::report::Palette,
|
|
||||||
) -> Box<dyn typos_cli::report::Report> {
|
|
||||||
match self {
|
match self {
|
||||||
Format::Silent => Box::new(crate::report::PrintSilent),
|
Format::Silent => Box::new(crate::report::PrintSilent),
|
||||||
Format::Brief => Box::new(crate::report::PrintBrief {
|
Format::Brief => Box::new(crate::report::PrintBrief),
|
||||||
stdout_palette,
|
Format::Long => Box::new(crate::report::PrintLong),
|
||||||
stderr_palette,
|
|
||||||
}),
|
|
||||||
Format::Long => Box::new(crate::report::PrintLong {
|
|
||||||
stdout_palette,
|
|
||||||
stderr_palette,
|
|
||||||
}),
|
|
||||||
Format::Json => Box::new(crate::report::PrintJson),
|
Format::Json => Box::new(crate::report::PrintJson),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,9 +255,7 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult {
|
||||||
let output_reporter = if args.diff {
|
let output_reporter = if args.diff {
|
||||||
Box::new(crate::report::PrintSilent)
|
Box::new(crate::report::PrintSilent)
|
||||||
} else {
|
} else {
|
||||||
let stdout_palette = report::Palette::colored();
|
args.format.reporter()
|
||||||
let stderr_palette = report::Palette::colored();
|
|
||||||
args.format.reporter(stdout_palette, stderr_palette)
|
|
||||||
};
|
};
|
||||||
let status_reporter = report::MessageStatus::new(output_reporter.as_ref());
|
let status_reporter = report::MessageStatus::new(output_reporter.as_ref());
|
||||||
let reporter: &dyn typos_cli::report::Report = &status_reporter;
|
let reporter: &dyn typos_cli::report::Report = &status_reporter;
|
||||||
|
|
|
@ -8,60 +8,9 @@ use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use typos_cli::report::{Context, Message, Report, Typo};
|
use typos_cli::report::{Context, Message, Report, Typo};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
const ERROR: anstyle::Style = anstyle::AnsiColor::BrightRed.on_default();
|
||||||
pub struct Palette {
|
const INFO: anstyle::Style = anstyle::AnsiColor::BrightBlue.on_default();
|
||||||
error: anstyle::Style,
|
const GOOD: anstyle::Style = anstyle::AnsiColor::BrightGreen.on_default();
|
||||||
info: anstyle::Style,
|
|
||||||
strong: anstyle::Style,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Palette {
|
|
||||||
pub fn colored() -> Self {
|
|
||||||
Self {
|
|
||||||
error: anstyle::AnsiColor::Red.on_default(),
|
|
||||||
info: anstyle::AnsiColor::Blue.on_default(),
|
|
||||||
strong: anstyle::Effects::BOLD.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn error<D: std::fmt::Display>(self, display: D) -> Styled<D> {
|
|
||||||
Styled::new(display, self.error)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn info<D: std::fmt::Display>(self, display: D) -> Styled<D> {
|
|
||||||
Styled::new(display, self.info)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn strong<D: std::fmt::Display>(self, display: D) -> Styled<D> {
|
|
||||||
Styled::new(display, self.strong)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct Styled<D> {
|
|
||||||
display: D,
|
|
||||||
style: anstyle::Style,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: std::fmt::Display> Styled<D> {
|
|
||||||
pub(crate) fn new(display: D, style: anstyle::Style) -> Self {
|
|
||||||
Self { display, style }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: std::fmt::Display> std::fmt::Display for Styled<D> {
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
if f.alternate() {
|
|
||||||
write!(f, "{}", self.style.render())?;
|
|
||||||
self.display.fmt(f)?;
|
|
||||||
write!(f, "{}", self.style.render_reset())?;
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
self.display.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MessageStatus<'r> {
|
pub struct MessageStatus<'r> {
|
||||||
typos_found: atomic::AtomicBool,
|
typos_found: atomic::AtomicBool,
|
||||||
|
@ -108,10 +57,7 @@ impl Report for PrintSilent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PrintBrief {
|
pub struct PrintBrief;
|
||||||
pub stdout_palette: Palette,
|
|
||||||
pub stderr_palette: Palette,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Report for PrintBrief {
|
impl Report for PrintBrief {
|
||||||
fn report(&self, msg: Message) -> Result<(), std::io::Error> {
|
fn report(&self, msg: Message) -> Result<(), std::io::Error> {
|
||||||
|
@ -119,11 +65,13 @@ impl Report for PrintBrief {
|
||||||
Message::BinaryFile(msg) => {
|
Message::BinaryFile(msg) => {
|
||||||
log::info!("{}", msg);
|
log::info!("{}", msg);
|
||||||
}
|
}
|
||||||
Message::Typo(msg) => print_brief_correction(msg, self.stdout_palette)?,
|
Message::Typo(msg) => print_brief_correction(msg)?,
|
||||||
Message::FileType(msg) => {
|
Message::FileType(msg) => {
|
||||||
|
let info = INFO.render();
|
||||||
|
let reset = anstyle::Reset.render();
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout().lock(),
|
stdout().lock(),
|
||||||
"{}:{}",
|
"{info}{}{reset}: {}",
|
||||||
msg.path.display(),
|
msg.path.display(),
|
||||||
msg.file_type.unwrap_or("-")
|
msg.file_type.unwrap_or("-")
|
||||||
)?;
|
)?;
|
||||||
|
@ -143,10 +91,7 @@ impl Report for PrintBrief {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PrintLong {
|
pub struct PrintLong;
|
||||||
pub stdout_palette: Palette,
|
|
||||||
pub stderr_palette: Palette,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Report for PrintLong {
|
impl Report for PrintLong {
|
||||||
fn report(&self, msg: Message) -> Result<(), std::io::Error> {
|
fn report(&self, msg: Message) -> Result<(), std::io::Error> {
|
||||||
|
@ -154,11 +99,13 @@ impl Report for PrintLong {
|
||||||
Message::BinaryFile(msg) => {
|
Message::BinaryFile(msg) => {
|
||||||
log::info!("{}", msg);
|
log::info!("{}", msg);
|
||||||
}
|
}
|
||||||
Message::Typo(msg) => print_long_correction(msg, self.stdout_palette)?,
|
Message::Typo(msg) => print_long_correction(msg)?,
|
||||||
Message::FileType(msg) => {
|
Message::FileType(msg) => {
|
||||||
|
let info = INFO.render();
|
||||||
|
let reset = anstyle::Reset.render();
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout().lock(),
|
stdout().lock(),
|
||||||
"{}:{}",
|
"{info}{}{reset}: {}",
|
||||||
msg.path.display(),
|
msg.path.display(),
|
||||||
msg.file_type.unwrap_or("-")
|
msg.file_type.unwrap_or("-")
|
||||||
)?;
|
)?;
|
||||||
|
@ -178,7 +125,12 @@ impl Report for PrintLong {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_brief_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Error> {
|
fn print_brief_correction(msg: &Typo) -> Result<(), std::io::Error> {
|
||||||
|
let error = ERROR.render();
|
||||||
|
let good = GOOD.render();
|
||||||
|
let info = INFO.render();
|
||||||
|
let reset = anstyle::Reset.render();
|
||||||
|
|
||||||
let start = String::from_utf8_lossy(&msg.buffer[0..msg.byte_offset]);
|
let start = String::from_utf8_lossy(&msg.buffer[0..msg.byte_offset]);
|
||||||
let column_number =
|
let column_number =
|
||||||
unicode_segmentation::UnicodeSegmentation::graphemes(start.as_ref(), true).count() + 1;
|
unicode_segmentation::UnicodeSegmentation::graphemes(start.as_ref(), true).count() + 1;
|
||||||
|
@ -188,26 +140,22 @@ fn print_brief_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::E
|
||||||
let divider = ":";
|
let divider = ":";
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout().lock(),
|
stdout().lock(),
|
||||||
"{:#}{:#}{:#}: {:#}",
|
"{info}{}{divider}{column_number}{reset}: `{error}{}{reset}` is disallowed",
|
||||||
palette.info(context_display(&msg.context)),
|
context_display(&msg.context),
|
||||||
palette.info(divider),
|
msg.typo,
|
||||||
palette.info(column_number),
|
|
||||||
palette.strong(format_args!("`{}` is disallowed:", msg.typo)),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
typos::Status::Corrections(corrections) => {
|
typos::Status::Corrections(corrections) => {
|
||||||
let divider = ":";
|
let divider = ":";
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout().lock(),
|
stdout().lock(),
|
||||||
"{:#}{:#}{:#}: {:#}",
|
"{info}{}{divider}{column_number}{reset}: `{error}{}{reset}` -> {}",
|
||||||
palette.info(context_display(&msg.context)),
|
context_display(&msg.context),
|
||||||
palette.info(divider),
|
msg.typo,
|
||||||
palette.info(column_number),
|
itertools::join(
|
||||||
palette.strong(format_args!(
|
corrections.iter().map(|s| format!("`{good}{}{reset}`", s)),
|
||||||
"`{}` -> {}",
|
", "
|
||||||
msg.typo,
|
)
|
||||||
itertools::join(corrections.iter().map(|s| format!("`{}`", s)), ", ")
|
|
||||||
)),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +163,12 @@ fn print_brief_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::E
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Error> {
|
fn print_long_correction(msg: &Typo) -> Result<(), std::io::Error> {
|
||||||
|
let error = ERROR.render();
|
||||||
|
let good = GOOD.render();
|
||||||
|
let info = INFO.render();
|
||||||
|
let reset = anstyle::Reset.render();
|
||||||
|
|
||||||
let stdout = stdout();
|
let stdout = stdout();
|
||||||
let mut handle = stdout.lock();
|
let mut handle = stdout.lock();
|
||||||
|
|
||||||
|
@ -229,36 +182,33 @@ fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Er
|
||||||
typos::Status::Invalid => {
|
typos::Status::Invalid => {
|
||||||
writeln!(
|
writeln!(
|
||||||
handle,
|
handle,
|
||||||
"{:#}: {:#}",
|
"{error}error{reset}: `{error}{}{reset}` is disallowed",
|
||||||
palette.error("error"),
|
msg.typo,
|
||||||
palette.strong(format_args!("`{}` is disallowed", msg.typo))
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
typos::Status::Corrections(corrections) => {
|
typos::Status::Corrections(corrections) => {
|
||||||
writeln!(
|
writeln!(
|
||||||
handle,
|
handle,
|
||||||
"{:#}: {:#}",
|
"{error}error{reset}: `{error}{}{reset}` should be {}",
|
||||||
palette.error("error"),
|
msg.typo,
|
||||||
palette.strong(format_args!(
|
itertools::join(
|
||||||
"`{}` should be {}",
|
corrections.iter().map(|s| format!("`{good}{}{reset}`", s)),
|
||||||
msg.typo,
|
", "
|
||||||
itertools::join(corrections.iter().map(|s| format!("`{}`", s)), ", ")
|
)
|
||||||
))
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let divider = ":";
|
let divider = ":";
|
||||||
writeln!(
|
writeln!(
|
||||||
handle,
|
handle,
|
||||||
" --> {:#}{:#}{:#}",
|
"{info} --> {reset}{}{divider}{column_number}",
|
||||||
palette.info(context_display(&msg.context)),
|
context_display(&msg.context),
|
||||||
palette.info(divider),
|
|
||||||
palette.info(column_number)
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(Context::File(context)) = &msg.context {
|
if let Some(Context::File(context)) = &msg.context {
|
||||||
let line_num = context.line_num.to_string();
|
let line_num = context.line_num.to_string();
|
||||||
let line_indent: String = itertools::repeat_n(" ", line_num.len()).collect();
|
let line_indent: String = itertools::repeat_n(" ", line_num.len()).collect();
|
||||||
|
let line = line.trim_end();
|
||||||
|
|
||||||
let visible_column = calculate_visible_column_width(start.as_ref());
|
let visible_column = calculate_visible_column_width(start.as_ref());
|
||||||
let visible_len = calculate_visible_column_width(msg.typo);
|
let visible_len = calculate_visible_column_width(msg.typo);
|
||||||
|
@ -266,16 +216,13 @@ fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Er
|
||||||
let hl_indent: String = itertools::repeat_n(" ", visible_column).collect();
|
let hl_indent: String = itertools::repeat_n(" ", visible_column).collect();
|
||||||
let hl: String = itertools::repeat_n("^", visible_len).collect();
|
let hl: String = itertools::repeat_n("^", visible_len).collect();
|
||||||
|
|
||||||
writeln!(handle, "{} |", line_indent)?;
|
writeln!(handle, "{info}{line_indent} |{reset}")?;
|
||||||
writeln!(handle, "{:#} | {}", palette.info(line_num), line.trim_end())?;
|
writeln!(handle, "{info}{line_num} |{reset} {line}")?;
|
||||||
writeln!(
|
writeln!(
|
||||||
handle,
|
handle,
|
||||||
"{} | {}{:#}",
|
"{info}{line_indent} |{reset} {hl_indent}{error}{hl}{reset}",
|
||||||
line_indent,
|
|
||||||
hl_indent,
|
|
||||||
palette.error(hl)
|
|
||||||
)?;
|
)?;
|
||||||
writeln!(handle, "{} |", line_indent)?;
|
writeln!(handle, "{info}{line_indent} |{reset}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -6,6 +6,6 @@ stdin = '''
|
||||||
Destory
|
Destory
|
||||||
'''
|
'''
|
||||||
stdout = """
|
stdout = """
|
||||||
./key.asc:asc
|
./key.asc: asc
|
||||||
"""
|
"""
|
||||||
stderr = ""
|
stderr = ""
|
||||||
|
|
Loading…
Reference in a new issue