mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
perf: avoid unnecessary memory allocation in ya.truncate() (#2753)
This commit is contained in:
parent
55f69fbfee
commit
cea2628a19
4 changed files with 48 additions and 26 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -385,9 +385,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.37"
|
||||
version = "4.5.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
|
||||
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -395,9 +395,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.37"
|
||||
version = "4.5.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
|
||||
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ ansi-to-tui = "7.0.0"
|
|||
anyhow = "1.0.98"
|
||||
base64 = "0.22.1"
|
||||
bitflags = "2.9.0"
|
||||
clap = { version = "4.5.37", features = [ "derive" ] }
|
||||
clap = { version = "4.5.38", features = [ "derive" ] }
|
||||
core-foundation-sys = "0.8.7"
|
||||
crossterm = { version = "0.29.0", features = [ "event-stream" ] }
|
||||
dirs = "6.0.0"
|
||||
|
|
@ -50,5 +50,5 @@ tokio-util = "0.7.15"
|
|||
toml = { version = "0.8.22" }
|
||||
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
|
||||
twox-hash = { version = "2.1.0", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
|
||||
unicode-width = "0.2.0"
|
||||
unicode-width = { version = "0.2.0", default-features = false }
|
||||
uzers = "0.12.1"
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ impl Cha {
|
|||
|
||||
#[inline]
|
||||
pub const fn is_hidden(&self) -> bool {
|
||||
self.kind.contains(ChaKind::HIDDEN) || win_either!(self.kind.contains(ChaKind::SYSTEM), false)
|
||||
win_either!(self.kind.contains(ChaKind::SYSTEM), self.kind.contains(ChaKind::HIDDEN))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use std::ops::ControlFlow;
|
||||
use mlua::{Function, Lua, Table};
|
||||
use twox_hash::XxHash3_128;
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
|
@ -26,32 +25,55 @@ impl Utils {
|
|||
}
|
||||
|
||||
pub(super) fn truncate(lua: &Lua) -> mlua::Result<Function> {
|
||||
fn truncate_impl(mut chars: impl Iterator<Item = char>, max: usize) -> Vec<char> {
|
||||
fn idx_and_width(it: impl Iterator<Item = (usize, char)>, max: usize) -> (usize, usize) {
|
||||
let mut width = 0;
|
||||
let flow = chars.try_fold(Vec::with_capacity(max), |mut v, c| {
|
||||
let idx = it
|
||||
.take_while(|(_, c)| {
|
||||
width += c.width().unwrap_or(0);
|
||||
if width < max {
|
||||
v.push(c);
|
||||
ControlFlow::Continue(v)
|
||||
} else {
|
||||
ControlFlow::Break(v)
|
||||
width <= max
|
||||
})
|
||||
.map(|(i, _)| i)
|
||||
.last()
|
||||
.unwrap();
|
||||
(idx, width)
|
||||
}
|
||||
});
|
||||
|
||||
match flow {
|
||||
ControlFlow::Break(v) => v,
|
||||
ControlFlow::Continue(v) => v,
|
||||
}
|
||||
lua.create_function(|lua, (s, t): (mlua::String, Table)| {
|
||||
let b = s.as_bytes();
|
||||
if b.is_empty() {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
lua.create_function(|_, (text, t): (mlua::String, Table)| {
|
||||
let (max, text) = (t.raw_get("max")?, text.to_string_lossy());
|
||||
let max = t.raw_get("max")?;
|
||||
if b.len() <= max {
|
||||
return Ok(s);
|
||||
} else if max < 1 {
|
||||
return lua.create_string("");
|
||||
}
|
||||
|
||||
Ok(if t.raw_get("rtl").unwrap_or(false) {
|
||||
truncate_impl(text.chars().rev(), max).into_iter().rev().collect()
|
||||
let lossy = String::from_utf8_lossy(&b);
|
||||
let rtl = t.raw_get("rtl").unwrap_or(false);
|
||||
let (idx, width) = if rtl {
|
||||
idx_and_width(lossy.char_indices().rev(), max)
|
||||
} else {
|
||||
truncate_impl(text.chars(), max).into_iter().collect::<String>()
|
||||
})
|
||||
idx_and_width(lossy.char_indices(), max)
|
||||
};
|
||||
|
||||
if width <= max {
|
||||
return Ok(s);
|
||||
} else if rtl && idx == 0 {
|
||||
return Ok(s);
|
||||
} else if !rtl && lossy[idx..].chars().nth(1).is_none() {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
let result: Vec<_> = if rtl {
|
||||
let i = lossy[idx..].char_indices().nth(1).map(|(i, _)| idx + i).unwrap_or(lossy.len());
|
||||
"…".bytes().chain(lossy[i..].bytes()).collect()
|
||||
} else {
|
||||
lossy[..idx].bytes().chain("…".bytes()).collect()
|
||||
};
|
||||
lua.create_string(result)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue