fix: Fix highlight indenting for emojis and tab characters

This commit is contained in:
SeongChan Lee 2022-04-27 12:05:29 +09:00
parent f2de431701
commit c191a78a77
5 changed files with 70 additions and 6 deletions

42
Cargo.lock generated
View file

@ -1574,6 +1574,7 @@ dependencies = [
"typos", "typos",
"typos-dict", "typos-dict",
"typos-vars", "typos-vars",
"unic-emoji-char",
"unicase", "unicase",
"unicode-segmentation", "unicode-segmentation",
"unicode-width", "unicode-width",
@ -1642,6 +1643,47 @@ dependencies = [
"varcon-core", "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]] [[package]]
name = "unicase" name = "unicase"
version = "2.6.0" version = "2.6.0"

View file

@ -92,6 +92,7 @@ kstring = { version = "2.0.0", features = ["serde"] }
typed-arena = "2.0.1" typed-arena = "2.0.1"
maplit = "1.0" maplit = "1.0"
unicode-width = "0.1.9" unicode-width = "0.1.9"
unic-emoji-char = "0.9.0"
[dev-dependencies] [dev-dependencies]
assert_fs = "1.0" assert_fs = "1.0"

View file

@ -221,8 +221,8 @@ fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Er
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 visible_column = UnicodeWidthStr::width(start.as_ref()); let visible_column = calculate_visible_column_width(start.as_ref());
let visible_len = UnicodeWidthStr::width(msg.typo); let visible_len = calculate_visible_column_width(msg.typo);
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();
@ -247,6 +247,27 @@ fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Er
Ok(()) Ok(())
} }
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 grapheme.chars().any(unic_emoji_char::is_emoji) {
// 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 context_display<'c>(context: &'c Option<Context<'c>>) -> &'c dyn std::fmt::Display { fn context_display<'c>(context: &'c Option<Context<'c>>) -> &'c dyn std::fmt::Display {
context context
.as_ref() .as_ref()

View file

@ -24,11 +24,11 @@ Face with spiral eyes (U+1F635 U+200D U+1F4AB, Recommended Emoji ZWJ Sequence, v
Grapheme clusters: 1, codepoints: 3, UnicodeWidthStr::width() == 4 (Read NOTE: https://github.com/unicode-rs/unicode-width) Grapheme clusters: 1, codepoints: 3, UnicodeWidthStr::width() == 4 (Read NOTE: https://github.com/unicode-rs/unicode-width)
😵‍💫 Apropriate world 😵‍💫 Apropriate world
^^^^^^^^^^ highlight here ^^^^^^^^^^ highlight here
--- ---
Horizontal tab (\t, U+09) Horizontal tab (\t, U+09)
Grapheme clusters: 1, codepoints: 1, UnicodeWidthStr::width() == 0 Grapheme clusters: 1, codepoints: 1, UnicodeWidthStr::width() == 0
Apropriate world Apropriate world
^^^^^^^^^^ highlight here ^^^^^^^^^^ highlight here

View file

@ -20,11 +20,11 @@ error: `Apropriate` should be `Appropriate`
--> -:26:3 --> -:26:3
| |
26 | 😵‍💫 Apropriate world 26 | 😵‍💫 Apropriate world
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
error: `Apropriate` should be `Appropriate` error: `Apropriate` should be `Appropriate`
--> -:33:2 --> -:33:2
| |
33 | Apropriate world 33 | Apropriate world
| ^^^^^^^^^^ | ^^^^^^^^^^
| |