From 994141f85269709617bb187a1bb6b64592baa6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Thu, 8 Apr 2021 12:59:44 +0200 Subject: [PATCH] fix unicode issue (#71) --- CHANGELOG.md | 5 +++++ Cargo.lock | 1 + Cargo.toml | 1 + src/table.rs | 24 +++++++++++------------- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b2cf87..3381aa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Unicode chars breaks the view [#71] + ### Added - Telescope support [#61] @@ -118,3 +122,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#40]: https://github.com/soywod/himalaya/issues/40 [#41]: https://github.com/soywod/himalaya/issues/41 [#61]: https://github.com/soywod/himalaya/issues/61 +[#71]: https://github.com/soywod/himalaya/issues/71 diff --git a/Cargo.lock b/Cargo.lock index 2b3eca6..de42dd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,6 +318,7 @@ dependencies = [ "terminal_size", "toml", "tree_magic", + "unicode-width", "uuid", ] diff --git a/Cargo.toml b/Cargo.toml index 6617335..42e0c78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,5 @@ serde_json = "1.0.61" terminal_size = "0.1.15" toml = "0.5.8" tree_magic = "0.2.3" +unicode-width = "0.1.7" uuid = { version = "0.8", features = ["v4"] } diff --git a/src/table.rs b/src/table.rs index 6eb28a0..4f8a911 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1,5 +1,6 @@ use std::fmt; use terminal_size::terminal_size; +use unicode_width::UnicodeWidthStr; #[derive(Clone, Debug)] pub struct Style(u8, u8, u8); @@ -46,8 +47,8 @@ impl Cell { } } - pub fn printable_value_len(&self) -> usize { - self.value.chars().collect::>().len() + pub fn unicode_width(&self) -> usize { + UnicodeWidthStr::width(self.value.as_str()) } pub fn render(&self, col_size: usize) -> String { @@ -58,18 +59,15 @@ impl Cell { .collect::>() .concat(); let style_end = "\x1b[0m"; + let unicode_width = self.unicode_width(); - if col_size > 0 && self.printable_value_len() > col_size { - let value: String = self.value.chars().collect::>()[0..=col_size - 2] - .into_iter() - .collect(); - - String::from(style_begin + &value + "… " + style_end) + if col_size > 0 && unicode_width > col_size { + String::from(style_begin + &self.value[0..=col_size - 2] + "… " + style_end) } else { let padding = if col_size == 0 { "".to_string() } else { - " ".repeat(col_size - self.printable_value_len() + 1) + " ".repeat(col_size - unicode_width + 1) }; String::from(style_begin + &self.value + &padding + style_end) @@ -102,7 +100,7 @@ pub trait DisplayTable<'a, T: DisplayRow + 'a> { let head = Self::header_row(); head.iter().for_each(|cell| { - col_sizes.push(cell.printable_value_len()); + col_sizes.push(cell.unicode_width()); }); let mut table = self @@ -110,9 +108,9 @@ pub trait DisplayTable<'a, T: DisplayRow + 'a> { .iter() .map(|item| { let row = item.to_row(); - row.iter().enumerate().for_each(|(i, cell)| { - col_sizes[i] = col_sizes[i].max(cell.printable_value_len()) - }); + row.iter() + .enumerate() + .for_each(|(i, cell)| col_sizes[i] = col_sizes[i].max(cell.unicode_width())); row }) .collect::>();