diff --git a/Cargo.lock b/Cargo.lock index eb3d28b..9ad5c0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -809,6 +809,7 @@ dependencies = [ "serde_json", "tempfile", "toml", + "unicode-width 0.2.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d382369..5678652 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ name = "disky" path = "src/main.rs" [dependencies] +unicode-width = "0.2" jwalk = "0.8" duckdb = { version = "1.1", features = ["bundled"] } clap = { version = "4", features = ["derive"] } diff --git a/src/tui/ui.rs b/src/tui/ui.rs index a4a74b4..13c9e27 100644 --- a/src/tui/ui.rs +++ b/src/tui/ui.rs @@ -7,6 +7,7 @@ use ratatui::{ widgets::{Block, Borders, List, ListItem, ListState, Paragraph}, Frame, }; +use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; pub fn render(frame: &mut Frame, app: &App, list_state: &mut ListState) { let area = frame.area(); @@ -163,9 +164,14 @@ fn size_bar(size: i64, max: i64, width: usize) -> String { } fn truncate(s: &str, max: usize) -> String { - if s.len() <= max { - s.to_string() - } else { - format!("{}…", &s[..max.saturating_sub(1)]) + let max = max.saturating_sub(1); // reserve 1 column for '…' + let mut width = 0; + for (byte_i, ch) in s.char_indices() { + let ch_w = ch.width().unwrap_or(0); + if width + ch_w > max { + return format!("{}…", &s[..byte_i]); + } + width += ch_w; } + s.to_string() }