mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat!: redesign tabs (#2745)
This commit is contained in:
parent
41cba40072
commit
ea90b0477e
8 changed files with 113 additions and 42 deletions
|
|
@ -38,11 +38,6 @@ marker_cut = { fg = "lightred", bg = "lightred" }
|
||||||
marker_marked = { fg = "lightcyan", bg = "lightcyan" }
|
marker_marked = { fg = "lightcyan", bg = "lightcyan" }
|
||||||
marker_selected = { fg = "lightyellow", bg = "lightyellow" }
|
marker_selected = { fg = "lightyellow", bg = "lightyellow" }
|
||||||
|
|
||||||
# Tab
|
|
||||||
tab_active = { reversed = true }
|
|
||||||
tab_inactive = {}
|
|
||||||
tab_width = 1
|
|
||||||
|
|
||||||
# Count
|
# Count
|
||||||
count_copied = { fg = "white", bg = "green" }
|
count_copied = { fg = "white", bg = "green" }
|
||||||
count_cut = { fg = "white", bg = "red" }
|
count_cut = { fg = "white", bg = "red" }
|
||||||
|
|
@ -58,6 +53,19 @@ syntect_theme = ""
|
||||||
# : }}}
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
|
# : Tabs {{{
|
||||||
|
|
||||||
|
[tabs]
|
||||||
|
active = { bg = "blue", bold = true }
|
||||||
|
inactive = { fg = "blue", bg = "gray" }
|
||||||
|
|
||||||
|
# Separator
|
||||||
|
sep_inner = { open = "", close = "" }
|
||||||
|
sep_outer = { open = "", close = "" }
|
||||||
|
|
||||||
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
# : Mode {{{
|
# : Mode {{{
|
||||||
|
|
||||||
[mode]
|
[mode]
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,6 @@ marker_cut = { fg = "lightred", bg = "lightred" }
|
||||||
marker_marked = { fg = "lightcyan", bg = "lightcyan" }
|
marker_marked = { fg = "lightcyan", bg = "lightcyan" }
|
||||||
marker_selected = { fg = "lightyellow", bg = "lightyellow" }
|
marker_selected = { fg = "lightyellow", bg = "lightyellow" }
|
||||||
|
|
||||||
# Tab
|
|
||||||
tab_active = { reversed = true }
|
|
||||||
tab_inactive = {}
|
|
||||||
tab_width = 1
|
|
||||||
|
|
||||||
# Count
|
# Count
|
||||||
count_copied = { fg = "white", bg = "green" }
|
count_copied = { fg = "white", bg = "green" }
|
||||||
count_cut = { fg = "white", bg = "red" }
|
count_cut = { fg = "white", bg = "red" }
|
||||||
|
|
@ -58,6 +53,19 @@ syntect_theme = ""
|
||||||
# : }}}
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
|
# : Tabs {{{
|
||||||
|
|
||||||
|
[tabs]
|
||||||
|
active = { bg = "blue", bold = true }
|
||||||
|
inactive = { fg = "blue", bg = "gray" }
|
||||||
|
|
||||||
|
# Separator
|
||||||
|
sep_inner = { open = "", close = "" }
|
||||||
|
sep_outer = { open = "", close = "" }
|
||||||
|
|
||||||
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
# : Mode {{{
|
# : Mode {{{
|
||||||
|
|
||||||
[mode]
|
[mode]
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ pub struct Theme {
|
||||||
pub flavor: Flavor,
|
pub flavor: Flavor,
|
||||||
#[serde(rename = "manager")]
|
#[serde(rename = "manager")]
|
||||||
pub mgr: Mgr, // TODO: Remove `serde(rename)`
|
pub mgr: Mgr, // TODO: Remove `serde(rename)`
|
||||||
|
pub tabs: Tabs,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
pub status: Status,
|
pub status: Status,
|
||||||
pub which: Which,
|
pub which: Which,
|
||||||
|
|
@ -53,11 +54,6 @@ pub struct Mgr {
|
||||||
marker_marked: Style,
|
marker_marked: Style,
|
||||||
marker_selected: Style,
|
marker_selected: Style,
|
||||||
|
|
||||||
// Tab
|
|
||||||
tab_active: Style,
|
|
||||||
tab_inactive: Style,
|
|
||||||
tab_width: u8,
|
|
||||||
|
|
||||||
// Count
|
// Count
|
||||||
count_copied: Style,
|
count_copied: Style,
|
||||||
count_cut: Style,
|
count_cut: Style,
|
||||||
|
|
@ -71,6 +67,21 @@ pub struct Mgr {
|
||||||
pub syntect_theme: PathBuf,
|
pub syntect_theme: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, DeserializeOver2, Serialize)]
|
||||||
|
pub struct Tabs {
|
||||||
|
pub active: Style,
|
||||||
|
pub inactive: Style,
|
||||||
|
|
||||||
|
pub sep_inner: TabsSep,
|
||||||
|
pub sep_outer: TabsSep,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, DeserializeOver2, Serialize)]
|
||||||
|
pub struct TabsSep {
|
||||||
|
pub open: String,
|
||||||
|
pub close: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, DeserializeOver2, Serialize)]
|
#[derive(Deserialize, DeserializeOver2, Serialize)]
|
||||||
pub struct Mode {
|
pub struct Mode {
|
||||||
pub normal_main: Style,
|
pub normal_main: Style,
|
||||||
|
|
@ -197,9 +208,7 @@ pub struct Help {
|
||||||
|
|
||||||
impl Theme {
|
impl Theme {
|
||||||
pub(crate) fn reshape(mut self, light: bool) -> Result<Self> {
|
pub(crate) fn reshape(mut self, light: bool) -> Result<Self> {
|
||||||
if self.mgr.tab_width < 1 {
|
if self.which.cols < 1 || self.which.cols > 3 {
|
||||||
bail!("[mgr].tab_width must be greater than 0");
|
|
||||||
} else if self.which.cols < 1 || self.which.cols > 3 {
|
|
||||||
bail!("[which].cols must be between 1 and 3");
|
bail!("[which].cols must be between 1 and 3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ Header = {
|
||||||
},
|
},
|
||||||
_right = {
|
_right = {
|
||||||
{ "count", id = 1, order = 1000 },
|
{ "count", id = 1, order = 1000 },
|
||||||
{ "tabs", id = 2, order = 2000 },
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,27 +73,6 @@ function Header:count()
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function Header:tabs()
|
|
||||||
local tabs = #cx.tabs
|
|
||||||
if tabs == 1 then
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local spans = {}
|
|
||||||
for i = 1, tabs do
|
|
||||||
local text = i
|
|
||||||
if th.mgr.tab_width > 2 then
|
|
||||||
text = ya.truncate(text .. " " .. cx.tabs[i].name, { max = th.mgr.tab_width })
|
|
||||||
end
|
|
||||||
if i == cx.tabs.idx then
|
|
||||||
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(th.mgr.tab_active)
|
|
||||||
else
|
|
||||||
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(th.mgr.tab_inactive)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return ui.Line(spans)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Header:reflow() return { self } end
|
function Header:reflow() return { self } end
|
||||||
|
|
||||||
function Header:redraw()
|
function Header:redraw()
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ function Root:layout()
|
||||||
:direction(ui.Layout.VERTICAL)
|
:direction(ui.Layout.VERTICAL)
|
||||||
:constraints({
|
:constraints({
|
||||||
ui.Constraint.Length(1),
|
ui.Constraint.Length(1),
|
||||||
|
ui.Constraint.Length(#cx.tabs > 1 and 1 or 0),
|
||||||
ui.Constraint.Fill(1),
|
ui.Constraint.Fill(1),
|
||||||
ui.Constraint.Length(1),
|
ui.Constraint.Length(1),
|
||||||
})
|
})
|
||||||
|
|
@ -24,8 +25,9 @@ end
|
||||||
function Root:build()
|
function Root:build()
|
||||||
self._children = {
|
self._children = {
|
||||||
Header:new(self._chunks[1], cx.active),
|
Header:new(self._chunks[1], cx.active),
|
||||||
Tab:new(self._chunks[2], cx.active),
|
Tabs:new(self._chunks[2]),
|
||||||
Status:new(self._chunks[3], cx.active),
|
Tab:new(self._chunks[3], cx.active),
|
||||||
|
Status:new(self._chunks[4], cx.active),
|
||||||
Modal:new(self._area),
|
Modal:new(self._area),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
64
yazi-plugin/preset/components/tabs.lua
Normal file
64
yazi-plugin/preset/components/tabs.lua
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
Tabs = {
|
||||||
|
_id = "tabs",
|
||||||
|
_offsets = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tabs:new(area)
|
||||||
|
return setmetatable({
|
||||||
|
_area = area,
|
||||||
|
}, { __index = self })
|
||||||
|
end
|
||||||
|
|
||||||
|
function Tabs:reflow() return { self } end
|
||||||
|
|
||||||
|
function Tabs:redraw()
|
||||||
|
local len = #cx.tabs
|
||||||
|
if len < 2 then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local lines = {
|
||||||
|
ui.Line(th.tabs.sep_outer.open):fg(th.tabs.inactive.bg),
|
||||||
|
}
|
||||||
|
|
||||||
|
local pos = lines[1]:width()
|
||||||
|
local max = math.floor(self:inner_width() / len)
|
||||||
|
for i = 1, len do
|
||||||
|
local name = ya.truncate(string.format(" %d %s ", i, cx.tabs[i].name), { max = max })
|
||||||
|
if i == cx.tabs.idx then
|
||||||
|
lines[#lines + 1] = ui.Line {
|
||||||
|
ui.Span(th.tabs.sep_inner.open):style(th.tabs.inactive),
|
||||||
|
ui.Span(name):style(th.tabs.active),
|
||||||
|
ui.Span(th.tabs.sep_inner.close):style(th.tabs.inactive),
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lines[#lines + 1] = ui.Line(name):style(th.tabs.inactive)
|
||||||
|
end
|
||||||
|
self._offsets[i], pos = pos, pos + lines[#lines]:width()
|
||||||
|
end
|
||||||
|
|
||||||
|
lines[#lines + 1] = ui.Line(th.tabs.sep_outer.close):fg(th.tabs.inactive.bg)
|
||||||
|
return { ui.Line(lines):area(self._area) }
|
||||||
|
end
|
||||||
|
|
||||||
|
function Tabs:inner_width()
|
||||||
|
local si, so = th.tabs.sep_inner, th.tabs.sep_outer
|
||||||
|
return math.max(0, self._area.w - ui.Line({ si.open, si.close, so.open, so.close }):width())
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Mouse events
|
||||||
|
function Tabs:click(event, up)
|
||||||
|
if up or event.is_middle then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for i = #self._offsets, 1, -1 do
|
||||||
|
if event.x >= self._offsets[i] then
|
||||||
|
ya.emit("tab_switch", { i - 1 })
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Tabs:scroll(event, step) end
|
||||||
|
|
||||||
|
function Tabs:touch(event, step) end
|
||||||
|
|
@ -11,6 +11,7 @@ impl Theme {
|
||||||
Composer::make(lua, 15, |lua, key| {
|
Composer::make(lua, 15, |lua, key| {
|
||||||
match key {
|
match key {
|
||||||
b"mgr" => lua.to_value_with(&THEME.mgr, OPTS)?,
|
b"mgr" => lua.to_value_with(&THEME.mgr, OPTS)?,
|
||||||
|
b"tabs" => lua.to_value_with(&THEME.tabs, OPTS)?,
|
||||||
b"mode" => lua.to_value_with(&THEME.mode, OPTS)?,
|
b"mode" => lua.to_value_with(&THEME.mode, OPTS)?,
|
||||||
b"status" => lua.to_value_with(&THEME.status, OPTS)?,
|
b"status" => lua.to_value_with(&THEME.status, OPTS)?,
|
||||||
b"which" => lua.to_value_with(&THEME.which, OPTS)?,
|
b"which" => lua.to_value_with(&THEME.which, OPTS)?,
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
|
||||||
lua.load(preset!("components/root")).set_name("root.lua").exec()?;
|
lua.load(preset!("components/root")).set_name("root.lua").exec()?;
|
||||||
lua.load(preset!("components/status")).set_name("status.lua").exec()?;
|
lua.load(preset!("components/status")).set_name("status.lua").exec()?;
|
||||||
lua.load(preset!("components/tab")).set_name("tab.lua").exec()?;
|
lua.load(preset!("components/tab")).set_name("tab.lua").exec()?;
|
||||||
|
lua.load(preset!("components/tabs")).set_name("tabs.lua").exec()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue