mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat!: rounded corners for indicator bar (#3419)
This commit is contained in:
parent
396f634bb8
commit
55ef88b726
28 changed files with 340 additions and 186 deletions
|
|
@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
||||||
- Improve the UX of the pick and input components ([#2906], [#2935])
|
- Improve the UX of the pick and input components ([#2906], [#2935])
|
||||||
- Show progress of each task in task manager ([#3121], [#3131], [#3134])
|
- Show progress of each task in task manager ([#3121], [#3131], [#3134])
|
||||||
- New `overall` option to set the overall background color ([#3317])
|
- New `overall` option to set the overall background color ([#3317])
|
||||||
|
- Rounded corners for indicator bar ([#3419])
|
||||||
- New `bulk_rename` command always renames files with the editor ([#2984])
|
- New `bulk_rename` command always renames files with the editor ([#2984])
|
||||||
- `key-*` DDS events to allow changing or canceling user key events ([#3005], [#3037])
|
- `key-*` DDS events to allow changing or canceling user key events ([#3005], [#3037])
|
||||||
- New `--bg` specifying image background color in the preset SVG and ImageMagick previewers ([#3189])
|
- New `--bg` specifying image background color in the preset SVG and ImageMagick previewers ([#3189])
|
||||||
|
|
@ -45,6 +46,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
||||||
|
|
||||||
- Rename `name` to `url` for open, fetchers, spotters, preloaders, previewers, filetype, and `globs` icon rules to support virtual file system ([#3034])
|
- Rename `name` to `url` for open, fetchers, spotters, preloaders, previewers, filetype, and `globs` icon rules to support virtual file system ([#3034])
|
||||||
- Rename `mime` fetcher to `mime.local`, and introduce `mime.dir` fetcher to support folder MIME types ([#3222])
|
- Rename `mime` fetcher to `mime.local`, and introduce `mime.dir` fetcher to support folder MIME types ([#3222])
|
||||||
|
- Reclassify `hovered` and `preview_hovered` under `[mgr]` of `theme.toml` into `[indicator]` as `current` and `preview`, respectively ([#3419])
|
||||||
- Remove `$0` parameter in opener rules to make the `open` command work under empty directories ([#3226])
|
- Remove `$0` parameter in opener rules to make the `open` command work under empty directories ([#3226])
|
||||||
- Return `Path` instead of `Url` from `Url:strip_prefix()` and `File.link_to` to enforce type safety ([#3361], [#3385])
|
- Return `Path` instead of `Url` from `Url:strip_prefix()` and `File.link_to` to enforce type safety ([#3361], [#3385])
|
||||||
- Use `body` instead of the term `content` in confirmations ([#2921])
|
- Use `body` instead of the term `content` in confirmations ([#2921])
|
||||||
|
|
@ -1551,3 +1553,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
||||||
[#3391]: https://github.com/sxyazi/yazi/pull/3391
|
[#3391]: https://github.com/sxyazi/yazi/pull/3391
|
||||||
[#3393]: https://github.com/sxyazi/yazi/pull/3393
|
[#3393]: https://github.com/sxyazi/yazi/pull/3393
|
||||||
[#3396]: https://github.com/sxyazi/yazi/pull/3396
|
[#3396]: https://github.com/sxyazi/yazi/pull/3396
|
||||||
|
[#3419]: https://github.com/sxyazi/yazi/pull/3419
|
||||||
|
|
|
||||||
26
Cargo.lock
generated
26
Cargo.lock
generated
|
|
@ -300,9 +300,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64ct"
|
name = "base64ct"
|
||||||
version = "1.8.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
|
checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bcrypt-pbkdf"
|
name = "bcrypt-pbkdf"
|
||||||
|
|
@ -505,9 +505,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.48"
|
version = "1.2.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a"
|
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
|
|
@ -662,6 +662,7 @@ dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
"serde",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1305,9 +1306,9 @@ checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.6"
|
version = "1.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30f4148e3c9b7dbe0cc7e842ad5a61b28f9025f201d78149383e778a08bc9215"
|
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
|
|
@ -2825,9 +2826,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pxfm"
|
name = "pxfm"
|
||||||
version = "0.1.26"
|
version = "0.1.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3502d6155304a4173a5f2c34b52b7ed0dd085890326cb50fd625fdf39e86b3b"
|
checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
@ -2969,6 +2970,7 @@ dependencies = [
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
"lru 0.12.5",
|
"lru 0.12.5",
|
||||||
"paste",
|
"paste",
|
||||||
|
"serde",
|
||||||
"strum",
|
"strum",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-truncate",
|
"unicode-truncate",
|
||||||
|
|
@ -3526,9 +3528,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.7"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd_helpers"
|
name = "simd_helpers"
|
||||||
|
|
@ -5270,9 +5272,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-jpeg"
|
name = "zune-jpeg"
|
||||||
version = "0.5.5"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc6fb7703e32e9a07fb3f757360338b3a567a5054f21b5f52a666752e333d58e"
|
checksum = "f520eebad972262a1dde0ec455bce4f8b298b1e5154513de58c114c4c54303e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core",
|
"zune-core",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ parking_lot = "0.12.5"
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
percent-encoding = "2.3.2"
|
percent-encoding = "2.3.2"
|
||||||
rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] }
|
rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] }
|
||||||
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info", "unstable-widget-ref" ] }
|
ratatui = { version = "0.29.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] }
|
||||||
regex = "1.12.2"
|
regex = "1.12.2"
|
||||||
russh = { version = "0.55.0", default-features = false, features = [ "ring", "rsa" ] }
|
russh = { version = "0.55.0", default-features = false, features = [ "ring", "rsa" ] }
|
||||||
scopeguard = "1.2.0"
|
scopeguard = "1.2.0"
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl UserData for Core {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(match key.as_bytes().as_ref() {
|
Ok(match &*key.as_bytes() {
|
||||||
b"active" => reuse!(active, super::Tab::make(me.active())),
|
b"active" => reuse!(active, super::Tab::make(me.active())),
|
||||||
b"tabs" => reuse!(tabs, super::Tabs::make(&me.mgr.tabs)),
|
b"tabs" => reuse!(tabs, super::Tabs::make(&me.mgr.tabs)),
|
||||||
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
|
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,11 @@ impl UserData for File {
|
||||||
|
|
||||||
fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1));
|
fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1));
|
||||||
fields.add_field_method_get("is_hovered", |_, me| Ok(me.idx == me.folder.cursor));
|
fields.add_field_method_get("is_hovered", |_, me| Ok(me.idx == me.folder.cursor));
|
||||||
|
fields.add_field_method_get("in_current", |_, me| {
|
||||||
|
Ok(&*me.folder as *const _ == &me.tab.current as *const _)
|
||||||
|
});
|
||||||
fields.add_field_method_get("in_preview", |_, me| {
|
fields.add_field_method_get("in_preview", |_, me| {
|
||||||
Ok(me.tab.hovered().is_some_and(|f| f.url == me.folder.url))
|
Ok(me.idx == me.folder.cursor && me.tab.hovered().is_some_and(|f| f.url == me.folder.url))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value};
|
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value};
|
||||||
use yazi_binding::cached_field;
|
use yazi_binding::{SER_OPT, cached_field};
|
||||||
use yazi_plugin::runtime::SER_OPT;
|
|
||||||
|
|
||||||
use super::{Lives, PtrCell};
|
use super::{Lives, PtrCell};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value};
|
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value};
|
||||||
use yazi_binding::{cached_field, deprecate};
|
use yazi_binding::{SER_OPT, cached_field, deprecate};
|
||||||
use yazi_plugin::runtime::SER_OPT;
|
|
||||||
|
|
||||||
use super::{Lives, PtrCell};
|
use super::{Lives, PtrCell};
|
||||||
use crate::lives::TaskSnap;
|
use crate::lives::TaskSnap;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ impl Rect {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let index = lua.create_function(move |lua, (_, key): (Table, mlua::String)| {
|
let index = lua.create_function(move |lua, (_, key): (Table, mlua::String)| {
|
||||||
Ok(match key.as_bytes().as_ref() {
|
Ok(match &*key.as_bytes() {
|
||||||
b"default" => {
|
b"default" => {
|
||||||
deprecate!(lua, "`ui.Rect.default` is deprecated, use `ui.Rect{{}}` instead, in your {}\nSee #2927 for more details: https://github.com/sxyazi/yazi/pull/2927");
|
deprecate!(lua, "`ui.Rect.default` is deprecated, use `ui.Rect{{}}` instead, in your {}\nSee #2927 for more details: https://github.com/sxyazi/yazi/pull/2927");
|
||||||
Some(Self(Default::default()))
|
Some(Self(Default::default()))
|
||||||
|
|
|
||||||
|
|
@ -82,65 +82,122 @@ macro_rules! impl_style_method {
|
||||||
macro_rules! impl_style_shorthands {
|
macro_rules! impl_style_shorthands {
|
||||||
($methods:ident, $($field:tt).+) => {
|
($methods:ident, $($field:tt).+) => {
|
||||||
$methods.add_function_mut("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
|
$methods.add_function_mut("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
|
||||||
|
use ratatui::style::Modifier;
|
||||||
|
|
||||||
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::Nil => {
|
mlua::Value::Boolean(true) if me.add_modifier.contains(Modifier::REVERSED) && !me.sub_modifier.contains(Modifier::REVERSED) => {
|
||||||
ud.borrow::<Self>()?.$($field).+.fg.map($crate::Color).into_lua(lua)
|
me.bg.map($crate::Color).into_lua(lua)
|
||||||
},
|
}
|
||||||
|
mlua::Value::Nil | mlua::Value::Boolean(_) => {
|
||||||
|
me.fg.map($crate::Color).into_lua(lua)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.fg = Some($crate::Color::try_from(value)?.0);
|
me.fg = Some($crate::Color::try_from(value)?.0);
|
||||||
ud.into_lua(lua)
|
ud.into_lua(lua)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
|
$methods.add_function_mut("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
|
||||||
|
use ratatui::style::Modifier;
|
||||||
|
|
||||||
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::Nil => {
|
mlua::Value::Boolean(true) if me.add_modifier.contains(Modifier::REVERSED) && !me.sub_modifier.contains(Modifier::REVERSED) => {
|
||||||
ud.borrow::<Self>()?.$($field).+.bg.map($crate::Color).into_lua(lua)
|
me.fg.map($crate::Color).into_lua(lua)
|
||||||
|
}
|
||||||
|
mlua::Value::Nil | mlua::Value::Boolean(_) => {
|
||||||
|
me.bg.map($crate::Color).into_lua(lua)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.bg = Some($crate::Color::try_from(value)?.0);
|
me.bg = Some($crate::Color::try_from(value)?.0);
|
||||||
ud.into_lua(lua)
|
ud.into_lua(lua)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("bold", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("bold", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::BOLD;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::BOLD);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::BOLD);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("dim", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("dim", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::DIM;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::DIM);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::DIM);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("italic", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("italic", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::ITALIC;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::ITALIC);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::ITALIC);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("underline", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("underline", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::UNDERLINED;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::UNDERLINED);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::UNDERLINED);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("blink", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("blink", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::SLOW_BLINK;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::SLOW_BLINK);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::SLOW_BLINK);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("blink_rapid", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("blink_rapid", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::RAPID_BLINK;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::RAPID_BLINK);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::RAPID_BLINK);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("reverse", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("reverse", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::REVERSED;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::REVERSED);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::REVERSED);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("hidden", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("hidden", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::HIDDEN;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::HIDDEN);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::HIDDEN);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("crossed", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("crossed", |_, (ud, remove): (mlua::AnyUserData, bool)| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier |= ratatui::style::Modifier::CROSSED_OUT;
|
let me = &mut ud.borrow_mut::<Self>()?.$($field).+;
|
||||||
|
if remove {
|
||||||
|
*me = me.remove_modifier(ratatui::style::Modifier::CROSSED_OUT);
|
||||||
|
} else {
|
||||||
|
*me = me.add_modifier(ratatui::style::Modifier::CROSSED_OUT);
|
||||||
|
}
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
$methods.add_function_mut("reset", |_, ud: mlua::AnyUserData| {
|
$methods.add_function_mut("reset", |_, ud: mlua::AnyUserData| {
|
||||||
ud.borrow_mut::<Self>()?.$($field).+.add_modifier = ratatui::style::Modifier::empty();
|
ud.borrow_mut::<Self>()?.$($field).+ = ratatui::style::Style::reset();
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
|
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, LuaSerdeExt, MetaMethod, Table, UserData, UserDataMethods, Value};
|
||||||
|
|
||||||
|
use crate::SER_OPT;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct Style(pub ratatui::style::Style);
|
pub struct Style(pub ratatui::style::Style);
|
||||||
|
|
@ -34,6 +36,9 @@ impl UserData for Style {
|
||||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||||
crate::impl_style_shorthands!(methods, 0);
|
crate::impl_style_shorthands!(methods, 0);
|
||||||
|
|
||||||
|
methods
|
||||||
|
.add_method("raw", |lua, me, ()| lua.to_value_with(&yazi_config::Style::from(me.0), SER_OPT));
|
||||||
|
|
||||||
methods.add_function_mut("patch", |_, (ud, value): (AnyUserData, Value)| {
|
methods.add_function_mut("patch", |_, (ud, value): (AnyUserData, Value)| {
|
||||||
{
|
{
|
||||||
let mut me = ud.borrow_mut::<Self>()?;
|
let mut me = ud.borrow_mut::<Self>()?;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
use mlua::{IntoLua, Lua, Table, Value};
|
use mlua::{IntoLua, Lua, SerializeOptions, Table, Value};
|
||||||
|
|
||||||
|
pub const SER_OPT: SerializeOptions =
|
||||||
|
SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false);
|
||||||
|
|
||||||
pub fn get_metatable(lua: &Lua, value: impl IntoLua) -> mlua::Result<Table> {
|
pub fn get_metatable(lua: &Lua, value: impl IntoLua) -> mlua::Result<Table> {
|
||||||
let (_, mt): (Value, Table) = unsafe {
|
let (_, mt): (Value, Table) = unsafe {
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,6 @@ overall = {}
|
||||||
[mgr]
|
[mgr]
|
||||||
cwd = { fg = "cyan" }
|
cwd = { fg = "cyan" }
|
||||||
|
|
||||||
# Hovered
|
|
||||||
hovered = { reversed = true }
|
|
||||||
preview_hovered = { underline = true }
|
|
||||||
|
|
||||||
# Find
|
# Find
|
||||||
find_keyword = { fg = "yellow", bold = true, italic = true, underline = true }
|
find_keyword = { fg = "yellow", bold = true, italic = true, underline = true }
|
||||||
find_position = { fg = "magenta", bg = "reset", bold = true, italic = true }
|
find_position = { fg = "magenta", bg = "reset", bold = true, italic = true }
|
||||||
|
|
@ -91,6 +87,17 @@ unset_alt = { fg = "red", bg = "gray" }
|
||||||
# : }}}
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
|
# : Indicator of hovered file {{{
|
||||||
|
|
||||||
|
[indicator]
|
||||||
|
parent = { reversed = true }
|
||||||
|
current = { reversed = true }
|
||||||
|
preview = { underline = true }
|
||||||
|
padding = { open = "", close = "" }
|
||||||
|
|
||||||
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
# : Status bar {{{
|
# : Status bar {{{
|
||||||
|
|
||||||
[status]
|
[status]
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,6 @@ overall = {}
|
||||||
[mgr]
|
[mgr]
|
||||||
cwd = { fg = "cyan" }
|
cwd = { fg = "cyan" }
|
||||||
|
|
||||||
# Hovered
|
|
||||||
hovered = { reversed = true }
|
|
||||||
preview_hovered = { underline = true }
|
|
||||||
|
|
||||||
# Find
|
# Find
|
||||||
find_keyword = { fg = "yellow", bold = true, italic = true, underline = true }
|
find_keyword = { fg = "yellow", bold = true, italic = true, underline = true }
|
||||||
find_position = { fg = "magenta", bg = "reset", bold = true, italic = true }
|
find_position = { fg = "magenta", bg = "reset", bold = true, italic = true }
|
||||||
|
|
@ -91,6 +87,17 @@ unset_alt = { fg = "red", bg = "gray" }
|
||||||
# : }}}
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
|
# : Indicator of hovered file {{{
|
||||||
|
|
||||||
|
[indicator]
|
||||||
|
parent = { reversed = true }
|
||||||
|
current = { reversed = true }
|
||||||
|
preview = { underline = true }
|
||||||
|
padding = { open = "", close = "" }
|
||||||
|
|
||||||
|
# : }}}
|
||||||
|
|
||||||
|
|
||||||
# : Status bar {{{
|
# : Status bar {{{
|
||||||
|
|
||||||
[status]
|
[status]
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
use std::{ops::Deref, str::FromStr};
|
|
||||||
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
|
||||||
pub struct Color(ratatui::style::Color);
|
|
||||||
|
|
||||||
impl Deref for Color {
|
|
||||||
type Target = ratatui::style::Color;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Color> for ratatui::style::Color {
|
|
||||||
fn from(value: Color) -> Self { value.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Color {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
ratatui::style::Color::from_str(&String::deserialize(deserializer)?)
|
|
||||||
.map_err(serde::de::Error::custom)
|
|
||||||
.map(Self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
yazi_macro::mod_pub!(keymap mgr open opener plugin popup preview tasks theme which vfs);
|
yazi_macro::mod_pub!(keymap mgr open opener plugin popup preview tasks theme which vfs);
|
||||||
|
|
||||||
yazi_macro::mod_flat!(color icon layout pattern platform preset priority style yazi);
|
yazi_macro::mod_flat!(icon layout pattern platform preset priority style yazi);
|
||||||
|
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,86 @@
|
||||||
use ratatui::style::Modifier;
|
use ratatui::style::Color;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::Color;
|
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Deserialize)]
|
|
||||||
pub struct Style {
|
pub struct Style {
|
||||||
pub fg: Option<Color>,
|
pub fg: Option<Color>,
|
||||||
pub bg: Option<Color>,
|
pub bg: Option<Color>,
|
||||||
#[serde(default)]
|
pub bold: Option<bool>,
|
||||||
pub bold: bool,
|
pub dim: Option<bool>,
|
||||||
#[serde(default)]
|
pub italic: Option<bool>,
|
||||||
pub dim: bool,
|
pub underline: Option<bool>,
|
||||||
#[serde(default)]
|
pub blink: Option<bool>,
|
||||||
pub italic: bool,
|
pub blink_rapid: Option<bool>,
|
||||||
#[serde(default)]
|
pub reversed: Option<bool>,
|
||||||
pub underline: bool,
|
pub hidden: Option<bool>,
|
||||||
#[serde(default)]
|
pub crossed: Option<bool>,
|
||||||
pub blink: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub blink_rapid: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub reversed: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub hidden: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub crossed: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Style> for ratatui::style::Style {
|
impl From<ratatui::style::Style> for Style {
|
||||||
fn from(value: Style) -> Self {
|
#[rustfmt::skip]
|
||||||
|
fn from(value: ratatui::style::Style) -> Self {
|
||||||
|
use ratatui::style::Modifier as M;
|
||||||
|
|
||||||
|
let sub = value.sub_modifier;
|
||||||
|
let all = value.add_modifier - sub;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fg: value.fg.map(Into::into),
|
fg: value.fg.map(Into::into),
|
||||||
bg: value.bg.map(Into::into),
|
bg: value.bg.map(Into::into),
|
||||||
underline_color: None,
|
bold: if all.contains(M::BOLD) { Some(true) } else if sub.contains(M::BOLD) { Some(false) } else { None },
|
||||||
add_modifier: value.into(),
|
dim: if all.contains(M::DIM) { Some(true) } else if sub.contains(M::DIM) { Some(false) } else { None },
|
||||||
sub_modifier: Modifier::empty(),
|
italic: if all.contains(M::ITALIC) { Some(true) } else if sub.contains(M::ITALIC) { Some(false) } else { None },
|
||||||
|
underline: if all.contains(M::UNDERLINED) { Some(true) } else if sub.contains(M::UNDERLINED) { Some(false) } else { None },
|
||||||
|
blink: if all.contains(M::SLOW_BLINK) { Some(true) } else if sub.contains(M::SLOW_BLINK) { Some(false) } else { None },
|
||||||
|
blink_rapid: if all.contains(M::RAPID_BLINK) { Some(true) } else if sub.contains(M::RAPID_BLINK) { Some(false) } else { None },
|
||||||
|
reversed: if all.contains(M::REVERSED) { Some(true) } else if sub.contains(M::REVERSED) { Some(false) } else { None },
|
||||||
|
hidden: if all.contains(M::HIDDEN) { Some(true) } else if sub.contains(M::HIDDEN) { Some(false) } else { None },
|
||||||
|
crossed: if all.contains(M::CROSSED_OUT) { Some(true) } else if sub.contains(M::CROSSED_OUT) { Some(false) } else { None },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Style> for ratatui::style::Modifier {
|
impl From<Style> for ratatui::style::Style {
|
||||||
|
#[rustfmt::skip]
|
||||||
fn from(value: Style) -> Self {
|
fn from(value: Style) -> Self {
|
||||||
let mut modifier = Self::empty();
|
use ratatui::style::Modifier as M;
|
||||||
if value.bold {
|
|
||||||
modifier |= Self::BOLD;
|
let (mut add, mut sub) = (M::empty(), M::empty());
|
||||||
|
if let Some(b) = value.bold {
|
||||||
|
if b { add |= M::BOLD } else { sub |= M::BOLD };
|
||||||
}
|
}
|
||||||
if value.dim {
|
if let Some(b) = value.dim {
|
||||||
modifier |= Self::DIM;
|
if b { add |= M::DIM } else { sub |= M::DIM };
|
||||||
}
|
}
|
||||||
if value.italic {
|
if let Some(b) = value.italic {
|
||||||
modifier |= Self::ITALIC;
|
if b { add |= M::ITALIC } else { sub |= M::ITALIC };
|
||||||
}
|
}
|
||||||
if value.underline {
|
if let Some(b) = value.underline {
|
||||||
modifier |= Self::UNDERLINED;
|
if b { add |= M::UNDERLINED } else { sub |= M::UNDERLINED };
|
||||||
}
|
}
|
||||||
if value.blink {
|
if let Some(b) = value.blink {
|
||||||
modifier |= Self::SLOW_BLINK;
|
if b { add |= M::SLOW_BLINK } else { sub |= M::SLOW_BLINK };
|
||||||
}
|
}
|
||||||
if value.blink_rapid {
|
if let Some(b) = value.blink_rapid {
|
||||||
modifier |= Self::RAPID_BLINK;
|
if b { add |= M::RAPID_BLINK } else { sub |= M::RAPID_BLINK };
|
||||||
}
|
}
|
||||||
if value.reversed {
|
if let Some(b) = value.reversed {
|
||||||
modifier |= Self::REVERSED;
|
if b { add |= M::REVERSED } else { sub |= M::REVERSED };
|
||||||
}
|
}
|
||||||
if value.hidden {
|
if let Some(b) = value.hidden {
|
||||||
modifier |= Self::HIDDEN;
|
if b { add |= M::HIDDEN } else { sub |= M::HIDDEN };
|
||||||
}
|
}
|
||||||
if value.crossed {
|
if let Some(b) = value.crossed {
|
||||||
modifier |= Self::CROSSED_OUT;
|
if b { add |= M::CROSSED_OUT } else { sub |= M::CROSSED_OUT };
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
fg: value.fg.map(Into::into),
|
||||||
|
bg: value.bg.map(Into::into),
|
||||||
|
underline_color: None,
|
||||||
|
add_modifier: add,
|
||||||
|
sub_modifier: sub,
|
||||||
}
|
}
|
||||||
modifier
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@ use std::ops::Deref;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use ratatui::style::Color;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use yazi_codegen::DeserializeOver2;
|
use yazi_codegen::DeserializeOver2;
|
||||||
use yazi_fs::File;
|
use yazi_fs::File;
|
||||||
use yazi_shared::{Condition, url::UrlLike};
|
use yazi_shared::{Condition, url::UrlLike};
|
||||||
|
|
||||||
use crate::{Color, Icon as I, Pattern, Style};
|
use crate::{Icon as I, Pattern, Style};
|
||||||
|
|
||||||
#[derive(Default, Deserialize, DeserializeOver2)]
|
#[derive(Default, Deserialize, DeserializeOver2)]
|
||||||
pub struct Icon {
|
pub struct Icon {
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,22 @@ use crate::Style;
|
||||||
|
|
||||||
#[derive(Deserialize, DeserializeOver1)]
|
#[derive(Deserialize, DeserializeOver1)]
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
pub flavor: Flavor,
|
pub flavor: Flavor,
|
||||||
pub app: App,
|
pub app: App,
|
||||||
pub mgr: Mgr,
|
pub mgr: Mgr,
|
||||||
pub tabs: Tabs,
|
pub tabs: Tabs,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
pub status: Status,
|
pub indicator: Indicator,
|
||||||
pub which: Which,
|
pub status: Status,
|
||||||
pub confirm: Confirm,
|
pub which: Which,
|
||||||
pub spot: Spot,
|
pub confirm: Confirm,
|
||||||
pub notify: Notify,
|
pub spot: Spot,
|
||||||
pub pick: Pick,
|
pub notify: Notify,
|
||||||
pub input: Input,
|
pub pick: Pick,
|
||||||
pub cmp: Cmp,
|
pub input: Input,
|
||||||
pub tasks: Tasks,
|
pub cmp: Cmp,
|
||||||
pub help: Help,
|
pub tasks: Tasks,
|
||||||
|
pub help: Help,
|
||||||
|
|
||||||
// File-specific styles
|
// File-specific styles
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
|
@ -43,10 +44,6 @@ pub struct App {
|
||||||
pub struct Mgr {
|
pub struct Mgr {
|
||||||
pub cwd: Style,
|
pub cwd: Style,
|
||||||
|
|
||||||
// Hovered
|
|
||||||
pub hovered: Style,
|
|
||||||
pub preview_hovered: Style,
|
|
||||||
|
|
||||||
// Find
|
// Find
|
||||||
pub find_keyword: Style,
|
pub find_keyword: Style,
|
||||||
pub find_position: Style,
|
pub find_position: Style,
|
||||||
|
|
@ -100,6 +97,20 @@ pub struct Mode {
|
||||||
pub unset_alt: Style,
|
pub unset_alt: Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, DeserializeOver2)]
|
||||||
|
pub struct Indicator {
|
||||||
|
pub parent: Style,
|
||||||
|
pub current: Style,
|
||||||
|
pub preview: Style,
|
||||||
|
pub padding: IndicatorPadding,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, DeserializeOver2)]
|
||||||
|
pub struct IndicatorPadding {
|
||||||
|
pub open: String,
|
||||||
|
pub close: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, DeserializeOver2)]
|
#[derive(Deserialize, DeserializeOver2)]
|
||||||
pub struct Status {
|
pub struct Status {
|
||||||
pub overall: Style,
|
pub overall: Style,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ impl App {
|
||||||
};
|
};
|
||||||
|
|
||||||
let id: mlua::String = t.get("_id")?;
|
let id: mlua::String = t.get("_id")?;
|
||||||
match id.as_bytes().as_ref() {
|
match &*id.as_bytes() {
|
||||||
b"current" => layout.current = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
|
b"current" => layout.current = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
|
||||||
b"preview" => layout.preview = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
|
b"preview" => layout.preview = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
|
||||||
b"progress" => layout.progress = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
|
b"progress" => layout.progress = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
Entity = {
|
Entity = {
|
||||||
_inc = 1000,
|
_inc = 1000,
|
||||||
_children = {
|
_children = {
|
||||||
{ "spacer", id = 1, order = 1000 },
|
{ "padding", id = 1, order = 1000 },
|
||||||
{ "icon", id = 2, order = 2000 },
|
{ "icon", id = 2, order = 2000 },
|
||||||
{ "prefix", id = 3, order = 3000 },
|
{ "prefix", id = 3, order = 3000 },
|
||||||
{ "highlights", id = 4, order = 4000 },
|
{ "highlights", id = 4, order = 4000 },
|
||||||
|
|
@ -12,7 +12,18 @@ Entity = {
|
||||||
|
|
||||||
function Entity:new(file) return setmetatable({ _file = file }, { __index = self }) end
|
function Entity:new(file) return setmetatable({ _file = file }, { __index = self }) end
|
||||||
|
|
||||||
function Entity:spacer() return " " end
|
function Entity:padding()
|
||||||
|
if not self._file.is_hovered or self._file.in_preview then
|
||||||
|
return " "
|
||||||
|
end
|
||||||
|
|
||||||
|
local style = self:style_rev()
|
||||||
|
if style then
|
||||||
|
return ui.Span(th.indicator.padding.open):style(style)
|
||||||
|
else
|
||||||
|
return " "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Entity:icon()
|
function Entity:icon()
|
||||||
local icon = self._file:icon()
|
local icon = self._file:icon()
|
||||||
|
|
@ -86,13 +97,25 @@ function Entity:redraw()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Entity:style()
|
function Entity:style()
|
||||||
local s = self._file:style()
|
local s = self._file:style() or ui.Style()
|
||||||
if not self._file.is_hovered then
|
if not self._file.is_hovered then
|
||||||
return s
|
return s
|
||||||
|
elseif self._file.in_current then
|
||||||
|
return s:patch(th.indicator.current)
|
||||||
elseif self._file.in_preview then
|
elseif self._file.in_preview then
|
||||||
return s and s:patch(th.mgr.preview_hovered) or th.mgr.preview_hovered
|
return s:patch(th.indicator.preview)
|
||||||
else
|
else
|
||||||
return s and s:patch(th.mgr.hovered) or th.mgr.hovered
|
return s:patch(th.indicator.parent)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Entity:style_rev()
|
||||||
|
local s = self:style()
|
||||||
|
local bg = s:bg(true)
|
||||||
|
if bg then
|
||||||
|
return ui.Style():fg(bg):bg("reset"):reverse(true)
|
||||||
|
elseif s:raw().reversed then
|
||||||
|
return ui.Style():bg("reset"):reverse(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,30 @@ Linemode = {
|
||||||
_inc = 1000,
|
_inc = 1000,
|
||||||
_children = {
|
_children = {
|
||||||
{ "solo", id = 1, order = 1000 },
|
{ "solo", id = 1, order = 1000 },
|
||||||
{ "spacer", id = 2, order = 2000 },
|
{ "padding", id = 2, order = 2000 },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
function Linemode:new(file) return setmetatable({ _file = file }, { __index = self }) end
|
function Linemode:new(file) return setmetatable({ _file = file }, { __index = self }) end
|
||||||
|
|
||||||
function Linemode:spacer() return " " end
|
function Linemode:padding()
|
||||||
|
if not self._file.is_hovered then
|
||||||
|
return " "
|
||||||
|
end
|
||||||
|
|
||||||
|
local style = Entity:new(self._file):style_rev()
|
||||||
|
if style then
|
||||||
|
return ui.Span(th.indicator.padding.close):style(style)
|
||||||
|
else
|
||||||
|
return " "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Linemode:solo()
|
function Linemode:solo()
|
||||||
|
if not self._file.in_current then
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
local mode = cx.active.pref.linemode
|
local mode = cx.active.pref.linemode
|
||||||
if mode == "none" or mode == "solo" then
|
if mode == "none" or mode == "solo" then
|
||||||
return ""
|
return ""
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,19 @@ function Parent:redraw()
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local items = {}
|
local left, right = {}, {}
|
||||||
for _, f in ipairs(self._folder.window) do
|
for _, f in ipairs(self._folder.window) do
|
||||||
local entity = Entity:new(f)
|
local entity = Entity:new(f)
|
||||||
items[#items + 1] = entity:redraw():truncate {
|
left[#left + 1], right[#right + 1] = entity:redraw(), Linemode:new(f):redraw()
|
||||||
max = self._area.w,
|
|
||||||
ellipsis = entity:ellipsis(self._area.w),
|
local max = math.max(0, self._area.w - right[#right]:width())
|
||||||
}
|
left[#left]:truncate { max = max, ellipsis = entity:ellipsis(max) }
|
||||||
end
|
end
|
||||||
|
|
||||||
return ui.List(items):area(self._area)
|
return {
|
||||||
|
ui.List(left):area(self._area),
|
||||||
|
ui.Text(right):area(self._area):align(ui.Align.RIGHT),
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Mouse events
|
-- Mouse events
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||||
pub(super) fn area(lua: &Lua) -> mlua::Result<Value> {
|
pub(super) fn area(lua: &Lua) -> mlua::Result<Value> {
|
||||||
let f = lua.create_function(|_, s: mlua::String| {
|
let f = lua.create_function(|_, s: mlua::String| {
|
||||||
let layout = LAYOUT.get();
|
let layout = LAYOUT.get();
|
||||||
Ok(match s.as_bytes().as_ref() {
|
Ok(match &*s.as_bytes() {
|
||||||
b"current" => Rect(layout.current),
|
b"current" => Rect(layout.current),
|
||||||
b"preview" => Rect(layout.preview),
|
b"preview" => Rect(layout.preview),
|
||||||
b"progress" => Rect(layout.progress),
|
b"progress" => Rect(layout.progress),
|
||||||
|
|
@ -74,7 +74,7 @@ pub(super) fn redraw(lua: &Lua) -> mlua::Result<Value> {
|
||||||
let id: mlua::String = c.get("_id")?;
|
let id: mlua::String = c.get("_id")?;
|
||||||
|
|
||||||
let mut layout = LAYOUT.get();
|
let mut layout = LAYOUT.get();
|
||||||
match id.as_bytes().as_ref() {
|
match &*id.as_bytes() {
|
||||||
b"current" => layout.current = *c.raw_get::<Rect>("_area")?,
|
b"current" => layout.current = *c.raw_get::<Rect>("_area")?,
|
||||||
b"preview" => layout.preview = *c.raw_get::<Rect>("_area")?,
|
b"preview" => layout.preview = *c.raw_get::<Rect>("_area")?,
|
||||||
b"progress" => layout.progress = *c.raw_get::<Rect>("_area")?,
|
b"progress" => layout.progress = *c.raw_get::<Rect>("_area")?,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op(lua: &Lua) -> mlua::Result<Function> {
|
fn op(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_function(|lua, (name, t): (mlua::String, Table)| match name.as_bytes().as_ref() {
|
lua.create_function(|lua, (name, t): (mlua::String, Table)| match &*name.as_bytes() {
|
||||||
b"part" => super::FilesOp::part(lua, t),
|
b"part" => super::FilesOp::part(lua, t),
|
||||||
b"done" => super::FilesOp::done(lua, t),
|
b"done" => super::FilesOp::done(lua, t),
|
||||||
b"size" => super::FilesOp::size(lua, t),
|
b"size" => super::FilesOp::size(lua, t),
|
||||||
|
|
@ -75,7 +75,7 @@ fn write(lua: &Lua) -> mlua::Result<Function> {
|
||||||
|
|
||||||
fn create(lua: &Lua) -> mlua::Result<Function> {
|
fn create(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_async_function(|lua, (r#type, url): (mlua::String, UrlRef)| async move {
|
lua.create_async_function(|lua, (r#type, url): (mlua::String, UrlRef)| async move {
|
||||||
let result = match r#type.as_bytes().as_ref() {
|
let result = match &*r#type.as_bytes() {
|
||||||
b"dir" => provider::create_dir(&*url).await,
|
b"dir" => provider::create_dir(&*url).await,
|
||||||
b"dir_all" => provider::create_dir_all(&*url).await,
|
b"dir_all" => provider::create_dir_all(&*url).await,
|
||||||
_ => Err("Creation type must be 'dir' or 'dir_all'".into_lua_err())?,
|
_ => Err("Creation type must be 'dir' or 'dir_all'".into_lua_err())?,
|
||||||
|
|
@ -90,7 +90,7 @@ fn create(lua: &Lua) -> mlua::Result<Function> {
|
||||||
|
|
||||||
fn remove(lua: &Lua) -> mlua::Result<Function> {
|
fn remove(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_async_function(|lua, (r#type, url): (mlua::String, UrlRef)| async move {
|
lua.create_async_function(|lua, (r#type, url): (mlua::String, UrlRef)| async move {
|
||||||
let result = match r#type.as_bytes().as_ref() {
|
let result = match &*r#type.as_bytes() {
|
||||||
b"file" => provider::remove_file(&*url).await,
|
b"file" => provider::remove_file(&*url).await,
|
||||||
b"dir" => provider::remove_dir(&*url).await,
|
b"dir" => provider::remove_dir(&*url).await,
|
||||||
b"dir_all" => provider::remove_dir_all(&*url).await,
|
b"dir_all" => provider::remove_dir_all(&*url).await,
|
||||||
|
|
@ -165,7 +165,7 @@ fn expand_url(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_function(|_, value: Value| {
|
lua.create_function(|_, value: Value| {
|
||||||
use yazi_fs::path::expand_url;
|
use yazi_fs::path::expand_url;
|
||||||
Ok(Url::new(match value {
|
Ok(Url::new(match value {
|
||||||
Value::String(s) => expand_url(UrlCow::try_from(s.as_bytes().as_ref())?),
|
Value::String(s) => expand_url(UrlCow::try_from(&*s.as_bytes())?),
|
||||||
Value::UserData(ud) => expand_url(&*ud.borrow::<yazi_binding::Url>()?),
|
Value::UserData(ud) => expand_url(&*ud.borrow::<yazi_binding::Url>()?),
|
||||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
use mlua::{IntoLua, Lua, LuaSerdeExt, SerializeOptions, Value};
|
use mlua::{IntoLua, Lua, LuaSerdeExt, Value};
|
||||||
use yazi_binding::{Composer, ComposerGet, ComposerSet, Url};
|
use yazi_binding::{Composer, ComposerGet, ComposerSet, SER_OPT, Url};
|
||||||
use yazi_boot::ARGS;
|
use yazi_boot::ARGS;
|
||||||
use yazi_config::YAZI;
|
use yazi_config::YAZI;
|
||||||
|
|
||||||
pub const SER_OPT: SerializeOptions =
|
|
||||||
SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false);
|
|
||||||
|
|
||||||
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||||
match key {
|
match key {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use mlua::{IntoLua, Lua, Value};
|
use mlua::{IntoLua, Lua, Value};
|
||||||
use yazi_binding::{Composer, ComposerGet, ComposerSet, Style, Url};
|
use yazi_binding::{Composer, ComposerGet, ComposerSet, Style, Url, deprecate};
|
||||||
use yazi_config::THEME;
|
use yazi_config::THEME;
|
||||||
|
|
||||||
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||||
|
|
@ -9,6 +9,7 @@ pub fn compose() -> Composer<ComposerGet, ComposerSet> {
|
||||||
b"mgr" => mgr(),
|
b"mgr" => mgr(),
|
||||||
b"tabs" => tabs(),
|
b"tabs" => tabs(),
|
||||||
b"mode" => mode(),
|
b"mode" => mode(),
|
||||||
|
b"indicator" => indicator(),
|
||||||
b"status" => status(),
|
b"status" => status(),
|
||||||
b"which" => which(),
|
b"which" => which(),
|
||||||
b"confirm" => confirm(),
|
b"confirm" => confirm(),
|
||||||
|
|
@ -50,8 +51,20 @@ fn mgr() -> Composer<ComposerGet, ComposerSet> {
|
||||||
match key {
|
match key {
|
||||||
b"cwd" => Style::from(m.cwd).into_lua(lua),
|
b"cwd" => Style::from(m.cwd).into_lua(lua),
|
||||||
|
|
||||||
b"hovered" => Style::from(m.hovered).into_lua(lua),
|
b"hovered" => {
|
||||||
b"preview_hovered" => Style::from(m.preview_hovered).into_lua(lua),
|
deprecate!(
|
||||||
|
lua,
|
||||||
|
"`th.mgr.hovered` is deprecated, use `th.indicator.current` instead, in your {}\nSee #3419 for more details: https://github.com/sxyazi/yazi/pull/3419"
|
||||||
|
);
|
||||||
|
Style::from(THEME.indicator.current).into_lua(lua)
|
||||||
|
}
|
||||||
|
b"preview_hovered" => {
|
||||||
|
deprecate!(
|
||||||
|
lua,
|
||||||
|
"`th.mgr.preview_hovered` is deprecated, use `th.indicator.preview` instead, in your {}\nSee #3419 for more details: https://github.com/sxyazi/yazi/pull/3419"
|
||||||
|
);
|
||||||
|
Style::from(THEME.indicator.preview).into_lua(lua)
|
||||||
|
}
|
||||||
|
|
||||||
b"find_keyword" => Style::from(m.find_keyword).into_lua(lua),
|
b"find_keyword" => Style::from(m.find_keyword).into_lua(lua),
|
||||||
b"find_position" => Style::from(m.find_position).into_lua(lua),
|
b"find_position" => Style::from(m.find_position).into_lua(lua),
|
||||||
|
|
@ -131,6 +144,29 @@ fn mode() -> Composer<ComposerGet, ComposerSet> {
|
||||||
Composer::new(get, set)
|
Composer::new(get, set)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn indicator() -> Composer<ComposerGet, ComposerSet> {
|
||||||
|
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||||
|
let t = &THEME.indicator;
|
||||||
|
match key {
|
||||||
|
b"parent" => Style::from(t.parent).into_lua(lua),
|
||||||
|
b"current" => Style::from(t.current).into_lua(lua),
|
||||||
|
b"preview" => Style::from(t.preview).into_lua(lua),
|
||||||
|
b"padding" => lua
|
||||||
|
.create_table_from([
|
||||||
|
("open", lua.create_string(&t.padding.open)?),
|
||||||
|
("close", lua.create_string(&t.padding.close)?),
|
||||||
|
])?
|
||||||
|
.into_lua(lua),
|
||||||
|
|
||||||
|
_ => Ok(Value::Nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result<Value> { Ok(value) }
|
||||||
|
|
||||||
|
Composer::new(get, set)
|
||||||
|
}
|
||||||
|
|
||||||
fn status() -> Composer<ComposerGet, ComposerSet> {
|
fn status() -> Composer<ComposerGet, ComposerSet> {
|
||||||
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
|
||||||
let t = &THEME.status;
|
let t = &THEME.status;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use super::Utils;
|
||||||
impl Utils {
|
impl Utils {
|
||||||
pub(super) fn id(lua: &Lua) -> mlua::Result<Function> {
|
pub(super) fn id(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_function(|_, r#type: mlua::String| {
|
lua.create_function(|_, r#type: mlua::String| {
|
||||||
Ok(Id(match r#type.as_bytes().as_ref() {
|
Ok(Id(match &*r#type.as_bytes() {
|
||||||
b"app" => *yazi_dds::ID,
|
b"app" => *yazi_dds::ID,
|
||||||
b"ft" => yazi_fs::FILES_TICKET.next(),
|
b"ft" => yazi_fs::FILES_TICKET.next(),
|
||||||
_ => Err("Invalid id type".into_lua_err())?,
|
_ => Err("Invalid id type".into_lua_err())?,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use mlua::{Function, IntoLuaMulti, Lua, LuaSerdeExt, Value};
|
use mlua::{Function, IntoLuaMulti, Lua, LuaSerdeExt, Value};
|
||||||
use yazi_binding::Error;
|
use yazi_binding::{Error, SER_OPT};
|
||||||
|
|
||||||
use super::Utils;
|
use super::Utils;
|
||||||
use crate::runtime::SER_OPT;
|
|
||||||
|
|
||||||
impl Utils {
|
impl Utils {
|
||||||
pub(super) fn json_encode(lua: &Lua) -> mlua::Result<Function> {
|
pub(super) fn json_encode(lua: &Lua) -> mlua::Result<Function> {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue