Skip to content

Commit 6a7b7d0

Browse files
authored
Merge pull request #864 from epage/color
fix(cli): Improve color formatting
2 parents 00220c3 + 0a5b4ab commit 6a7b7d0

File tree

4 files changed

+55
-120
lines changed

4 files changed

+55
-120
lines changed

crates/typos-cli/src/bin/typos-cli/args.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,11 @@ pub enum Format {
1313
}
1414

1515
impl Format {
16-
pub(crate) fn reporter(
17-
self,
18-
stdout_palette: crate::report::Palette,
19-
stderr_palette: crate::report::Palette,
20-
) -> Box<dyn typos_cli::report::Report> {
16+
pub(crate) fn reporter(self) -> Box<dyn typos_cli::report::Report> {
2117
match self {
2218
Format::Silent => Box::new(crate::report::PrintSilent),
23-
Format::Brief => Box::new(crate::report::PrintBrief {
24-
stdout_palette,
25-
stderr_palette,
26-
}),
27-
Format::Long => Box::new(crate::report::PrintLong {
28-
stdout_palette,
29-
stderr_palette,
30-
}),
19+
Format::Brief => Box::new(crate::report::PrintBrief),
20+
Format::Long => Box::new(crate::report::PrintLong),
3121
Format::Json => Box::new(crate::report::PrintJson),
3222
}
3323
}

crates/typos-cli/src/bin/typos-cli/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,7 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult {
255255
let output_reporter = if args.diff {
256256
Box::new(crate::report::PrintSilent)
257257
} else {
258-
let stdout_palette = report::Palette::colored();
259-
let stderr_palette = report::Palette::colored();
260-
args.format.reporter(stdout_palette, stderr_palette)
258+
args.format.reporter()
261259
};
262260
let status_reporter = report::MessageStatus::new(output_reporter.as_ref());
263261
let reporter: &dyn typos_cli::report::Report = &status_reporter;

crates/typos-cli/src/bin/typos-cli/report.rs

Lines changed: 50 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,60 +8,9 @@ use unicode_width::UnicodeWidthStr;
88

99
use typos_cli::report::{Context, Message, Report, Typo};
1010

11-
#[derive(Copy, Clone, Debug, Default)]
12-
pub struct Palette {
13-
error: anstyle::Style,
14-
info: anstyle::Style,
15-
strong: anstyle::Style,
16-
}
17-
18-
impl Palette {
19-
pub fn colored() -> Self {
20-
Self {
21-
error: anstyle::AnsiColor::Red.on_default(),
22-
info: anstyle::AnsiColor::Blue.on_default(),
23-
strong: anstyle::Effects::BOLD.into(),
24-
}
25-
}
26-
27-
pub(crate) fn error<D: std::fmt::Display>(self, display: D) -> Styled<D> {
28-
Styled::new(display, self.error)
29-
}
30-
31-
pub(crate) fn info<D: std::fmt::Display>(self, display: D) -> Styled<D> {
32-
Styled::new(display, self.info)
33-
}
34-
35-
pub(crate) fn strong<D: std::fmt::Display>(self, display: D) -> Styled<D> {
36-
Styled::new(display, self.strong)
37-
}
38-
}
39-
40-
#[derive(Debug)]
41-
pub(crate) struct Styled<D> {
42-
display: D,
43-
style: anstyle::Style,
44-
}
45-
46-
impl<D: std::fmt::Display> Styled<D> {
47-
pub(crate) fn new(display: D, style: anstyle::Style) -> Self {
48-
Self { display, style }
49-
}
50-
}
51-
52-
impl<D: std::fmt::Display> std::fmt::Display for Styled<D> {
53-
#[inline]
54-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55-
if f.alternate() {
56-
write!(f, "{}", self.style.render())?;
57-
self.display.fmt(f)?;
58-
write!(f, "{}", self.style.render_reset())?;
59-
Ok(())
60-
} else {
61-
self.display.fmt(f)
62-
}
63-
}
64-
}
11+
const ERROR: anstyle::Style = anstyle::AnsiColor::BrightRed.on_default();
12+
const INFO: anstyle::Style = anstyle::AnsiColor::BrightBlue.on_default();
13+
const GOOD: anstyle::Style = anstyle::AnsiColor::BrightGreen.on_default();
6514

6615
pub struct MessageStatus<'r> {
6716
typos_found: atomic::AtomicBool,
@@ -108,22 +57,21 @@ impl Report for PrintSilent {
10857
}
10958
}
11059

111-
pub struct PrintBrief {
112-
pub stdout_palette: Palette,
113-
pub stderr_palette: Palette,
114-
}
60+
pub struct PrintBrief;
11561

11662
impl Report for PrintBrief {
11763
fn report(&self, msg: Message) -> Result<(), std::io::Error> {
11864
match &msg {
11965
Message::BinaryFile(msg) => {
12066
log::info!("{}", msg);
12167
}
122-
Message::Typo(msg) => print_brief_correction(msg, self.stdout_palette)?,
68+
Message::Typo(msg) => print_brief_correction(msg)?,
12369
Message::FileType(msg) => {
70+
let info = INFO.render();
71+
let reset = anstyle::Reset.render();
12472
writeln!(
12573
stdout().lock(),
126-
"{}:{}",
74+
"{info}{}{reset}: {}",
12775
msg.path.display(),
12876
msg.file_type.unwrap_or("-")
12977
)?;
@@ -143,22 +91,21 @@ impl Report for PrintBrief {
14391
}
14492
}
14593

146-
pub struct PrintLong {
147-
pub stdout_palette: Palette,
148-
pub stderr_palette: Palette,
149-
}
94+
pub struct PrintLong;
15095

15196
impl Report for PrintLong {
15297
fn report(&self, msg: Message) -> Result<(), std::io::Error> {
15398
match &msg {
15499
Message::BinaryFile(msg) => {
155100
log::info!("{}", msg);
156101
}
157-
Message::Typo(msg) => print_long_correction(msg, self.stdout_palette)?,
102+
Message::Typo(msg) => print_long_correction(msg)?,
158103
Message::FileType(msg) => {
104+
let info = INFO.render();
105+
let reset = anstyle::Reset.render();
159106
writeln!(
160107
stdout().lock(),
161-
"{}:{}",
108+
"{info}{}{reset}: {}",
162109
msg.path.display(),
163110
msg.file_type.unwrap_or("-")
164111
)?;
@@ -178,7 +125,12 @@ impl Report for PrintLong {
178125
}
179126
}
180127

181-
fn print_brief_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Error> {
128+
fn print_brief_correction(msg: &Typo) -> Result<(), std::io::Error> {
129+
let error = ERROR.render();
130+
let good = GOOD.render();
131+
let info = INFO.render();
132+
let reset = anstyle::Reset.render();
133+
182134
let start = String::from_utf8_lossy(&msg.buffer[0..msg.byte_offset]);
183135
let column_number =
184136
unicode_segmentation::UnicodeSegmentation::graphemes(start.as_ref(), true).count() + 1;
@@ -188,34 +140,35 @@ fn print_brief_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::E
188140
let divider = ":";
189141
writeln!(
190142
stdout().lock(),
191-
"{:#}{:#}{:#}: {:#}",
192-
palette.info(context_display(&msg.context)),
193-
palette.info(divider),
194-
palette.info(column_number),
195-
palette.strong(format_args!("`{}` is disallowed:", msg.typo)),
143+
"{info}{}{divider}{column_number}{reset}: `{error}{}{reset}` is disallowed",
144+
context_display(&msg.context),
145+
msg.typo,
196146
)?;
197147
}
198148
typos::Status::Corrections(corrections) => {
199149
let divider = ":";
200150
writeln!(
201151
stdout().lock(),
202-
"{:#}{:#}{:#}: {:#}",
203-
palette.info(context_display(&msg.context)),
204-
palette.info(divider),
205-
palette.info(column_number),
206-
palette.strong(format_args!(
207-
"`{}` -> {}",
208-
msg.typo,
209-
itertools::join(corrections.iter().map(|s| format!("`{}`", s)), ", ")
210-
)),
152+
"{info}{}{divider}{column_number}{reset}: `{error}{}{reset}` -> {}",
153+
context_display(&msg.context),
154+
msg.typo,
155+
itertools::join(
156+
corrections.iter().map(|s| format!("`{good}{}{reset}`", s)),
157+
", "
158+
)
211159
)?;
212160
}
213161
}
214162

215163
Ok(())
216164
}
217165

218-
fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Error> {
166+
fn print_long_correction(msg: &Typo) -> Result<(), std::io::Error> {
167+
let error = ERROR.render();
168+
let good = GOOD.render();
169+
let info = INFO.render();
170+
let reset = anstyle::Reset.render();
171+
219172
let stdout = stdout();
220173
let mut handle = stdout.lock();
221174

@@ -229,53 +182,47 @@ fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Er
229182
typos::Status::Invalid => {
230183
writeln!(
231184
handle,
232-
"{:#}: {:#}",
233-
palette.error("error"),
234-
palette.strong(format_args!("`{}` is disallowed", msg.typo))
185+
"{error}error{reset}: `{error}{}{reset}` is disallowed",
186+
msg.typo,
235187
)?;
236188
}
237189
typos::Status::Corrections(corrections) => {
238190
writeln!(
239191
handle,
240-
"{:#}: {:#}",
241-
palette.error("error"),
242-
palette.strong(format_args!(
243-
"`{}` should be {}",
244-
msg.typo,
245-
itertools::join(corrections.iter().map(|s| format!("`{}`", s)), ", ")
246-
))
192+
"{error}error{reset}: `{error}{}{reset}` should be {}",
193+
msg.typo,
194+
itertools::join(
195+
corrections.iter().map(|s| format!("`{good}{}{reset}`", s)),
196+
", "
197+
)
247198
)?;
248199
}
249200
}
250201
let divider = ":";
251202
writeln!(
252203
handle,
253-
" --> {:#}{:#}{:#}",
254-
palette.info(context_display(&msg.context)),
255-
palette.info(divider),
256-
palette.info(column_number)
204+
"{info} --> {reset}{}{divider}{column_number}",
205+
context_display(&msg.context),
257206
)?;
258207

259208
if let Some(Context::File(context)) = &msg.context {
260209
let line_num = context.line_num.to_string();
261210
let line_indent: String = itertools::repeat_n(" ", line_num.len()).collect();
211+
let line = line.trim_end();
262212

263213
let visible_column = calculate_visible_column_width(start.as_ref());
264214
let visible_len = calculate_visible_column_width(msg.typo);
265215

266216
let hl_indent: String = itertools::repeat_n(" ", visible_column).collect();
267217
let hl: String = itertools::repeat_n("^", visible_len).collect();
268218

269-
writeln!(handle, "{} |", line_indent)?;
270-
writeln!(handle, "{:#} | {}", palette.info(line_num), line.trim_end())?;
219+
writeln!(handle, "{info}{line_indent} |{reset}")?;
220+
writeln!(handle, "{info}{line_num} |{reset} {line}")?;
271221
writeln!(
272222
handle,
273-
"{} | {}{:#}",
274-
line_indent,
275-
hl_indent,
276-
palette.error(hl)
223+
"{info}{line_indent} |{reset} {hl_indent}{error}{hl}{reset}",
277224
)?;
278-
writeln!(handle, "{} |", line_indent)?;
225+
writeln!(handle, "{info}{line_indent} |{reset}")?;
279226
}
280227

281228
Ok(())

crates/typos-cli/tests/cmd/override-default-type.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ stdin = '''
66
Destory
77
'''
88
stdout = """
9-
./key.asc:asc
9+
./key.asc: asc
1010
"""
1111
stderr = ""

0 commit comments

Comments
 (0)