mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
perf: chunk loading for mime-types (#467)
This commit is contained in:
parent
ccb98ac21f
commit
5fb0fceacb
31 changed files with 219 additions and 115 deletions
|
|
@ -112,7 +112,7 @@ impl Adaptor {
|
|||
return Self::X11;
|
||||
}
|
||||
if std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() {
|
||||
return Self::Kitty;
|
||||
return Self::KittyOld;
|
||||
}
|
||||
|
||||
warn!("[Adaptor] Falling back to chafa");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ where
|
|||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
let mut execs = Vec::new();
|
||||
let mut execs = vec![];
|
||||
while let Some(value) = &seq.next_element::<String>()? {
|
||||
execs.push(parse(value).map_err(de::Error::custom)?);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ impl OpenRule {
|
|||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
let mut uses = Vec::new();
|
||||
let mut uses = vec![];
|
||||
while let Some(use_) = seq.next_element::<String>()? {
|
||||
uses.push(use_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,16 @@ impl Pattern {
|
|||
|
||||
#[inline]
|
||||
pub fn match_path(&self, path: impl AsRef<Path>, is_folder: bool) -> bool {
|
||||
if is_folder != self.is_folder {
|
||||
return false;
|
||||
}
|
||||
|
||||
let path = path.as_ref();
|
||||
let s = if self.full_path {
|
||||
path.to_str()
|
||||
self.matches(if self.full_path {
|
||||
path.to_string_lossy()
|
||||
} else {
|
||||
path.file_name().and_then(|n| n.to_str()).or_else(|| path.to_str())
|
||||
};
|
||||
is_folder == self.is_folder && s.is_some_and(|s| self.matches(s))
|
||||
path.file_name().map_or_else(|| path.to_string_lossy(), |n| n.to_string_lossy())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ impl Icon {
|
|||
where
|
||||
A: de::MapAccess<'de>,
|
||||
{
|
||||
let mut icons = Vec::new();
|
||||
let mut icons = vec![];
|
||||
while let Some((key, value)) = &map.next_entry::<String, String>()? {
|
||||
icons.push(Icon {
|
||||
name: Pattern::try_from(key.clone())
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ impl Completion {
|
|||
let ticket = self.ticket;
|
||||
tokio::spawn(async move {
|
||||
let mut dir = fs::read_dir(&parent).await?;
|
||||
let mut cache = Vec::new();
|
||||
let mut cache = vec![];
|
||||
while let Ok(Some(f)) = dir.next_entry().await {
|
||||
let Ok(meta) = f.metadata().await else {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ impl Files {
|
|||
// --- Selected
|
||||
pub fn selected(&self, pending: &BTreeSet<usize>, unset: bool) -> Vec<&File> {
|
||||
if self.selected.is_empty() && (unset || pending.is_empty()) {
|
||||
return Vec::new();
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let selected: BTreeSet<_> = self.selected.iter().collect();
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ impl Manager {
|
|||
|
||||
tokio::spawn(async move {
|
||||
done.extend(todo.iter().map(|f| (f.url(), None)));
|
||||
if let Err(e) = isolate::preload("mime.lua".to_string(), todo, true).await {
|
||||
if let Err(e) = isolate::preload("mime.lua", todo, true).await {
|
||||
error!("preload in watcher failed: {e}");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ impl Manager {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let mut failed = Vec::new();
|
||||
let mut failed = vec![];
|
||||
for (o, n) in todo {
|
||||
if fs::symlink_metadata(&n).await.is_ok() {
|
||||
failed.push((o, n, anyhow!("Destination already exists")));
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ impl Manager {
|
|||
|
||||
fn handle_ioerr(&mut self, op: FilesOp) -> bool {
|
||||
let url = op.url();
|
||||
let op = FilesOp::Full(url.clone(), Vec::new());
|
||||
let op = FilesOp::Full(url.clone(), vec![]);
|
||||
|
||||
if url == self.cwd() {
|
||||
self.current_mut().update(op);
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ impl Watcher {
|
|||
if reload.is_empty() {
|
||||
continue;
|
||||
}
|
||||
if let Err(e) = isolate::preload("mime.lua".to_string(), reload, true).await {
|
||||
if let Err(e) = isolate::preload("mime.lua", reload, true).await {
|
||||
error!("preload in watcher failed: {e}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ impl App {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let mut patches = Vec::new();
|
||||
let mut patches = vec![];
|
||||
for x in frame.area.left()..frame.area.right() {
|
||||
for y in frame.area.top()..frame.area.bottom() {
|
||||
let cell = frame.buffer.get(x, y);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
local M = {}
|
||||
|
||||
function M:peek()
|
||||
local limit = self.area.h
|
||||
local child = Command("jq")
|
||||
:args({
|
||||
"-C",
|
||||
|
|
@ -13,10 +12,17 @@ function M:peek()
|
|||
:stderr(Command.PIPED)
|
||||
:spawn()
|
||||
|
||||
if not child then
|
||||
return self:fallback_to_builtin()
|
||||
end
|
||||
|
||||
local limit = self.area.h
|
||||
local i, lines = 0, ""
|
||||
repeat
|
||||
local code, next = child:read_line()
|
||||
if code ~= 0 then
|
||||
local next, event = child:read_line()
|
||||
if event == 1 then
|
||||
return self:fallback_to_builtin()
|
||||
elseif event ~= 0 then
|
||||
break
|
||||
end
|
||||
|
||||
|
|
@ -46,4 +52,11 @@ function M:seek(units)
|
|||
end
|
||||
end
|
||||
|
||||
function M:fallback_to_builtin()
|
||||
local _, bound = ya.preview_code(self)
|
||||
if bound then
|
||||
ya.manager_emit("peek", { tostring(bound), only_if = tostring(self.file.url), upper_bound = "" })
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -1,35 +1,57 @@
|
|||
local M = {}
|
||||
|
||||
function M:preload()
|
||||
local command = Command("file"):arg("--mime-type"):stdout(Command.PIPED):stderr(Command.PIPED)
|
||||
if ya.target_family() == "windows" then
|
||||
command:arg("-b")
|
||||
else
|
||||
command:arg("-bL")
|
||||
end
|
||||
|
||||
local urls = {}
|
||||
for _, file in ipairs(self.files) do
|
||||
urls[#urls + 1] = tostring(file.url)
|
||||
end
|
||||
|
||||
local i, mimes = 1, {}
|
||||
local output = command:args(urls):output()
|
||||
for line in output.stdout:gmatch("[^\r\n]+") do
|
||||
if i > #urls then
|
||||
break
|
||||
end
|
||||
if ya.mime_valid(line) then
|
||||
mimes[urls[i]] = line
|
||||
end
|
||||
i = i + 1
|
||||
local args
|
||||
if ya.target_family() == "windows" then
|
||||
args = { "-b", "--mime-type" }
|
||||
else
|
||||
args = { "-b", "-L", "--mime-type" }
|
||||
end
|
||||
|
||||
if #mimes then
|
||||
ya.manager_emit("update_mimetype", {}, mimes)
|
||||
return 3
|
||||
local child, code = Command("file"):args(args):args(urls):stdout(Command.PIPED):spawn()
|
||||
if not child then
|
||||
ya.err("spawn `file` command returns " .. tostring(code))
|
||||
return 0
|
||||
end
|
||||
return 2
|
||||
|
||||
local mimes, last = {}, ya.time()
|
||||
local flush = function(force)
|
||||
if not force and ya.time() - last < 0.1 then
|
||||
return
|
||||
end
|
||||
if next(mimes) then
|
||||
ya.manager_emit("update_mimetype", {}, mimes)
|
||||
mimes, last = {}, ya.time()
|
||||
end
|
||||
end
|
||||
|
||||
local i, j = 1, 0
|
||||
repeat
|
||||
local next, event = child:read_line_with { timeout = 100 }
|
||||
if event == 3 then
|
||||
flush(true)
|
||||
goto continue
|
||||
elseif event ~= 0 then
|
||||
break
|
||||
end
|
||||
|
||||
next = next:gsub("[\r\n]+$", "")
|
||||
if ya.mime_valid(next) then
|
||||
j, mimes[urls[i]] = j + 1, next
|
||||
flush(false)
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
::continue::
|
||||
until i > #urls
|
||||
|
||||
flush(true)
|
||||
return j == #urls and 3 or 2
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ function M:preload()
|
|||
:stderr(Command.PIPED)
|
||||
:output()
|
||||
|
||||
if not output.status:success() then
|
||||
if not output then
|
||||
return 0
|
||||
elseif not output.status:success() then
|
||||
local pages = tonumber(output.stderr:match("the last page %((%d+)%)")) or 0
|
||||
if self.skip > 0 and pages > 0 then
|
||||
ya.manager_emit("peek", { tostring(math.max(0, pages - 1)), only_if = tostring(self.file.url), upper_bound = "" })
|
||||
|
|
|
|||
|
|
@ -31,25 +31,27 @@ function M:preload()
|
|||
return 1
|
||||
end
|
||||
|
||||
local status = Command("ffmpegthumbnailer")
|
||||
:args({
|
||||
"-q",
|
||||
"6",
|
||||
"-c",
|
||||
"jpeg",
|
||||
"-i",
|
||||
tostring(self.file.url),
|
||||
"-o",
|
||||
tostring(cache),
|
||||
"-t",
|
||||
tostring(percentage),
|
||||
"-s",
|
||||
tostring(PREVIEW.max_width),
|
||||
})
|
||||
:spawn()
|
||||
:wait()
|
||||
local child = Command("ffmpegthumbnailer"):args({
|
||||
"-q",
|
||||
"6",
|
||||
"-c",
|
||||
"jpeg",
|
||||
"-i",
|
||||
tostring(self.file.url),
|
||||
"-o",
|
||||
tostring(cache),
|
||||
"-t",
|
||||
tostring(percentage),
|
||||
"-s",
|
||||
tostring(PREVIEW.max_width),
|
||||
}):spawn()
|
||||
|
||||
return status:success() and 1 or 2
|
||||
if not child then
|
||||
return 0
|
||||
end
|
||||
|
||||
local status = child:wait()
|
||||
return status and status:success() and 1 or 2
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -32,13 +32,12 @@ impl<'a> TryFrom<Table<'a>> for Line {
|
|||
|
||||
impl Line {
|
||||
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||
#[inline]
|
||||
fn new(value: Value) -> mlua::Result<Line> {
|
||||
let new = lua.create_function(|_, (_, value): (Table, Value)| {
|
||||
if let Value::Table(tbl) = value {
|
||||
return Line::try_from(tbl);
|
||||
}
|
||||
Err("expected a table of Spans or Lines".into_lua_err())
|
||||
}
|
||||
})?;
|
||||
|
||||
let line = lua.create_table_from([
|
||||
// Alignment
|
||||
|
|
@ -47,10 +46,7 @@ impl Line {
|
|||
("RIGHT", RIGHT.into_lua(lua)?),
|
||||
])?;
|
||||
|
||||
line.set_metatable(Some(lua.create_table_from([(
|
||||
"__call",
|
||||
lua.create_function(|_, (_, value): (Table, Value)| new(value))?,
|
||||
)])?));
|
||||
line.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||
|
||||
ui.set("Line", line)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,25 +9,21 @@ pub struct Rect;
|
|||
|
||||
impl Rect {
|
||||
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||
#[inline]
|
||||
fn new<'a>(lua: &'a Lua, args: Table) -> mlua::Result<AnyUserData<'a>> {
|
||||
let new = lua.create_function(|lua, (_, args): (Table, Table)| {
|
||||
Rect::cast(lua, ratatui::layout::Rect {
|
||||
x: args.get("x")?,
|
||||
y: args.get("y")?,
|
||||
width: args.get("w")?,
|
||||
height: args.get("h")?,
|
||||
})
|
||||
}
|
||||
})?;
|
||||
|
||||
let rect = lua.create_table_from([(
|
||||
"default",
|
||||
Rect::cast(lua, ratatui::layout::Rect::default())?.into_lua(lua)?,
|
||||
)])?;
|
||||
|
||||
rect.set_metatable(Some(lua.create_table_from([(
|
||||
"__call",
|
||||
lua.create_function(|lua, (_, args): (Table, Table)| new(lua, args))?,
|
||||
)])?));
|
||||
rect.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||
|
||||
ui.set("Rect", rect)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@ pub struct Style(pub(super) ratatui::style::Style);
|
|||
|
||||
impl Style {
|
||||
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||
ui.set("Style", lua.create_function(|_, ()| Ok(Self::default()))?)
|
||||
let new = lua.create_function(|_, ()| Ok(Self::default()))?;
|
||||
|
||||
let style = lua.create_table()?;
|
||||
style.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||
|
||||
ui.set("Style", style)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
2
yazi-plugin/src/external/shell.rs
vendored
2
yazi-plugin/src/external/shell.rs
vendored
|
|
@ -73,7 +73,7 @@ mod parser {
|
|||
|
||||
pub(super) fn parse(cmd: &str, args: &[&str]) -> Vec<String> {
|
||||
let mut it = cmd.chars().peekable();
|
||||
let mut expanded = Vec::new();
|
||||
let mut expanded = vec![];
|
||||
|
||||
while let Some(c) = it.next() {
|
||||
if c.is_whitespace() {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ use super::slim_lua;
|
|||
use crate::{bindings::{Cast, File}, elements::Rect, LOADED};
|
||||
|
||||
pub async fn preload(
|
||||
name: String,
|
||||
name: &str,
|
||||
files: Vec<yazi_shared::fs::File>,
|
||||
multi: bool,
|
||||
) -> mlua::Result<u8> {
|
||||
LOADED.ensure(&name).await.into_lua_err()?;
|
||||
LOADED.ensure(name).await.into_lua_err()?;
|
||||
|
||||
let name = name.to_owned();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua()?;
|
||||
let plugin: Table = if let Some(b) = LOADED.read().get(&name) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use mlua::{prelude::LuaUserDataMethods, UserData};
|
||||
use std::time::Duration;
|
||||
|
||||
use mlua::{prelude::LuaUserDataMethods, IntoLua, Table, UserData, Value};
|
||||
use tokio::{io::{AsyncBufReadExt, AsyncReadExt, BufReader}, process::{ChildStderr, ChildStdin, ChildStdout}, select};
|
||||
|
||||
use super::Status;
|
||||
|
|
@ -21,27 +23,8 @@ impl Child {
|
|||
|
||||
impl UserData for Child {
|
||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method_mut("read", |_, me, ()| async move {
|
||||
async fn read(t: Option<impl AsyncBufReadExt + Unpin>) -> Option<Vec<u8>> {
|
||||
let Some(mut r) = t else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let mut buf = vec![0; 4096];
|
||||
match r.read(&mut buf).await {
|
||||
Ok(0) | Err(_) => return None,
|
||||
Ok(n) => buf.truncate(n),
|
||||
}
|
||||
Some(buf)
|
||||
}
|
||||
|
||||
Ok(select! {
|
||||
Some(r) = read(me.stdout.as_mut()) => (0u8, r),
|
||||
Some(r) = read(me.stderr.as_mut()) => (1u8, r),
|
||||
else => (2u8, Vec::new())
|
||||
})
|
||||
});
|
||||
methods.add_async_method_mut("read_line", |_, me, ()| async move {
|
||||
#[inline]
|
||||
async fn read_line(me: &mut Child) -> (String, u8) {
|
||||
async fn read(t: Option<impl AsyncBufReadExt + Unpin>) -> Option<String> {
|
||||
let Some(mut r) = t else {
|
||||
return None;
|
||||
|
|
@ -54,15 +37,52 @@ impl UserData for Child {
|
|||
}
|
||||
}
|
||||
|
||||
select! {
|
||||
Some(r) = read(me.stdout.as_mut()) => (r, 0u8),
|
||||
Some(r) = read(me.stderr.as_mut()) => (r, 1u8),
|
||||
else => (String::new(), 2u8),
|
||||
}
|
||||
}
|
||||
|
||||
methods.add_async_method_mut("read", |_, me, len: usize| async move {
|
||||
async fn read(t: Option<impl AsyncBufReadExt + Unpin>, len: usize) -> Option<Vec<u8>> {
|
||||
let Some(mut r) = t else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let mut buf = vec![0; len];
|
||||
match r.read(&mut buf).await {
|
||||
Ok(0) | Err(_) => return None,
|
||||
Ok(n) => buf.truncate(n),
|
||||
}
|
||||
Some(buf)
|
||||
}
|
||||
|
||||
Ok(select! {
|
||||
Some(r) = read(me.stdout.as_mut()) => (0u8, r),
|
||||
Some(r) = read(me.stderr.as_mut()) => (1u8, r),
|
||||
else => (2u8, String::new()),
|
||||
Some(r) = read(me.stdout.as_mut(), len) => (r, 0u8),
|
||||
Some(r) = read(me.stderr.as_mut(), len) => (r, 1u8),
|
||||
else => (vec![], 2u8)
|
||||
})
|
||||
});
|
||||
methods.add_async_method_mut("wait", |_, me, ()| async move {
|
||||
Ok(Status::new(me.inner.wait().await?))
|
||||
methods.add_async_method_mut("read_line", |_, me, ()| async move { Ok(read_line(me).await) });
|
||||
methods.add_async_method_mut("read_line_with", |_, me, options: Table| async move {
|
||||
let timeout: u64 = options.get("timeout")?;
|
||||
match tokio::time::timeout(Duration::from_millis(timeout), read_line(me)).await {
|
||||
Ok(value) => Ok(value),
|
||||
Err(_) => Ok((String::new(), 3u8)),
|
||||
}
|
||||
});
|
||||
methods.add_async_method_mut("wait", |lua, me, ()| async move {
|
||||
Ok(match me.inner.wait().await {
|
||||
Ok(status) => (Status::new(status).into_lua(lua)?, Value::Nil),
|
||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
||||
})
|
||||
});
|
||||
methods.add_method_mut("start_kill", |lua, me, ()| {
|
||||
Ok(match me.inner.start_kill() {
|
||||
Ok(_) => (true, Value::Nil),
|
||||
Err(e) => (false, e.raw_os_error().into_lua(lua)?),
|
||||
})
|
||||
});
|
||||
methods.add_method_mut("start_kill", |_, me, ()| Ok(me.inner.start_kill().is_ok()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::process::Stdio;
|
||||
|
||||
use mlua::{prelude::LuaUserDataMethods, AnyUserData, IntoLua, Lua, Table, UserData};
|
||||
use mlua::{prelude::LuaUserDataMethods, AnyUserData, IntoLua, Lua, Table, UserData, Value};
|
||||
|
||||
use super::{output::Output, Child};
|
||||
|
||||
|
|
@ -72,9 +72,17 @@ impl UserData for Command {
|
|||
});
|
||||
Ok(ud)
|
||||
});
|
||||
methods.add_method_mut("spawn", |_, me, ()| Ok(Child::new(me.inner.spawn()?)));
|
||||
methods.add_async_method_mut("output", |_, me, ()| async move {
|
||||
Ok(Output::new(me.inner.output().await?))
|
||||
methods.add_method_mut("spawn", |lua, me, ()| {
|
||||
Ok(match me.inner.spawn() {
|
||||
Ok(child) => (Child::new(child).into_lua(lua)?, Value::Nil),
|
||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
||||
})
|
||||
});
|
||||
methods.add_async_method_mut("output", |lua, me, ()| async move {
|
||||
Ok(match me.inner.output().await {
|
||||
Ok(output) => (Output::new(output).into_lua(lua)?, Value::Nil),
|
||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::ValueSendable;
|
|||
|
||||
impl Utils {
|
||||
fn parse_args(t: Table) -> mlua::Result<(Vec<String>, BTreeMap<String, String>)> {
|
||||
let mut args = Vec::new();
|
||||
let mut args = vec![];
|
||||
let mut named = BTreeMap::new();
|
||||
for result in t.pairs::<Value, Value>() {
|
||||
let (k, Value::String(v)) = result? else {
|
||||
|
|
|
|||
14
yazi-plugin/src/utils/log.rs
Normal file
14
yazi-plugin/src/utils/log.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use mlua::{Lua, Table};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use super::Utils;
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn log(lua: &Lua, ya: &Table) -> mlua::Result<()> {
|
||||
ya.set("dbg", lua.create_async_function(|_, s: String| async move { Ok(debug!("{s}")) })?)?;
|
||||
|
||||
ya.set("err", lua.create_async_function(|_, s: String| async move { Ok(error!("{s}")) })?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,12 @@
|
|||
mod cache;
|
||||
mod call;
|
||||
mod image;
|
||||
mod log;
|
||||
mod plugin;
|
||||
mod preview;
|
||||
mod target;
|
||||
mod text;
|
||||
mod time;
|
||||
mod utils;
|
||||
|
||||
pub use preview::*;
|
||||
|
|
|
|||
18
yazi-plugin/src/utils/time.rs
Normal file
18
yazi-plugin/src/utils/time.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use mlua::{Lua, Table};
|
||||
|
||||
use super::Utils;
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn time(lua: &Lua, ya: &Table) -> mlua::Result<()> {
|
||||
ya.set(
|
||||
"time",
|
||||
lua.create_function(|_, ()| {
|
||||
Ok(SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())
|
||||
})?,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,11 @@ pub fn install(lua: &Lua) -> mlua::Result<()> {
|
|||
Utils::cache(lua, &ya)?;
|
||||
Utils::call(lua, &ya)?;
|
||||
Utils::image(lua, &ya)?;
|
||||
Utils::log(lua, &ya)?;
|
||||
Utils::plugin(lua, &ya)?;
|
||||
Utils::preview(lua, &ya)?;
|
||||
Utils::target(lua, &ya)?;
|
||||
Utils::time(lua, &ya)?;
|
||||
Utils::text(lua, &ya)?;
|
||||
|
||||
lua.globals().set("ya", ya)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ impl Preload {
|
|||
match op {
|
||||
PreloadOp::Rule(task) => {
|
||||
let urls: Vec<_> = task.targets.iter().map(|f| f.url()).collect();
|
||||
let result = isolate::preload(task.plugin.cmd, task.targets, task.plugin.multi).await;
|
||||
let result = isolate::preload(&task.plugin.cmd, task.targets, task.plugin.multi).await;
|
||||
if let Err(e) = result {
|
||||
self.fail(task.id, format!("Preload task failed:\n{e}"))?;
|
||||
return Err(e.into());
|
||||
|
|
@ -39,7 +39,7 @@ impl Preload {
|
|||
|
||||
let code = result.unwrap();
|
||||
if code & 1 == 0 {
|
||||
error!("Preload task returned {code}");
|
||||
error!("Preload task `{}` returned {code}", task.plugin.cmd);
|
||||
}
|
||||
if code >> 1 & 1 != 0 {
|
||||
let mut loaded = self.rule_loaded.write();
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ impl<'de> Deserialize<'de> for Condition {
|
|||
|
||||
impl Condition {
|
||||
fn build(expr: &str) -> Self {
|
||||
let mut stack: Vec<ConditionOp> = Vec::new();
|
||||
let mut output: Vec<ConditionOp> = Vec::new();
|
||||
let mut stack: Vec<ConditionOp> = vec![];
|
||||
let mut output: Vec<ConditionOp> = vec![];
|
||||
|
||||
let mut chars = expr.chars().peekable();
|
||||
while let Some(token) = chars.next() {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl FilesOp {
|
|||
|
||||
pub fn prepare(url: &Url) -> u64 {
|
||||
let ticket = FILES_TICKET.fetch_add(1, Ordering::Relaxed);
|
||||
Self::Part(url.clone(), Vec::new(), ticket).emit();
|
||||
Self::Part(url.clone(), vec![], ticket).emit();
|
||||
ticket
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue