term: Fix unicode display width hack
We were skipping certain glyphs due to the width calculation being wrong. This fixes it, and we're able to display emojis correctly inside tables now.
This commit is contained in:
parent
06946a2bf4
commit
40303cd8e1
|
|
@ -2574,8 +2574,8 @@ dependencies = [
|
|||
"pretty_assertions",
|
||||
"tempfile",
|
||||
"termion 2.0.1",
|
||||
"unicode-display-width",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
|
|
@ -3619,6 +3619,15 @@ version = "0.3.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-display-width"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a43273b656140aa2bb8e65351fe87c255f0eca706b2538a9bd4a590a3490bf3"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ inquire = { version = "0.6.2", default-features = false, features = ["termion",
|
|||
libc = { version = "0.2" }
|
||||
once_cell = { version = "1.13" }
|
||||
termion = { version = "2" }
|
||||
unicode-width = { version = "0.1.10", default-features = false }
|
||||
unicode-display-width = { version = "0.3.0" }
|
||||
unicode-segmentation = { version = "1.7.1" }
|
||||
zeroize = { version = "1.1" }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ use std::sync::atomic::AtomicBool;
|
|||
use std::{fmt, io};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use super::color::Color;
|
||||
use super::style::{Property, Style};
|
||||
|
|
@ -232,16 +231,6 @@ impl<T> Paint<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: UnicodeWidthStr> UnicodeWidthStr for Paint<T> {
|
||||
fn width(&self) -> usize {
|
||||
self.item.width()
|
||||
}
|
||||
|
||||
fn width_cjk(&self) -> usize {
|
||||
self.item.width_cjk()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display> fmt::Display for Paint<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if Paint::is_enabled() && self.style.wrap {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::fmt;
|
|||
|
||||
use super::{Color, Filled, Line, Paint};
|
||||
|
||||
use unicode_display_width as unicode;
|
||||
use unicode_segmentation::UnicodeSegmentation as _;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
/// Text that can be displayed on the terminal, measured, truncated and padded.
|
||||
pub trait Cell: fmt::Display {
|
||||
|
|
@ -123,7 +123,9 @@ impl Cell for str {
|
|||
type Padded = String;
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.graphemes(true).map(UnicodeWidthStr::width).sum()
|
||||
self.graphemes(true)
|
||||
.map(|g| unicode::width(g) as usize)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn truncate(&self, width: usize, delim: &str) -> String {
|
||||
|
|
@ -204,3 +206,12 @@ impl<T: Cell + fmt::Display> Cell for Filled<T> {
|
|||
T::pad(&self.item, width)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_width() {
|
||||
assert_eq!(unicode_display_width::width("❤️"), 2);
|
||||
assert_eq!(unicode_display_width::width("🪵"), 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,9 +362,12 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_width() {
|
||||
let line = Line::new("Radicle Heartwood Protocol & Stack ❤️ 🪵");
|
||||
// Nb. This might not display correctly in some editors or terminals.
|
||||
let line = Line::new("Radicle Heartwood Protocol & Stack ❤️🪵");
|
||||
assert_eq!(line.width(), 39, "{line}");
|
||||
let line = Line::new("❤\u{fe0f}");
|
||||
assert_eq!(line.width(), 1, "{line}");
|
||||
assert_eq!(line.width(), 2, "{line}");
|
||||
let line = Line::new("❤️");
|
||||
assert_eq!(line.width(), 2, "{line}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,5 @@ pub fn label(s: impl Into<Paint<String>>) -> Label {
|
|||
|
||||
/// Cleanup the input string for display as a label.
|
||||
fn cleanup(input: &str) -> String {
|
||||
input
|
||||
.chars()
|
||||
.filter(|c| *c != '\u{fe0f}' && *c != '\n' && *c != '\r')
|
||||
.collect()
|
||||
input.chars().filter(|c| *c != '\n' && *c != '\r').collect()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue