From f248187fc70b61c3d4e9eb3ab802f0ef23d4e46e Mon Sep 17 00:00:00 2001 From: sxyazi Date: Wed, 14 May 2025 01:40:59 +0800 Subject: [PATCH] feat: truncate long items in the file list --- yazi-plugin/preset/components/current.lua | 11 ++++----- yazi-plugin/preset/components/parent.lua | 6 ++--- yazi-plugin/preset/plugins/folder.lua | 6 ++--- yazi-plugin/src/elements/line.rs | 27 ++++++++++++++++++++++- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/yazi-plugin/preset/components/current.lua b/yazi-plugin/preset/components/current.lua index 33586037..dfa04be2 100644 --- a/yazi-plugin/preset/components/current.lua +++ b/yazi-plugin/preset/components/current.lua @@ -32,15 +32,16 @@ function Current:redraw() return self:empty() end - local entities, linemodes = {}, {} + local left, right = {}, {} for _, f in ipairs(files) do - entities[#entities + 1] = Entity:new(f):redraw() - linemodes[#linemodes + 1] = Linemode:new(f):redraw() + left[#left + 1] = Entity:new(f):redraw() + right[#right + 1] = Linemode:new(f):redraw() + left[#left]:truncate { max = math.max(0, self._area.w - right[#right]:width()) } end return { - ui.List(entities):area(self._area), - ui.Text(linemodes):area(self._area):align(ui.Text.RIGHT), + ui.List(left):area(self._area), + ui.Text(right):area(self._area):align(ui.Text.RIGHT), } end diff --git a/yazi-plugin/preset/components/parent.lua b/yazi-plugin/preset/components/parent.lua index 6b04313b..a01f48f4 100644 --- a/yazi-plugin/preset/components/parent.lua +++ b/yazi-plugin/preset/components/parent.lua @@ -17,13 +17,13 @@ function Parent:redraw() return {} end - local entities = {} + local items = {} for _, f in ipairs(self._folder.window) do - entities[#entities + 1] = Entity:new(f):redraw() + items[#items + 1] = Entity:new(f):redraw():truncate { max = self._area.w } end return { - ui.List(entities):area(self._area), + ui.List(items):area(self._area), } end diff --git a/yazi-plugin/preset/plugins/folder.lua b/yazi-plugin/preset/plugins/folder.lua index a8f06e70..547a6024 100644 --- a/yazi-plugin/preset/plugins/folder.lua +++ b/yazi-plugin/preset/plugins/folder.lua @@ -19,13 +19,13 @@ function M:peek(job) return ya.preview_widget(job, ui.Line(s):area(job.area):align(ui.Line.CENTER)) end - local entities = {} + local items = {} for _, f in ipairs(folder.window) do - entities[#entities + 1] = Entity:new(f):redraw() + items[#items + 1] = Entity:new(f):redraw():truncate { max = job.area.w } end ya.preview_widget(job, { - ui.List(entities):area(job.area), + ui.List(items):area(job.area), table.unpack(Marker:new(job.area, folder):redraw()), }) end diff --git a/yazi-plugin/src/elements/line.rs b/yazi-plugin/src/elements/line.rs index 7e7e3601..b2fc9392 100644 --- a/yazi-plugin/src/elements/line.rs +++ b/yazi-plugin/src/elements/line.rs @@ -1,4 +1,4 @@ -use std::mem; +use std::{borrow::Cow, mem}; use ansi_to_tui::IntoText; use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; @@ -131,5 +131,30 @@ impl UserData for Line { methods.add_method("visible", |_, me, ()| { Ok(me.inner.iter().flat_map(|s| s.content.chars()).any(|c| c.width().unwrap_or(0) > 0)) }); + methods.add_function_mut("truncate", |_, (ud, t): (AnyUserData, Table)| { + let mut me = ud.borrow_mut::()?; + let max = t.raw_get("max")?; + + let mut width = 0; + 'outer: for (x, span) in me.inner.iter_mut().enumerate() { + for (y, c) in span.content.char_indices() { + width += c.width().unwrap_or(0); + if width < max { + continue; + } else if width == max && span.content[y..].chars().nth(1).is_none() { + continue; + } + + match &mut span.content { + Cow::Borrowed(s) => span.content = Cow::Borrowed(&s[..y]), + Cow::Owned(s) => s.truncate(y), + } + me.inner.spans.truncate(x + 1); + me.inner.spans.push(ratatui::text::Span::raw("…")); + break 'outer; + } + } + Ok(ud) + }); } }