mirror of
https://github.com/sxyazi/yazi.git
synced 2024-10-05 14:47:19 +03:00
feat: add a next
property to the preloader rules to allow running multiple preloaders (#1058)
This commit is contained in:
parent
0ff4835f8d
commit
c2affae3a9
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -120,9 +120,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.83"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
@ -1086,9 +1086,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.154"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
@ -2924,6 +2924,7 @@ dependencies = [
|
||||
"ratatui",
|
||||
"regex",
|
||||
"serde",
|
||||
"shell-words",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
12
flake.lock
12
flake.lock
@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1713805509,
|
||||
"narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=",
|
||||
"lastModified": 1716097317,
|
||||
"narHash": "sha256-1UMrLtgzielG/Sop6gl6oTSM4pDt7rF9j9VuxhDWDlY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4",
|
||||
"rev": "8535fb92661f37ff9f0da3007fbc942f7d134b41",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -51,11 +51,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1713924823,
|
||||
"narHash": "sha256-kOeyS3GFwgnKvzuBMmFqEAX0xwZ7Nj4/5tXuvpZ0d4U=",
|
||||
"lastModified": 1716085073,
|
||||
"narHash": "sha256-3+9gI93XxszWA2+9S2xZfws1QArPX/MC6nahOGpcMB4=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "8a2edac3ae926a2a6ce60f4595dcc4540fc8cad4",
|
||||
"rev": "cfc8776011bd83508324115d353222475e1601c0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -13,7 +13,7 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
arc-swap = "1.7.1"
|
||||
base64 = "0.22.1"
|
||||
color_quant = "1.1.0"
|
||||
|
@ -13,7 +13,7 @@ yazi-dds = { path = "../yazi-dds", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
clap = { version = "4.5.4", features = [ "derive" ] }
|
||||
crossterm = "0.27.0"
|
||||
md-5 = "0.10.6"
|
||||
@ -22,7 +22,7 @@ tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
toml_edit = "0.22.13"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
clap = { version = "4.5.4", features = [ "derive" ] }
|
||||
clap_complete = "4.5.2"
|
||||
clap_complete_fig = "4.5.0"
|
||||
|
@ -12,7 +12,7 @@ repository = "https://github.com/sxyazi/yazi"
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
arc-swap = "1.7.1"
|
||||
crossterm = "0.27.0"
|
||||
globset = "0.4.14"
|
||||
|
@ -80,7 +80,7 @@ suppress_preload = false
|
||||
[plugin]
|
||||
|
||||
preloaders = [
|
||||
{ name = "*", cond = "!mime", run = "mime", multi = true, prio = "high" },
|
||||
{ name = "*", cond = "!mime", run = "mime", next = true, multi = true, prio = "high" },
|
||||
# Image
|
||||
{ mime = "image/svg+xml", run = "magick" },
|
||||
{ mime = "image/heic", run = "magick" },
|
||||
|
@ -23,10 +23,10 @@ impl Open {
|
||||
P: AsRef<Path>,
|
||||
M: AsRef<str>,
|
||||
{
|
||||
let is_folder = mime.as_ref() == MIME_DIR;
|
||||
let is_dir = mime.as_ref() == MIME_DIR;
|
||||
self.rules.iter().find_map(|rule| {
|
||||
if rule.mime.as_ref().is_some_and(|p| p.match_mime(&mime))
|
||||
|| rule.name.as_ref().is_some_and(|p| p.match_path(&path, is_folder))
|
||||
|| rule.name.as_ref().is_some_and(|p| p.match_path(&path, is_dir))
|
||||
{
|
||||
let openers = rule
|
||||
.use_
|
||||
|
@ -7,8 +7,8 @@ use serde::Deserialize;
|
||||
#[serde(try_from = "String")]
|
||||
pub struct Pattern {
|
||||
inner: globset::GlobMatcher,
|
||||
is_dir: bool,
|
||||
is_star: bool,
|
||||
is_folder: bool,
|
||||
}
|
||||
|
||||
impl Pattern {
|
||||
@ -16,15 +16,15 @@ impl Pattern {
|
||||
pub fn match_mime(&self, str: impl AsRef<str>) -> bool { self.inner.is_match(str.as_ref()) }
|
||||
|
||||
#[inline]
|
||||
pub fn match_path(&self, path: impl AsRef<Path>, is_folder: bool) -> bool {
|
||||
is_folder == self.is_folder && (self.is_star || self.inner.is_match(path))
|
||||
pub fn match_path(&self, path: impl AsRef<Path>, is_dir: bool) -> bool {
|
||||
is_dir == self.is_dir && (self.is_star || self.inner.is_match(path))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn any_file(&self) -> bool { self.is_star && !self.is_folder }
|
||||
pub fn any_file(&self) -> bool { self.is_star && !self.is_dir }
|
||||
|
||||
#[inline]
|
||||
pub fn any_dir(&self) -> bool { self.is_star && self.is_folder }
|
||||
pub fn any_dir(&self) -> bool { self.is_star && self.is_dir }
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for Pattern {
|
||||
@ -42,7 +42,7 @@ impl TryFrom<&str> for Pattern {
|
||||
.build()?
|
||||
.compile_matcher();
|
||||
|
||||
Ok(Self { inner, is_star: b == "*", is_folder: b.len() < a.len() })
|
||||
Ok(Self { inner, is_dir: b.len() < a.len(), is_star: b == "*" })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
mod plugin;
|
||||
mod props;
|
||||
mod rule;
|
||||
mod run;
|
||||
mod preloader;
|
||||
mod previewer;
|
||||
|
||||
pub use plugin::*;
|
||||
pub use props::*;
|
||||
pub use rule::*;
|
||||
#[allow(unused_imports)]
|
||||
pub use run::*;
|
||||
pub use preloader::*;
|
||||
pub use previewer::*;
|
||||
|
||||
pub const MAX_PRELOADERS: u8 = 32;
|
||||
|
@ -3,13 +3,13 @@ use std::path::Path;
|
||||
use serde::Deserialize;
|
||||
use yazi_shared::MIME_DIR;
|
||||
|
||||
use super::PluginRule;
|
||||
use super::{Preloader, Previewer};
|
||||
use crate::{plugin::MAX_PRELOADERS, Preset, MERGED_YAZI};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Plugin {
|
||||
pub preloaders: Vec<PluginRule>,
|
||||
pub previewers: Vec<PluginRule>,
|
||||
pub preloaders: Vec<Preloader>,
|
||||
pub previewers: Vec<Previewer>,
|
||||
}
|
||||
|
||||
impl Default for Plugin {
|
||||
@ -21,17 +21,17 @@ impl Default for Plugin {
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Shadow {
|
||||
preloaders: Vec<PluginRule>,
|
||||
preloaders: Vec<Preloader>,
|
||||
#[serde(default)]
|
||||
prepend_preloaders: Vec<PluginRule>,
|
||||
prepend_preloaders: Vec<Preloader>,
|
||||
#[serde(default)]
|
||||
append_preloaders: Vec<PluginRule>,
|
||||
append_preloaders: Vec<Preloader>,
|
||||
|
||||
previewers: Vec<PluginRule>,
|
||||
previewers: Vec<Previewer>,
|
||||
#[serde(default)]
|
||||
prepend_previewers: Vec<PluginRule>,
|
||||
prepend_previewers: Vec<Previewer>,
|
||||
#[serde(default)]
|
||||
append_previewers: Vec<PluginRule>,
|
||||
append_previewers: Vec<Previewer>,
|
||||
}
|
||||
|
||||
let mut shadow = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().plugin;
|
||||
@ -50,9 +50,6 @@ impl Default for Plugin {
|
||||
}
|
||||
|
||||
for (i, preloader) in shadow.preloaders.iter_mut().enumerate() {
|
||||
if preloader.sync {
|
||||
panic!("Preloaders cannot be synchronous");
|
||||
}
|
||||
preloader.id = i as u8;
|
||||
}
|
||||
|
||||
@ -66,24 +63,34 @@ impl Plugin {
|
||||
path: &Path,
|
||||
mime: Option<&str>,
|
||||
f: impl Fn(&str) -> bool + Copy,
|
||||
) -> Vec<&PluginRule> {
|
||||
let is_folder = mime == Some(MIME_DIR);
|
||||
self
|
||||
.preloaders
|
||||
.iter()
|
||||
.filter(|&rule| {
|
||||
rule.cond.as_ref().and_then(|c| c.eval(f)) != Some(false)
|
||||
&& (rule.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
|
||||
|| rule.name.as_ref().is_some_and(|p| p.match_path(path, is_folder)))
|
||||
})
|
||||
.collect()
|
||||
) -> Vec<&Preloader> {
|
||||
let is_dir = mime == Some(MIME_DIR);
|
||||
let mut preloaders = Vec::with_capacity(1);
|
||||
|
||||
for p in &self.preloaders {
|
||||
if p.cond.as_ref().and_then(|c| c.eval(f)) == Some(false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pub fn previewer(&self, path: &Path, mime: &str) -> Option<&PluginRule> {
|
||||
let is_folder = mime == MIME_DIR;
|
||||
self.previewers.iter().find(|&rule| {
|
||||
rule.mime.as_ref().is_some_and(|p| p.match_mime(mime))
|
||||
|| rule.name.as_ref().is_some_and(|p| p.match_path(path, is_folder))
|
||||
if !p.mime.as_ref().zip(mime).map_or(false, |(p, m)| p.match_mime(m))
|
||||
&& !p.name.as_ref().is_some_and(|p| p.match_path(path, is_dir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
preloaders.push(p);
|
||||
if !p.next {
|
||||
break;
|
||||
}
|
||||
}
|
||||
preloaders
|
||||
}
|
||||
|
||||
pub fn previewer(&self, path: &Path, mime: &str) -> Option<&Previewer> {
|
||||
let is_dir = mime == MIME_DIR;
|
||||
self.previewers.iter().find(|&p| {
|
||||
p.mime.as_ref().is_some_and(|p| p.match_mime(mime))
|
||||
|| p.name.as_ref().is_some_and(|p| p.match_path(path, is_dir))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
39
yazi-config/src/plugin/preloader.rs
Normal file
39
yazi-config/src/plugin/preloader.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use serde::Deserialize;
|
||||
use yazi_shared::{event::Cmd, Condition};
|
||||
|
||||
use crate::{Pattern, Priority};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Preloader {
|
||||
#[serde(skip)]
|
||||
pub id: u8,
|
||||
pub cond: Option<Condition>,
|
||||
pub name: Option<Pattern>,
|
||||
pub mime: Option<Pattern>,
|
||||
pub run: Cmd,
|
||||
#[serde(default)]
|
||||
pub next: bool,
|
||||
#[serde(default)]
|
||||
pub multi: bool,
|
||||
#[serde(default)]
|
||||
pub prio: Priority,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PreloaderProps {
|
||||
pub id: u8,
|
||||
pub name: String,
|
||||
pub multi: bool,
|
||||
pub prio: Priority,
|
||||
}
|
||||
|
||||
impl From<&Preloader> for PreloaderProps {
|
||||
fn from(preloader: &Preloader) -> Self {
|
||||
Self {
|
||||
id: preloader.id,
|
||||
name: preloader.run.name.to_owned(),
|
||||
multi: preloader.multi,
|
||||
prio: preloader.prio,
|
||||
}
|
||||
}
|
||||
}
|
21
yazi-config/src/plugin/previewer.rs
Normal file
21
yazi-config/src/plugin/previewer.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use serde::Deserialize;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::Pattern;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Previewer {
|
||||
pub name: Option<Pattern>,
|
||||
pub mime: Option<Pattern>,
|
||||
pub run: Cmd,
|
||||
#[serde(default)]
|
||||
pub sync: bool,
|
||||
}
|
||||
|
||||
impl Previewer {
|
||||
#[inline]
|
||||
pub fn any_file(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_file()) }
|
||||
|
||||
#[inline]
|
||||
pub fn any_dir(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_dir()) }
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
use super::PluginRule;
|
||||
use crate::Priority;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PluginProps {
|
||||
pub id: u8,
|
||||
pub name: String,
|
||||
pub multi: bool,
|
||||
pub prio: Priority,
|
||||
}
|
||||
|
||||
impl From<&PluginRule> for PluginProps {
|
||||
fn from(rule: &PluginRule) -> Self {
|
||||
Self { id: rule.id, name: rule.run.name.to_owned(), multi: rule.multi, prio: rule.prio }
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
use serde::Deserialize;
|
||||
use yazi_shared::{event::Cmd, Condition};
|
||||
|
||||
use crate::{Pattern, Priority};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct PluginRule {
|
||||
#[serde(skip)]
|
||||
pub id: u8,
|
||||
pub cond: Option<Condition>,
|
||||
pub name: Option<Pattern>,
|
||||
pub mime: Option<Pattern>,
|
||||
#[serde(deserialize_with = "super::run_deserialize")]
|
||||
pub run: Cmd,
|
||||
#[serde(default)]
|
||||
pub sync: bool,
|
||||
#[serde(default)]
|
||||
pub multi: bool,
|
||||
#[serde(default)]
|
||||
pub prio: Priority,
|
||||
}
|
||||
|
||||
impl PluginRule {
|
||||
#[inline]
|
||||
pub fn any_file(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_file()) }
|
||||
|
||||
#[inline]
|
||||
pub fn any_dir(&self) -> bool { self.name.as_ref().is_some_and(|p| p.any_dir()) }
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
use std::fmt;
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::{de::{self, Visitor}, Deserializer};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub(super) fn run_deserialize<'de, D>(deserializer: D) -> Result<Cmd, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct RunVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for RunVisitor {
|
||||
type Value = Cmd;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a `run` string or array of strings")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, _: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
Err(de::Error::custom("`run` within [plugin] must be a string"))
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
if value.is_empty() {
|
||||
return Err(de::Error::custom("`run` within [plugin] cannot be empty"));
|
||||
}
|
||||
Ok(Cmd { name: value.to_owned(), ..Default::default() })
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(RunVisitor)
|
||||
}
|
@ -19,7 +19,7 @@ yazi-scheduler = { path = "../yazi-scheduler", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
bitflags = "2.5.0"
|
||||
crossterm = "0.27.0"
|
||||
futures = "0.3.30"
|
||||
@ -39,4 +39,4 @@ shell-words = "1.1.0"
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = "0.2.154"
|
||||
libc = "0.2.155"
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{collections::HashMap, mem};
|
||||
|
||||
use yazi_config::{manager::SortBy, plugin::{PluginRule, MAX_PRELOADERS}, PLUGIN};
|
||||
use yazi_config::{manager::SortBy, plugin::{Preloader, MAX_PRELOADERS}, PLUGIN};
|
||||
use yazi_shared::{fs::{File, Url}, MIME_DIR};
|
||||
|
||||
use super::Tasks;
|
||||
@ -34,15 +34,15 @@ impl Tasks {
|
||||
drop(loaded);
|
||||
let mut loaded = self.scheduler.preload.rule_loaded.write();
|
||||
|
||||
let mut go = |rule: &PluginRule, targets: Vec<&File>| {
|
||||
let mut go = |preloader: &Preloader, targets: Vec<&File>| {
|
||||
for &f in &targets {
|
||||
if let Some(n) = loaded.get_mut(&f.url) {
|
||||
*n |= 1 << rule.id;
|
||||
*n |= 1 << preloader.id;
|
||||
} else {
|
||||
loaded.insert(f.url.clone(), 1 << rule.id);
|
||||
loaded.insert(f.url.clone(), 1 << preloader.id);
|
||||
}
|
||||
}
|
||||
self.scheduler.preload_paged(rule, targets);
|
||||
self.scheduler.preload_paged(preloader, targets);
|
||||
};
|
||||
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
|
@ -17,7 +17,7 @@ yazi-boot = { path = "../yazi-boot", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
mlua = { version = "0.9.8", features = [ "lua54" ] }
|
||||
parking_lot = "0.12.2"
|
||||
serde = { version = "1.0.202", features = [ "derive" ] }
|
||||
|
@ -23,7 +23,7 @@ yazi-proxy = { path = "../yazi-proxy", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
better-panic = "0.3.0"
|
||||
crossterm = { version = "0.27.0", features = [ "event-stream" ] }
|
||||
fdlimit = "0.3.0"
|
||||
@ -41,7 +41,7 @@ tracing-appender = "0.2.3"
|
||||
tracing-subscriber = "0.3.18"
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = "0.2.154"
|
||||
libc = "0.2.155"
|
||||
signal-hook-tokio = { version = "0.3.1", features = [ "futures-v0_3" ] }
|
||||
|
||||
[target.'cfg(all(not(target_os = "macos"), not(target_os = "windows")))'.dependencies]
|
||||
|
@ -22,7 +22,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
ansi-to-tui = "3.1.0"
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
base64 = "0.22.1"
|
||||
crossterm = "0.27.0"
|
||||
futures = "0.3.30"
|
||||
|
@ -50,10 +50,12 @@ end
|
||||
|
||||
local function entry()
|
||||
local st = state()
|
||||
if st.empty == true then
|
||||
return fail("No directory history in the database, check out the `zoxide` docs to set it up.")
|
||||
elseif st.empty == nil and head(st.cwd) < 2 then
|
||||
set_state(true)
|
||||
if st.empty == nil then
|
||||
st.empty = head(st.cwd) < 2
|
||||
set_state(st.empty)
|
||||
end
|
||||
|
||||
if st.empty then
|
||||
return fail("No directory history in the database, check out the `zoxide` docs to set it up.")
|
||||
end
|
||||
|
||||
|
@ -17,6 +17,6 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
mlua = { version = "0.9.8", features = [ "lua54" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
|
@ -16,7 +16,7 @@ yazi-proxy = { path = "../yazi-proxy", version = "0.2.5" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
async-priority-channel = "0.2.0"
|
||||
futures = "0.3.30"
|
||||
parking_lot = "0.12.2"
|
||||
@ -27,7 +27,7 @@ tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = "0.2.154"
|
||||
libc = "0.2.155"
|
||||
|
||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||
trash = "4.1.1"
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use yazi_config::plugin::PluginProps;
|
||||
use yazi_config::plugin::PreloaderProps;
|
||||
use yazi_shared::{fs::Url, Throttle};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -21,7 +21,7 @@ impl PreloadOp {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PreloadOpRule {
|
||||
pub id: usize,
|
||||
pub plugin: PluginProps,
|
||||
pub plugin: PreloaderProps,
|
||||
pub targets: Vec<yazi_shared::fs::File>,
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||
use futures::{future::BoxFuture, FutureExt};
|
||||
use parking_lot::Mutex;
|
||||
use tokio::{fs, select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}, task::JoinHandle};
|
||||
use yazi_config::{open::Opener, plugin::PluginRule, TASKS};
|
||||
use yazi_config::{open::Opener, plugin::Preloader, TASKS};
|
||||
use yazi_dds::Pump;
|
||||
use yazi_shared::{event::Data, fs::{unique_path, Url}, Throttle};
|
||||
|
||||
@ -218,13 +218,13 @@ impl Scheduler {
|
||||
self.plugin.macro_(PluginOpEntry { id, name, args }).ok();
|
||||
}
|
||||
|
||||
pub fn preload_paged(&self, rule: &PluginRule, targets: Vec<&yazi_shared::fs::File>) {
|
||||
pub fn preload_paged(&self, preloader: &Preloader, targets: Vec<&yazi_shared::fs::File>) {
|
||||
let id = self.ongoing.lock().add(
|
||||
TaskKind::Preload,
|
||||
format!("Run preloader `{}` with {} target(s)", rule.run.name, targets.len()),
|
||||
format!("Run preloader `{}` with {} target(s)", preloader.run.name, targets.len()),
|
||||
);
|
||||
|
||||
let plugin = rule.into();
|
||||
let plugin = preloader.into();
|
||||
let targets = targets.into_iter().cloned().collect();
|
||||
let preload = self.preload.clone();
|
||||
_ = self.micro.try_send(
|
||||
|
@ -7,9 +7,10 @@ authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
description = "Yazi shared library"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
rust-version = "1.78.0"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
bitflags = "2.5.0"
|
||||
crossterm = "0.27.0"
|
||||
dirs = "5.0.1"
|
||||
@ -20,10 +21,11 @@ percent-encoding = "2.3.1"
|
||||
ratatui = "=0.26.1"
|
||||
regex = "1.10.4"
|
||||
serde = { version = "1.0.202", features = [ "derive" ] }
|
||||
shell-words = "1.1.0"
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
|
||||
# Logging
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = "0.2.154"
|
||||
libc = "0.2.155"
|
||||
|
@ -1,4 +1,7 @@
|
||||
use std::{any::Any, collections::HashMap, fmt::{self, Display}};
|
||||
use std::{any::Any, collections::HashMap, fmt::{self, Display}, mem, str::FromStr};
|
||||
|
||||
use anyhow::bail;
|
||||
use serde::{de, Deserialize};
|
||||
|
||||
use super::Data;
|
||||
|
||||
@ -112,3 +115,46 @@ impl Display for Cmd {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Cmd {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
#[allow(clippy::explicit_counter_loop)]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut args = shell_words::split(s)?;
|
||||
if args.is_empty() || args[0].is_empty() {
|
||||
bail!("command name cannot be empty");
|
||||
}
|
||||
|
||||
let mut cmd = Cmd { name: mem::take(&mut args[0]), ..Default::default() };
|
||||
let mut i = 0usize;
|
||||
for arg in args.into_iter().skip(1) {
|
||||
let Some(arg) = arg.strip_prefix("--") else {
|
||||
cmd.args.insert(i.to_string(), Data::String(arg));
|
||||
i += 1;
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let Some(key) = parts.next().map(|s| s.to_owned()) else {
|
||||
bail!("invalid argument: {arg}");
|
||||
};
|
||||
|
||||
if let Some(val) = parts.next() {
|
||||
cmd.args.insert(key, Data::String(val.to_owned()));
|
||||
} else {
|
||||
cmd.args.insert(key, Data::Boolean(true));
|
||||
}
|
||||
}
|
||||
Ok(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Cmd {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
<_>::from_str(&String::deserialize(deserializer)?).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +61,7 @@ impl From<Metadata> for Cha {
|
||||
kind: ck,
|
||||
len: m.len(),
|
||||
accessed: m.accessed().ok(),
|
||||
// TODO: remove this once https://github.com/rust-lang/rust/issues/108277 is fixed.
|
||||
created: None,
|
||||
created: m.created().ok(),
|
||||
modified: m.modified().ok(),
|
||||
|
||||
#[cfg(unix)]
|
||||
|
Loading…
Reference in New Issue
Block a user