Skip to content

Commit

Permalink
Grapheme handling when truncating long filenames
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Thiel committed Jun 7, 2019
1 parent 28d84fc commit 0994466
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ open = "1.2.2"
log = "0.4.6"
tui-react = { path = "./tui-react", version = "0.1" }
num_cpus = "1.10.0"
unicode-segmentation = "1.3.0"

[[bin]]
name="dua"
Expand Down
61 changes: 61 additions & 0 deletions src/interactive/app/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use dua::path_of;
use dua::traverse::{EntryData, Tree, TreeIndex};
use itertools::Itertools;
use petgraph::Direction;
use unicode_segmentation::UnicodeSegmentation;

#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq)]
pub enum SortMode {
Expand Down Expand Up @@ -52,3 +53,63 @@ pub fn sorted_entries(tree: &Tree, node_idx: TreeIndex, sorting: SortMode) -> Ve
})
.collect()
}

pub fn fit_string_graphemes_with_ellipsis(
s: impl Into<String>,
path_graphemes_count: usize,
mut desired_graphemes: usize,
) -> (String, usize) {
const ELLIPSIS: usize = 1;
const MIN_GRAPHEMES_ON_SIDE: usize = 1;
const MIN_LEN: usize = ELLIPSIS + MIN_GRAPHEMES_ON_SIDE;
const USE_EXTENDED: bool = true;

let s = s.into();
desired_graphemes = desired_graphemes.max(MIN_LEN);

debug_assert!(
path_graphemes_count == s.graphemes(USE_EXTENDED).count(),
"input grapheme count is actually correct"
);

let gc = path_graphemes_count;
if gc <= desired_graphemes {
return (s, gc);
}

let mut n = String::with_capacity(desired_graphemes);
let to_be_removed = gc - desired_graphemes + ELLIPSIS;
let gmi = s.graphemes(USE_EXTENDED);

n.push('…');
n.extend(gmi.skip(to_be_removed));
(n, desired_graphemes)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn fit_string_inputs() {
assert_eq!(
("aaa".into(), 3),
fit_string_graphemes_with_ellipsis("aaa", 3, 4)
);
assert_eq!(
("…a".to_string(), 2),
fit_string_graphemes_with_ellipsis("abbbba", 6, 1),
"even amount of chars, desired too small"
);
assert_eq!(
("…ca".to_string(), 3),
fit_string_graphemes_with_ellipsis("abbbbca", 7, 3),
"uneven amount of chars, desired too small"
);
assert_eq!(
("… a".to_string(), 3),
fit_string_graphemes_with_ellipsis("a a", 6, 3),
"spaces are counted as graphemes, too"
);
}
}
34 changes: 26 additions & 8 deletions src/interactive/widgets/mark.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
use crate::interactive::{widgets::COLOR_MARKED_LIGHT, CursorDirection};
use dua::traverse::{Tree, TreeIndex};
use dua::{path_of, ByteFormat};
use crate::interactive::{
fit_string_graphemes_with_ellipsis, widgets::COLOR_MARKED_LIGHT, CursorDirection,
};
use dua::{
path_of,
traverse::{Tree, TreeIndex},
ByteFormat,
};
use itertools::Itertools;
use std::collections::btree_map::Entry;
use std::{borrow::Borrow, collections::BTreeMap, path::PathBuf};
use std::{borrow::Borrow, collections::btree_map::Entry, collections::BTreeMap, path::PathBuf};
use termion::{event::Key, event::Key::*};
use tui::style::Color;
use tui::{
buffer::Buffer,
layout::Rect,
style::Color,
style::{Modifier, Style},
widgets::Block,
widgets::Borders,
widgets::Text,
};
use tui_react::{List, ListProps};
use unicode_segmentation::UnicodeSegmentation;

pub type EntryMarkMap = BTreeMap<TreeIndex, EntryMark>;
pub struct EntryMark {
Expand Down Expand Up @@ -127,8 +132,21 @@ impl MarkPane {
Some(selected) if idx == selected => Modifier::BOLD,
_ => Modifier::empty(),
};
let path = format!(" {}", v.path.display());
let path_len = path.len();
let (path, path_len) = {
let path = format!(" {} ", v.path.display());
let num_path_graphemes = path.graphemes(true).count();
match num_path_graphemes + format.total_width() {
n if n > area.width as usize => {
let desired_size = num_path_graphemes - (n - area.width as usize);
fit_string_graphemes_with_ellipsis(
path,
num_path_graphemes,
desired_size,
)
}
_ => (path, num_path_graphemes),
}
};
let path = Text::Styled(
path.into(),
Style {
Expand Down

0 comments on commit 0994466

Please sign in to comment.