mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: truncate path for deeply nested directories (#787)
This commit is contained in:
parent
d96af54574
commit
3f80bc56a6
2 changed files with 45 additions and 29 deletions
|
|
@ -2,16 +2,12 @@ Header = {
|
|||
area = ui.Rect.default,
|
||||
}
|
||||
|
||||
function Header:cwd()
|
||||
function Header:cwd(max)
|
||||
local cwd = cx.active.current.cwd
|
||||
local readable = ya.readable_path(tostring(cwd))
|
||||
|
||||
local span
|
||||
if not cwd.is_search then
|
||||
span = ui.Span(ya.readable_path(tostring(cwd)))
|
||||
else
|
||||
span = ui.Span(string.format("%s (search: %s)", ya.readable_path(tostring(cwd)), cwd:frag()))
|
||||
end
|
||||
return span:style(THEME.manager.cwd)
|
||||
local text = cwd.is_search and string.format("%s (search: %s)", readable, cwd:frag()) or readable
|
||||
return ui.Span(ya.truncate(text, { max = max, rtl = true })):style(THEME.manager.cwd)
|
||||
end
|
||||
|
||||
function Header:count()
|
||||
|
|
@ -49,7 +45,7 @@ function Header:tabs()
|
|||
for i = 1, tabs do
|
||||
local text = i
|
||||
if THEME.manager.tab_width > 2 then
|
||||
text = ya.truncate(text .. " " .. cx.tabs[i]:name(), THEME.manager.tab_width)
|
||||
text = ya.truncate(text .. " " .. cx.tabs[i]:name(), { max = THEME.manager.tab_width })
|
||||
end
|
||||
if i == cx.tabs.idx then
|
||||
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(THEME.manager.tab_active)
|
||||
|
|
@ -60,7 +56,18 @@ function Header:tabs()
|
|||
return ui.Line(spans)
|
||||
end
|
||||
|
||||
-- TODO: remove this function after v0.2.5 release
|
||||
function Header:layout(area)
|
||||
if not ya.deprecated_header_layout then
|
||||
ya.deprecated_header_layout = true
|
||||
ya.notify {
|
||||
title = "Deprecated API",
|
||||
content = "`Header:layout()` is deprecated, please apply the latest `Header:render()` in your `init.lua`",
|
||||
timeout = 5,
|
||||
level = "warn",
|
||||
}
|
||||
end
|
||||
|
||||
self.area = area
|
||||
|
||||
return ui.Layout()
|
||||
|
|
@ -70,12 +77,12 @@ function Header:layout(area)
|
|||
end
|
||||
|
||||
function Header:render(area)
|
||||
local chunks = self:layout(area)
|
||||
self.area = area
|
||||
|
||||
local left = ui.Line { self:cwd() }
|
||||
local right = ui.Line { self:count(), self:tabs() }
|
||||
local left = ui.Line { self:cwd(math.max(0, area.w - right:width())) }
|
||||
return {
|
||||
ui.Paragraph(chunks[1], { left }),
|
||||
ui.Paragraph(chunks[2], { right }):align(ui.Paragraph.RIGHT),
|
||||
ui.Paragraph(area, { left }),
|
||||
ui.Paragraph(area, { right }):align(ui.Paragraph.RIGHT),
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use mlua::{Lua, Table};
|
||||
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
use super::Utils;
|
||||
|
||||
|
|
@ -20,26 +20,35 @@ impl Utils {
|
|||
|
||||
ya.raw_set(
|
||||
"truncate",
|
||||
lua.create_function(|_, (text, max): (mlua::String, usize)| {
|
||||
let mut width = 0;
|
||||
let flow =
|
||||
text.to_string_lossy().chars().try_fold(String::with_capacity(max), |mut s, c| {
|
||||
width += c.width().unwrap_or(0);
|
||||
if s.width() < max {
|
||||
s.push(c);
|
||||
ControlFlow::Continue(s)
|
||||
} else {
|
||||
ControlFlow::Break(s)
|
||||
}
|
||||
});
|
||||
lua.create_function(|_, (text, t): (mlua::String, Table)| {
|
||||
let (max, text) = (t.raw_get("max")?, text.to_string_lossy());
|
||||
|
||||
Ok(match flow {
|
||||
ControlFlow::Break(s) => s,
|
||||
ControlFlow::Continue(s) => s,
|
||||
Ok(if t.raw_get("rtl").unwrap_or(false) {
|
||||
Self::truncate(text.chars().rev(), max).into_iter().rev().collect()
|
||||
} else {
|
||||
Self::truncate(text.chars(), max).into_iter().collect::<String>()
|
||||
})
|
||||
})?,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn truncate(mut chars: impl Iterator<Item = char>, max: usize) -> Vec<char> {
|
||||
let mut width = 0;
|
||||
let flow = chars.try_fold(Vec::with_capacity(max), |mut v, c| {
|
||||
width += c.width().unwrap_or(0);
|
||||
if width < max {
|
||||
v.push(c);
|
||||
ControlFlow::Continue(v)
|
||||
} else {
|
||||
ControlFlow::Break(v)
|
||||
}
|
||||
});
|
||||
|
||||
match flow {
|
||||
ControlFlow::Break(v) => v,
|
||||
ControlFlow::Continue(v) => v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue