mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: icon rules mixing (#2755)
This commit is contained in:
parent
5a4e6e4068
commit
9a0ef6bb20
2 changed files with 103 additions and 24 deletions
|
|
@ -101,13 +101,13 @@ impl Icon {
|
||||||
self.prepend_globs.0.into_iter().chain(self.globs.0).chain(self.append_globs.0).collect(),
|
self.prepend_globs.0.into_iter().chain(self.globs.0).chain(self.append_globs.0).collect(),
|
||||||
),
|
),
|
||||||
dirs: StrIcons(
|
dirs: StrIcons(
|
||||||
self.prepend_dirs.0.into_iter().chain(self.dirs.0).chain(self.append_dirs.0).collect(),
|
self.append_dirs.0.into_iter().chain(self.dirs.0).chain(self.prepend_dirs.0).collect(),
|
||||||
),
|
),
|
||||||
files: StrIcons(
|
files: StrIcons(
|
||||||
self.prepend_files.0.into_iter().chain(self.files.0).chain(self.append_files.0).collect(),
|
self.append_files.0.into_iter().chain(self.files.0).chain(self.prepend_files.0).collect(),
|
||||||
),
|
),
|
||||||
exts: StrIcons(
|
exts: StrIcons(
|
||||||
self.prepend_exts.0.into_iter().chain(self.exts.0).chain(self.append_exts.0).collect(),
|
self.append_exts.0.into_iter().chain(self.exts.0).chain(self.prepend_exts.0).collect(),
|
||||||
),
|
),
|
||||||
conds: CondIcons(
|
conds: CondIcons(
|
||||||
self.prepend_conds.0.into_iter().chain(self.conds.0).chain(self.append_conds.0).collect(),
|
self.prepend_conds.0.into_iter().chain(self.conds.0).chain(self.append_conds.0).collect(),
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,20 @@ impl Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn truncate(lua: &Lua) -> mlua::Result<Function> {
|
pub(super) fn truncate(lua: &Lua) -> mlua::Result<Function> {
|
||||||
fn idx_and_width(it: impl Iterator<Item = (usize, char)>, max: usize) -> (usize, usize) {
|
fn traverse(
|
||||||
let mut width = 0;
|
it: impl Iterator<Item = (usize, char)>,
|
||||||
|
max: usize,
|
||||||
|
) -> (Option<usize>, usize, bool) {
|
||||||
|
let (mut adv, mut last) = (0, 0);
|
||||||
let idx = it
|
let idx = it
|
||||||
.take_while(|(_, c)| {
|
.take_while(|&(_, c)| {
|
||||||
width += c.width().unwrap_or(0);
|
last = adv;
|
||||||
width <= max
|
adv += c.width().unwrap_or(0);
|
||||||
|
adv <= max
|
||||||
})
|
})
|
||||||
.map(|(i, _)| i)
|
.map(|(i, _)| i)
|
||||||
.last()
|
.last();
|
||||||
.unwrap();
|
(idx, last, adv > max)
|
||||||
(idx, width)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lua.create_function(|lua, (s, t): (mlua::String, Table)| {
|
lua.create_function(|lua, (s, t): (mlua::String, Table)| {
|
||||||
|
|
@ -53,25 +56,28 @@ impl Utils {
|
||||||
|
|
||||||
let lossy = String::from_utf8_lossy(&b);
|
let lossy = String::from_utf8_lossy(&b);
|
||||||
let rtl = t.raw_get("rtl").unwrap_or(false);
|
let rtl = t.raw_get("rtl").unwrap_or(false);
|
||||||
let (idx, width) = if rtl {
|
let (idx, width, remain) = if rtl {
|
||||||
idx_and_width(lossy.char_indices().rev(), max)
|
traverse(lossy.char_indices().rev(), max)
|
||||||
} else {
|
} else {
|
||||||
idx_and_width(lossy.char_indices(), max)
|
traverse(lossy.char_indices(), max)
|
||||||
};
|
};
|
||||||
|
|
||||||
if width <= max {
|
let Some(idx) = idx else { return lua.create_string("…") };
|
||||||
return Ok(s);
|
if !remain {
|
||||||
} else if rtl && idx == 0 {
|
|
||||||
return Ok(s);
|
|
||||||
} else if !rtl && lossy[idx..].chars().nth(1).is_none() {
|
|
||||||
return Ok(s);
|
return Ok(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result: Vec<_> = if rtl {
|
let result: Vec<_> = match (rtl, width == max) {
|
||||||
let i = lossy[idx..].char_indices().nth(1).map(|(i, _)| idx + i).unwrap_or(lossy.len());
|
(false, false) => {
|
||||||
"…".bytes().chain(lossy[i..].bytes()).collect()
|
let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8());
|
||||||
} else {
|
lossy[..idx + len].bytes().chain("…".bytes()).collect()
|
||||||
lossy[..idx].bytes().chain("…".bytes()).collect()
|
}
|
||||||
|
(false, true) => lossy[..idx].bytes().chain("…".bytes()).collect(),
|
||||||
|
(true, false) => "…".bytes().chain(lossy[idx..].bytes()).collect(),
|
||||||
|
(true, true) => {
|
||||||
|
let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8());
|
||||||
|
"…".bytes().chain(lossy[idx + len..].bytes()).collect()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
lua.create_string(result)
|
lua.create_string(result)
|
||||||
})
|
})
|
||||||
|
|
@ -88,3 +94,76 @@ impl Utils {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use mlua::Value;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn truncate(s: &str, max: usize, rtl: bool) -> String {
|
||||||
|
let lua = Lua::new();
|
||||||
|
let t = lua
|
||||||
|
.create_table_from([("max", Value::Integer(max as i64)), ("rtl", Value::Boolean(rtl))])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Utils::truncate(&lua).unwrap().call((s, t)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_truncate() {
|
||||||
|
assert_eq!(truncate("你好,world", 0, false), "");
|
||||||
|
assert_eq!(truncate("你好,world", 1, false), "…");
|
||||||
|
assert_eq!(truncate("你好,world", 2, false), "…");
|
||||||
|
|
||||||
|
assert_eq!(truncate("你好,世界", 3, false), "你…");
|
||||||
|
assert_eq!(truncate("你好,世界", 4, false), "你…");
|
||||||
|
assert_eq!(truncate("你好,世界", 5, false), "你好…");
|
||||||
|
|
||||||
|
assert_eq!(truncate("Hello, world", 5, false), "Hell…");
|
||||||
|
assert_eq!(truncate("Ni好,世界", 3, false), "Ni…");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_truncate_rtl() {
|
||||||
|
assert_eq!(truncate("world,你好", 0, true), "");
|
||||||
|
assert_eq!(truncate("world,你好", 1, true), "…");
|
||||||
|
assert_eq!(truncate("world,你好", 2, true), "…");
|
||||||
|
|
||||||
|
assert_eq!(truncate("你好,世界", 3, true), "…界");
|
||||||
|
assert_eq!(truncate("你好,世界", 4, true), "…界");
|
||||||
|
assert_eq!(truncate("你好,世界", 5, true), "…世界");
|
||||||
|
|
||||||
|
assert_eq!(truncate("Hello, world", 5, true), "…orld");
|
||||||
|
assert_eq!(truncate("你好,Shi界", 3, true), "…界");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_truncate_oboe() {
|
||||||
|
assert_eq!(truncate("Hello, world", 11, false), "Hello, wor…");
|
||||||
|
assert_eq!(truncate("你好,世界", 9, false), "你好,世…");
|
||||||
|
assert_eq!(truncate("你好,世Jie", 9, false), "你好,世…");
|
||||||
|
|
||||||
|
assert_eq!(truncate("Hello, world", 11, true), "…llo, world");
|
||||||
|
assert_eq!(truncate("你好,世界", 9, true), "…好,世界");
|
||||||
|
assert_eq!(truncate("Ni好,世界", 9, true), "…好,世界");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_truncate_exact() {
|
||||||
|
assert_eq!(truncate("Hello, world", 12, false), "Hello, world");
|
||||||
|
assert_eq!(truncate("你好,世界", 10, false), "你好,世界");
|
||||||
|
|
||||||
|
assert_eq!(truncate("Hello, world", 12, true), "Hello, world");
|
||||||
|
assert_eq!(truncate("你好,世界", 10, true), "你好,世界");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_truncate_overflow() {
|
||||||
|
assert_eq!(truncate("Hello, world", 13, false), "Hello, world");
|
||||||
|
assert_eq!(truncate("你好,世界", 11, false), "你好,世界");
|
||||||
|
|
||||||
|
assert_eq!(truncate("Hello, world", 13, true), "Hello, world");
|
||||||
|
assert_eq!(truncate("你好,世界", 11, true), "你好,世界");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue