diff --git a/Cargo.lock b/Cargo.lock index bee0e62b0..3a53e7d78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "annotate-snippets" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982b1e014494ccc9d4737fa74eee118cd67b1905d781b7b9d03b32d77858593f" +dependencies = [ + "anstyle", + "unicode-width", +] + [[package]] name = "anstream" version = "0.6.19" @@ -550,12 +560,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] @@ -775,6 +785,12 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "log" version = "0.4.27" @@ -1085,10 +1101,23 @@ dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.10", "windows-sys 0.48.0", ] +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.60.2", +] + [[package]] name = "rustversion" version = "1.0.18" @@ -1344,6 +1373,12 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + [[package]] name = "syn" version = "1.0.109" @@ -1375,18 +1410,18 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix", + "rustix 0.38.19", "windows-sys 0.48.0", ] [[package]] name = "terminal_size" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ - "rustix", - "windows-sys 0.59.0", + "rustix 1.0.8", + "windows-sys 0.60.2", ] [[package]] @@ -1540,6 +1575,7 @@ name = "typos-cli" version = "1.36.0" dependencies = [ "ahash", + "annotate-snippets", "anstream", "anstyle", "anyhow", @@ -1570,6 +1606,8 @@ dependencies = [ "serde_json", "serde_regex", "snapbox", + "supports-unicode", + "terminal_size", "thread_local", "toml", "trycmd", @@ -1577,10 +1615,7 @@ dependencies = [ "typos", "typos-dict", "typos-vars", - "unic-emoji-char", "unicase", - "unicode-segmentation", - "unicode-width", "varcon-core", ] @@ -1615,47 +1650,6 @@ dependencies = [ "varcon-core", ] -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-emoji-char" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicase" version = "2.8.1" @@ -1668,12 +1662,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-width" version = "0.2.1" @@ -1809,6 +1797,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-sys" version = "0.48.0" @@ -1827,6 +1821,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -1851,13 +1854,30 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -1870,6 +1890,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -1882,6 +1908,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -1894,12 +1926,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -1912,6 +1956,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -1924,6 +1974,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -1936,6 +1992,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -1948,6 +2010,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.7.12" diff --git a/crates/typos-cli/Cargo.toml b/crates/typos-cli/Cargo.toml index 9ff651b56..d5d03ad69 100644 --- a/crates/typos-cli/Cargo.toml +++ b/crates/typos-cli/Cargo.toml @@ -60,15 +60,12 @@ difflib = "0.4" proc-exit = "2.0" human-panic = "2.0.3" content_inspector = "0.2.4" -unicode-segmentation = "1.11.0" derive_more = { version = "2.0", features = ["from", "display"] } derive_setters = "0.1" itertools = "0.14" serde_json = "1.0" kstring = { version = "2.0.0", features = ["serde"] } typed-arena = "2.0.2" -unicode-width = "0.2.0" -unic-emoji-char = "0.9.0" thread_local = "1.1.8" globset = "0.4.14" anstyle = "1.0.6" @@ -79,6 +76,9 @@ regex = "1.10.4" encoding_rs = "0.8.34" serde-sarif = "0.7.0" schemars = { version = "0.9.0", features = ["preserve_order","semver1"], optional = true } +annotate-snippets = "0.12.2" +terminal_size = "0.4.3" +supports-unicode = "3.0.0" [dev-dependencies] assert_fs = "1.1" diff --git a/crates/typos-cli/src/bin/typos-cli/report.rs b/crates/typos-cli/src/bin/typos-cli/report.rs index 74aeccdd0..a8f267764 100644 --- a/crates/typos-cli/src/bin/typos-cli/report.rs +++ b/crates/typos-cli/src/bin/typos-cli/report.rs @@ -1,17 +1,22 @@ #![allow(clippy::needless_update)] +use std::borrow::Cow; use std::io::Write as _; use std::sync::{atomic, Mutex}; +use annotate_snippets::Annotation; +use annotate_snippets::AnnotationKind; +use annotate_snippets::Group; +use annotate_snippets::Level; +use annotate_snippets::Origin; +use annotate_snippets::Snippet; +use anstream::stderr; use anstream::stdout; use serde_sarif::sarif; use serde_sarif::sarif::{ArtifactChange, ArtifactContent, Fix, Replacement}; -use typos_cli::report::{Context, Message, Report, Typo}; -use unicode_width::UnicodeWidthStr; +use typos_cli::report::{Context, Error, Message, Report, Typo}; -const ERROR: anstyle::Style = anstyle::AnsiColor::BrightRed.on_default(); const INFO: anstyle::Style = anstyle::AnsiColor::BrightBlue.on_default(); -const GOOD: anstyle::Style = anstyle::AnsiColor::BrightGreen.on_default(); pub(crate) struct MessageStatus<'r> { typos_found: atomic::AtomicBool, @@ -66,11 +71,15 @@ pub(crate) struct PrintBrief; impl Report for PrintBrief { fn report(&self, msg: Message<'_>) -> Result<(), std::io::Error> { + let renderer = RENDERER.clone().short_message(true); match &msg { Message::BinaryFile(msg) => { log::info!("{msg}"); } - Message::Typo(msg) => print_brief_correction(msg)?, + Message::Typo(msg) => { + let report = &[typo_to_group(msg)]; + writeln!(stdout(), "{}", renderer.render(report))?; + } Message::FileType(msg) => { let info = INFO.render(); let reset = anstyle::Reset.render(); @@ -88,7 +97,8 @@ impl Report for PrintBrief { writeln!(stdout().lock(), "{}", msg.data)?; } Message::Error(msg) => { - log::error!("{}: {}", context_display(&msg.context), msg.msg); + let report = &[error_to_group(msg)]; + writeln!(stderr(), "{}", renderer.render(report))?; } _ => unimplemented!("New message {:?}", msg), } @@ -104,7 +114,10 @@ impl Report for PrintLong { Message::BinaryFile(msg) => { log::info!("{msg}"); } - Message::Typo(msg) => print_long_correction(msg)?, + Message::Typo(msg) => { + let report = &[typo_to_group(msg)]; + writeln!(stdout(), "{}", RENDERER.render(report))?; + } Message::FileType(msg) => { let info = INFO.render(); let reset = anstyle::Reset.render(); @@ -122,7 +135,8 @@ impl Report for PrintLong { writeln!(stdout().lock(), "{}", msg.data)?; } Message::Error(msg) => { - log::error!("{}: {}", context_display(&msg.context), msg.msg); + let report = &[error_to_group(msg)]; + writeln!(stderr(), "{}", RENDERER.render(report))?; } _ => unimplemented!("New message {:?}", msg), } @@ -130,150 +144,86 @@ impl Report for PrintLong { } } -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 column_number = - unicode_segmentation::UnicodeSegmentation::graphemes(start.as_ref(), true).count() + 1; - match &msg.corrections { - typos::Status::Valid => {} +fn typo_to_group<'t>(msg: &'t Typo<'t>) -> Group<'t> { + let title = match &msg.corrections { + typos::Status::Valid => unimplemented!("never valid words to report"), typos::Status::Invalid => { - let divider = ":"; - writeln!( - stdout().lock(), - "{info}{}{divider}{column_number}{reset}: `{error}{}{reset}` is disallowed", - context_display(&msg.context), - msg.typo, - )?; + format!("`{}` is disallowed", msg.typo,) } typos::Status::Corrections(corrections) => { - let divider = ":"; - writeln!( - stdout().lock(), - "{info}{}{divider}{column_number}{reset}: `{error}{}{reset}` -> {}", - context_display(&msg.context), + format!( + "`{}` should be {}", msg.typo, - itertools::join( - corrections.iter().map(|s| format!("`{good}{s}{reset}`")), - ", " - ) - )?; + itertools::join(corrections.iter().map(|s| format!("`{s}`")), ", ") + ) } - } - - Ok(()) -} - -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 mut handle = stdout.lock(); - - let line = String::from_utf8_lossy(msg.buffer.as_ref()); - let line = line.replace('\t', " "); - let start = String::from_utf8_lossy(&msg.buffer[0..msg.byte_offset]); - let column_number = - unicode_segmentation::UnicodeSegmentation::graphemes(start.as_ref(), true).count() + 1; - match &msg.corrections { - typos::Status::Valid => {} - typos::Status::Invalid => { - writeln!( - handle, - "{error}error{reset}: `{error}{}{reset}` is disallowed", - msg.typo, - )?; + }; + let group = Group::with_title(Level::ERROR.primary_title(Cow::Owned(title))); + let group = match &msg.context { + Some(Context::File(context)) => { + let path = context.path.as_os_str().to_string_lossy(); + let line = String::from_utf8_lossy(msg.buffer.as_ref()); + let snippet = Snippet::source(line) + .path(path) + .line_start(context.line_num); + append_corrections(msg, 0, snippet, group) } - typos::Status::Corrections(corrections) => { - writeln!( - handle, - "{error}error{reset}: `{error}{}{reset}` should be {}", - msg.typo, - itertools::join( - corrections.iter().map(|s| format!("`{good}{s}{reset}`")), - ", " - ) - )?; + Some(Context::Path(context)) => { + let path = context + .path + .parent() + .unwrap_or(std::path::Path::new(".")) + .join(""); + let path = path.as_os_str().to_string_lossy(); + let line = context.path.as_os_str().to_string_lossy(); + let snippet = Snippet::source(line); + append_corrections(msg, path.len(), snippet, group) } - } - let divider = ":"; - writeln!( - handle, - "{info} --> {reset}{}{divider}{column_number}", - context_display(&msg.context), - )?; - - if let Some(Context::File(context)) = &msg.context { - let line_num = context.line_num.to_string(); - 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_len = calculate_visible_column_width(msg.typo); - - let hl_indent: String = itertools::repeat_n(" ", visible_column).collect(); - let hl: String = itertools::repeat_n("^", visible_len).collect(); - - writeln!(handle, "{info}{line_indent} |{reset}")?; - writeln!(handle, "{info}{line_num} |{reset} {line}")?; - writeln!( - handle, - "{info}{line_indent} |{reset} {hl_indent}{error}{hl}{reset}", - )?; - writeln!(handle, "{info}{line_indent} |{reset}")?; - } - - Ok(()) + Some(_) | None => group, + }; + group } -fn calculate_visible_column_width(str: &str) -> usize { - let mut result = 0; - let graphemes = unicode_segmentation::UnicodeSegmentation::graphemes(str, true); - for grapheme in graphemes { - result += if grapheme == "\t" { - // TODO: config tab width - 1 - } else if is_emoji(grapheme) { - // UnicodeWidthStr::width doesn't cover for emoji according to their README. - // See: https://github.com/unicode-rs/unicode-width#unicode-width - // Also, the actual rendered column width may differ from calculation, especially for emojis. - // In here, we expect emoji renderers should render this emoji properly. - 2 - } else { - UnicodeWidthStr::width(grapheme) - } - } - - result +fn append_corrections<'t>( + msg: &'t Typo<'t>, + offset: usize, + snippet: Snippet<'t, Annotation<'t>>, + group: Group<'t>, +) -> Group<'t> { + let span_start = msg.byte_offset + offset; + let span_end = span_start + msg.typo.len(); + let span = span_start..span_end; + let snippet = snippet.annotation(AnnotationKind::Primary.span(span)); + group.element(snippet) } -fn is_emoji(grapheme: &str) -> bool { - if grapheme.is_ascii() { - return false; - } - - for ch in grapheme.chars() { - if unic_emoji_char::is_emoji(ch) { - return true; +fn error_to_group<'e>(error: &'e Error<'e>) -> Group<'e> { + let group = Group::with_title(Level::ERROR.primary_title(&error.msg)); + match &error.context { + Some(Context::File(context)) => group.element( + Origin::path(context.path.as_os_str().to_string_lossy()).line(context.line_num), + ), + Some(Context::Path(context)) => { + group.element(Origin::path(context.path.as_os_str().to_string_lossy())) } + Some(_) | None => group, } - - false } -fn context_display<'c>(context: &'c Option>) -> &'c dyn std::fmt::Display { - context - .as_ref() - .map(|c| c as &dyn std::fmt::Display) - .unwrap_or(&"") -} +static RENDERER: std::sync::LazyLock = + std::sync::LazyLock::new(|| { + let width = terminal_size::terminal_size() + .map(|(w, _)| w.0 as usize) + .unwrap_or(annotate_snippets::renderer::DEFAULT_TERM_WIDTH); + let decor_style = if supports_unicode::supports_unicode() { + annotate_snippets::renderer::DecorStyle::Unicode + } else { + annotate_snippets::renderer::DecorStyle::Ascii + }; + annotate_snippets::Renderer::styled() + .term_width(width) + .decor_style(decor_style) + }); #[derive(Copy, Clone, Debug)] pub(crate) struct PrintJson; @@ -500,80 +450,3 @@ fn typo_to_sarif_location(msg: &Typo<'_>) -> Result ./file:1:1 - | -1 | hello `hello` - | ^^^^^ - | + ╭▸ ./file:1:1 + │ +1 │ hello `hello` + ╰╴━━━━━ error: `hello` is disallowed - --> ./file:1:8 - | -1 | hello `hello` - | ^^^^^ - | + ╭▸ ./file:1:8 + │ +1 │ hello `hello` + ╰╴ ━━━━━ """ stderr = "" diff --git a/crates/typos-cli/tests/cmd/extend-exclude-inverted.toml b/crates/typos-cli/tests/cmd/extend-exclude-inverted.toml index b8e837b0c..6a5d7ca20 100644 --- a/crates/typos-cli/tests/cmd/extend-exclude-inverted.toml +++ b/crates/typos-cli/tests/cmd/extend-exclude-inverted.toml @@ -2,11 +2,10 @@ bin.name = "typos" stdin = "" stdout = """ error: `hte` should be `the` - --> ./checked/file.txt:1:1 - | -1 | hte - | ^^^ - | + ╭▸ ./checked/file.txt:1:1 + │ +1 │ hte + ╰╴━━━ """ stderr = "" status.code = 2 diff --git a/crates/typos-cli/tests/cmd/extend-ignore-identifiers-re.toml b/crates/typos-cli/tests/cmd/extend-ignore-identifiers-re.toml index 60502ebd5..25aa9dcda 100644 --- a/crates/typos-cli/tests/cmd/extend-ignore-identifiers-re.toml +++ b/crates/typos-cli/tests/cmd/extend-ignore-identifiers-re.toml @@ -3,10 +3,9 @@ status.code = 2 stdin = "" stdout = """ error: `hello` should be `goodbye` - --> ./file.fail:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ ./file.fail:1:1 + │ +1 │ hello + ╰╴━━━━━ """ stderr = "" diff --git a/crates/typos-cli/tests/cmd/extend-ignore-re.toml b/crates/typos-cli/tests/cmd/extend-ignore-re.toml index 74c74079b..3f5d1bce7 100644 --- a/crates/typos-cli/tests/cmd/extend-ignore-re.toml +++ b/crates/typos-cli/tests/cmd/extend-ignore-re.toml @@ -3,17 +3,15 @@ args = "--sort" stdin = "" stdout = """ error: `hello` should be `goodbye` - --> ./file.ignore:1:1 - | -1 | hello `hello` - | ^^^^^ - | + ╭▸ ./file.ignore:1:1 + │ +1 │ hello `hello` + ╰╴━━━━━ error: `olt` should be `old` - --> ./olt-manager.php:1:5 - | -1 | One olt two - | ^^^ - | + ╭▸ ./olt-manager.php:1:5 + │ +1 │ One olt two + ╰╴ ━━━ """ stderr = "" status.code = 2 diff --git a/crates/typos-cli/tests/cmd/extend-ignore-words-re.toml b/crates/typos-cli/tests/cmd/extend-ignore-words-re.toml index 60502ebd5..25aa9dcda 100644 --- a/crates/typos-cli/tests/cmd/extend-ignore-words-re.toml +++ b/crates/typos-cli/tests/cmd/extend-ignore-words-re.toml @@ -3,10 +3,9 @@ status.code = 2 stdin = "" stdout = """ error: `hello` should be `goodbye` - --> ./file.fail:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ ./file.fail:1:1 + │ +1 │ hello + ╰╴━━━━━ """ stderr = "" diff --git a/crates/typos-cli/tests/cmd/extend-words-case.toml b/crates/typos-cli/tests/cmd/extend-words-case.toml index 139615829..bdef7a2f7 100644 --- a/crates/typos-cli/tests/cmd/extend-words-case.toml +++ b/crates/typos-cli/tests/cmd/extend-words-case.toml @@ -4,10 +4,9 @@ status.code = 2 stdin = "" stdout = """ error: `Trailling` should be `Trailing` - --> ./file.txt:1:26 - | -1 | public function noErrorOnTraillingSemicolonAndWhitespace(Connection $connection) - | ^^^^^^^^^ - | + ╭▸ ./file.txt:1:26 + │ +1 │ public function noErrorOnTraillingSemicolonAndWhitespace(Connection $connection) + ╰╴ ━━━━━━━━━ """ stderr = "" diff --git a/crates/typos-cli/tests/cmd/file-list-stdin.toml b/crates/typos-cli/tests/cmd/file-list-stdin.toml index aaad0e1e0..52d385741 100644 --- a/crates/typos-cli/tests/cmd/file-list-stdin.toml +++ b/crates/typos-cli/tests/cmd/file-list-stdin.toml @@ -6,17 +6,15 @@ d.fail """ stdout = """ error: `hello` should be `goodbye` - --> b.fail:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ b.fail:1:1 + │ +1 │ hello + ╰╴━━━━━ error: `hello` should be `goodbye` - --> d.fail:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ d.fail:1:1 + │ +1 │ hello + ╰╴━━━━━ """ stderr = "" status.code = 2 diff --git a/crates/typos-cli/tests/cmd/filename-typo.in/README.md b/crates/typos-cli/tests/cmd/filename-typo.in/README.md new file mode 100644 index 000000000..8acf91a30 --- /dev/null +++ b/crates/typos-cli/tests/cmd/filename-typo.in/README.md @@ -0,0 +1,4 @@ +We should not correct +- goes +- ret +- prev diff --git a/crates/typos-cli/tests/cmd/filename-typo.in/makro.rs b/crates/typos-cli/tests/cmd/filename-typo.in/makro.rs new file mode 100644 index 000000000..e69de29bb diff --git a/crates/typos-cli/tests/cmd/filename-typo.toml b/crates/typos-cli/tests/cmd/filename-typo.toml new file mode 100644 index 000000000..44b5c0eaa --- /dev/null +++ b/crates/typos-cli/tests/cmd/filename-typo.toml @@ -0,0 +1,10 @@ +bin.name = "typos" +stdin = "" +stdout = """ +error: `makro` should be `macro` + ╭▸ +1 │ ./makro.rs + ╰╴ ━━━━━ +""" +stderr = "" +status.code = 2 diff --git a/crates/typos-cli/tests/cmd/ignore-block.toml b/crates/typos-cli/tests/cmd/ignore-block.toml index f7229a418..0dcac613e 100644 --- a/crates/typos-cli/tests/cmd/ignore-block.toml +++ b/crates/typos-cli/tests/cmd/ignore-block.toml @@ -2,17 +2,15 @@ bin.name = "typos" stdin = "--sort" stdout = """ error: `hello` should be `goodbye` - --> ./file.ignore:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ ./file.ignore:1:1 + │ +1 │ hello + ╰╴━━━━━ error: `hello` should be `goodbye` - --> ./file.ignore:6:1 - | -6 | hello - | ^^^^^ - | + ╭▸ ./file.ignore:6:1 + │ +6 │ hello + ╰╴━━━━━ """ stderr = "" status.code = 2 diff --git a/crates/typos-cli/tests/cmd/ignore-line.toml b/crates/typos-cli/tests/cmd/ignore-line.toml index 7a5eae202..d939a5ef7 100644 --- a/crates/typos-cli/tests/cmd/ignore-line.toml +++ b/crates/typos-cli/tests/cmd/ignore-line.toml @@ -2,17 +2,15 @@ bin.name = "typos" stdin = "--sort" stdout = """ error: `hello` should be `goodbye` - --> ./file.ignore:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ ./file.ignore:1:1 + │ +1 │ hello + ╰╴━━━━━ error: `hello` should be `goodbye` - --> ./file.ignore:3:1 - | -3 | hello - | ^^^^^ - | + ╭▸ ./file.ignore:3:1 + │ +3 │ hello + ╰╴━━━━━ """ stderr = "" status.code = 2 diff --git a/crates/typos-cli/tests/cmd/ignore-next-line.toml b/crates/typos-cli/tests/cmd/ignore-next-line.toml index f7229a418..0dcac613e 100644 --- a/crates/typos-cli/tests/cmd/ignore-next-line.toml +++ b/crates/typos-cli/tests/cmd/ignore-next-line.toml @@ -2,17 +2,15 @@ bin.name = "typos" stdin = "--sort" stdout = """ error: `hello` should be `goodbye` - --> ./file.ignore:1:1 - | -1 | hello - | ^^^^^ - | + ╭▸ ./file.ignore:1:1 + │ +1 │ hello + ╰╴━━━━━ error: `hello` should be `goodbye` - --> ./file.ignore:6:1 - | -6 | hello - | ^^^^^ - | + ╭▸ ./file.ignore:6:1 + │ +6 │ hello + ╰╴━━━━━ """ stderr = "" status.code = 2 diff --git a/crates/typos-cli/tests/cmd/stdin-failure-multiwidth.toml b/crates/typos-cli/tests/cmd/stdin-failure-multiwidth.toml index 34d656dd2..7edaf9900 100644 --- a/crates/typos-cli/tests/cmd/stdin-failure-multiwidth.toml +++ b/crates/typos-cli/tests/cmd/stdin-failure-multiwidth.toml @@ -39,34 +39,29 @@ Grapheme clusters: 1, codepoints: 1, UnicodeWidthStr::width() == 0 ''' stdout = """ error: `Apropriate` should be `Appropriate` - --> -:5:3 - | -5 | 한 Apropriate world - | ^^^^^^^^^^ - | + ╭▸ -:5:3 + │ +5 │ 한 Apropriate world + ╰╴ ━━━━━━━━━━ error: `Apropriate` should be `Appropriate` - --> -:12:3 - | -12 | 한 Apropriate world - | ^^^^^^^^^^ - | + ╭▸ -:12:3 + │ +12 │ 한 Apropriate world + ╰╴ ━━━━━━━━━━ error: `Apropriate` should be `Appropriate` - --> -:19:3 - | -19 | 👁️‍🗨️ Apropriate world - | ^^^^^^^^^^ - | + ╭▸ -:19:7 + │ +19 │ 👁️🗨️ Apropriate world + ╰╴ ━━━━━━━━━━ error: `Apropriate` should be `Appropriate` - --> -:26:3 - | -26 | 😵‍💫 Apropriate world - | ^^^^^^^^^^ - | + ╭▸ -:26:5 + │ +26 │ 😵💫 Apropriate world + ╰╴ ━━━━━━━━━━ error: `Apropriate` should be `Appropriate` - --> -:33:2 - | -33 | Apropriate world - | ^^^^^^^^^^ - | + ╭▸ -:33:2 + │ +33 │ Apropriate world + ╰╴ ━━━━━━━━━━ """ stderr = "" diff --git a/crates/typos-cli/tests/cmd/stdin-failure.toml b/crates/typos-cli/tests/cmd/stdin-failure.toml index 9428a7818..535f2b469 100644 --- a/crates/typos-cli/tests/cmd/stdin-failure.toml +++ b/crates/typos-cli/tests/cmd/stdin-failure.toml @@ -6,10 +6,9 @@ Apropriate world ''' stdout = """ error: `Apropriate` should be `Appropriate` - --> -:1:1 - | -1 | Apropriate world - | ^^^^^^^^^^ - | + ╭▸ -:1:1 + │ +1 │ Apropriate world + ╰╴━━━━━━━━━━ """ stderr = ""