Skip to content

Commit cea2628

Browse files
authored
perf: avoid unnecessary memory allocation in ya.truncate() (#2753)
1 parent 55f69fb commit cea2628

File tree

4 files changed

+47
-25
lines changed

4 files changed

+47
-25
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ansi-to-tui = "7.0.0"
2424
anyhow = "1.0.98"
2525
base64 = "0.22.1"
2626
bitflags = "2.9.0"
27-
clap = { version = "4.5.37", features = [ "derive" ] }
27+
clap = { version = "4.5.38", features = [ "derive" ] }
2828
core-foundation-sys = "0.8.7"
2929
crossterm = { version = "0.29.0", features = [ "event-stream" ] }
3030
dirs = "6.0.0"
@@ -50,5 +50,5 @@ tokio-util = "0.7.15"
5050
toml = { version = "0.8.22" }
5151
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
5252
twox-hash = { version = "2.1.0", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
53-
unicode-width = "0.2.0"
53+
unicode-width = { version = "0.2.0", default-features = false }
5454
uzers = "0.12.1"

yazi-fs/src/cha/cha.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl Cha {
167167

168168
#[inline]
169169
pub const fn is_hidden(&self) -> bool {
170-
self.kind.contains(ChaKind::HIDDEN) || win_either!(self.kind.contains(ChaKind::SYSTEM), false)
170+
win_either!(self.kind.contains(ChaKind::SYSTEM), self.kind.contains(ChaKind::HIDDEN))
171171
}
172172

173173
#[inline]

yazi-plugin/src/utils/text.rs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::ops::ControlFlow;
21
use mlua::{Function, Lua, Table};
32
use twox_hash::XxHash3_128;
43
use unicode_width::UnicodeWidthChar;
@@ -26,32 +25,55 @@ impl Utils {
2625
}
2726

2827
pub(super) fn truncate(lua: &Lua) -> mlua::Result<Function> {
29-
fn truncate_impl(mut chars: impl Iterator<Item = char>, max: usize) -> Vec<char> {
28+
fn idx_and_width(it: impl Iterator<Item = (usize, char)>, max: usize) -> (usize, usize) {
3029
let mut width = 0;
31-
let flow = chars.try_fold(Vec::with_capacity(max), |mut v, c| {
30+
let idx = it
31+
.take_while(|(_, c)| {
3232
width += c.width().unwrap_or(0);
33-
if width < max {
34-
v.push(c);
35-
ControlFlow::Continue(v)
36-
} else {
37-
ControlFlow::Break(v)
33+
width <= max
34+
})
35+
.map(|(i, _)| i)
36+
.last()
37+
.unwrap();
38+
(idx, width)
3839
}
39-
});
4040

41-
match flow {
42-
ControlFlow::Break(v) => v,
43-
ControlFlow::Continue(v) => v,
41+
lua.create_function(|lua, (s, t): (mlua::String, Table)| {
42+
let b = s.as_bytes();
43+
if b.is_empty() {
44+
return Ok(s);
4445
}
46+
47+
let max = t.raw_get("max")?;
48+
if b.len() <= max {
49+
return Ok(s);
50+
} else if max < 1 {
51+
return lua.create_string("");
4552
}
4653

47-
lua.create_function(|_, (text, t): (mlua::String, Table)| {
48-
let (max, text) = (t.raw_get("max")?, text.to_string_lossy());
54+
let lossy = String::from_utf8_lossy(&b);
55+
let rtl = t.raw_get("rtl").unwrap_or(false);
56+
let (idx, width) = if rtl {
57+
idx_and_width(lossy.char_indices().rev(), max)
58+
} else {
59+
idx_and_width(lossy.char_indices(), max)
60+
};
61+
62+
if width <= max {
63+
return Ok(s);
64+
} else if rtl && idx == 0 {
65+
return Ok(s);
66+
} else if !rtl && lossy[idx..].chars().nth(1).is_none() {
67+
return Ok(s);
68+
}
4969

50-
Ok(if t.raw_get("rtl").unwrap_or(false) {
51-
truncate_impl(text.chars().rev(), max).into_iter().rev().collect()
70+
let result: Vec<_> = if rtl {
71+
let i = lossy[idx..].char_indices().nth(1).map(|(i, _)| idx + i).unwrap_or(lossy.len());
72+
"…".bytes().chain(lossy[i..].bytes()).collect()
5273
} else {
53-
truncate_impl(text.chars(), max).into_iter().collect::<String>()
54-
})
74+
lossy[..idx].bytes().chain("…".bytes()).collect()
75+
};
76+
lua.create_string(result)
5577
})
5678
}
5779

0 commit comments

Comments
 (0)