mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
perf: introduce copy-on-write for event system to eliminate all memory reallocations
This commit is contained in:
parent
5e48df5126
commit
1f0817080e
8 changed files with 37 additions and 37 deletions
|
|
@ -21,7 +21,7 @@ impl<'a> Input<'a> {
|
||||||
bail!("Highlighting is disabled");
|
bail!("Highlighting is disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
let (theme, syntaxes) = Highlighter::init();
|
let (theme, syntaxes) = futures::executor::block_on(Highlighter::init());
|
||||||
if let Some(syntax) = syntaxes.find_syntax_by_name("Bourne Again Shell (bash)") {
|
if let Some(syntax) = syntaxes.find_syntax_by_name("Bourne Again Shell (bash)") {
|
||||||
let mut h = HighlightLines::new(syntax, theme);
|
let mut h = HighlightLines::new(syntax, theme);
|
||||||
let regions = h.highlight_line(self.cx.input.value(), syntaxes)?;
|
let regions = h.highlight_line(self.cx.input.value(), syntaxes)?;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ function M:preload()
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local child, err = Command("magick"):args({
|
local status, err = Command("magick"):args({
|
||||||
"-size",
|
"-size",
|
||||||
"800x560",
|
"800x560",
|
||||||
"-gravity",
|
"-gravity",
|
||||||
|
|
@ -37,15 +37,14 @@ function M:preload()
|
||||||
"+0+0",
|
"+0+0",
|
||||||
TEXT,
|
TEXT,
|
||||||
"JPG:" .. tostring(cache),
|
"JPG:" .. tostring(cache),
|
||||||
}):spawn()
|
}):status()
|
||||||
|
|
||||||
if not child then
|
if status then
|
||||||
|
return status.success and 1 or 2
|
||||||
|
else
|
||||||
ya.err("Failed to start `magick`, error: " .. err)
|
ya.err("Failed to start `magick`, error: " .. err)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local status = child:wait()
|
|
||||||
return status and status.success and 1 or 2
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ function M:preload()
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local child, err = Command("magick"):args({
|
local status, err = Command("magick"):args({
|
||||||
"-density",
|
"-density",
|
||||||
"200",
|
"200",
|
||||||
tostring(self.file.url),
|
tostring(self.file.url),
|
||||||
|
|
@ -30,15 +30,14 @@ function M:preload()
|
||||||
tostring(PREVIEW.image_quality),
|
tostring(PREVIEW.image_quality),
|
||||||
"-auto-orient",
|
"-auto-orient",
|
||||||
"JPG:" .. tostring(cache),
|
"JPG:" .. tostring(cache),
|
||||||
}):spawn()
|
}):status()
|
||||||
|
|
||||||
if not child then
|
if status then
|
||||||
|
return status.success and 1 or 2
|
||||||
|
else
|
||||||
ya.err("Failed to start `magick`, error: " .. err)
|
ya.err("Failed to start `magick`, error: " .. err)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local status = child:wait()
|
|
||||||
return status and status.success and 1 or 2
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot(job) require("file"):spot(job) end
|
function M:spot(job) require("file"):spot(job) end
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ function M:preload()
|
||||||
local ss = math.floor(meta.format.duration * percent / 100)
|
local ss = math.floor(meta.format.duration * percent / 100)
|
||||||
local qv = 31 - math.floor(PREVIEW.image_quality * 0.3)
|
local qv = 31 - math.floor(PREVIEW.image_quality * 0.3)
|
||||||
-- stylua: ignore
|
-- stylua: ignore
|
||||||
local child, err = Command("ffmpeg"):args({
|
local status, err = Command("ffmpeg"):args({
|
||||||
"-v", "quiet", "-hwaccel", "auto",
|
"-v", "quiet", "-hwaccel", "auto",
|
||||||
"-skip_frame", "nokey", "-ss", ss,
|
"-skip_frame", "nokey", "-ss", ss,
|
||||||
"-an", "-sn", "-dn",
|
"-an", "-sn", "-dn",
|
||||||
|
|
@ -59,15 +59,14 @@ function M:preload()
|
||||||
"-vf", string.format("scale=%d:-2:flags=fast_bilinear", PREVIEW.max_width),
|
"-vf", string.format("scale=%d:-2:flags=fast_bilinear", PREVIEW.max_width),
|
||||||
"-f", "image2",
|
"-f", "image2",
|
||||||
"-y", tostring(cache),
|
"-y", tostring(cache),
|
||||||
}):spawn()
|
}):status()
|
||||||
|
|
||||||
if not child then
|
if status then
|
||||||
|
return status.success and 1 or 2
|
||||||
|
else
|
||||||
ya.err("Failed to start `ffmpeg`, error: " .. err)
|
ya.err("Failed to start `ffmpeg`, error: " .. err)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local status = child:wait()
|
|
||||||
return status and status.success and 1 or 2
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot(job)
|
function M:spot(job)
|
||||||
|
|
|
||||||
21
yazi-plugin/src/external/highlighter.rs
vendored
21
yazi-plugin/src/external/highlighter.rs
vendored
|
|
@ -1,14 +1,14 @@
|
||||||
use std::{borrow::Cow, io::Cursor, mem, path::{Path, PathBuf}, sync::OnceLock};
|
use std::{borrow::Cow, io::Cursor, mem, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use ratatui::{layout::Size, text::{Line, Span, Text}};
|
use ratatui::{layout::Size, text::{Line, Span, Text}};
|
||||||
use syntect::{LoadingError, dumps, easy::HighlightLines, highlighting::{self, Theme, ThemeSet}, parsing::{SyntaxReference, SyntaxSet}};
|
use syntect::{LoadingError, dumps, easy::HighlightLines, highlighting::{self, Theme, ThemeSet}, parsing::{SyntaxReference, SyntaxSet}};
|
||||||
use tokio::{fs::File, io::{AsyncBufReadExt, BufReader}};
|
use tokio::{fs::File, io::{AsyncBufReadExt, BufReader}, sync::OnceCell};
|
||||||
use yazi_config::{PREVIEW, THEME, preview::PreviewWrap};
|
use yazi_config::{PREVIEW, THEME, preview::PreviewWrap};
|
||||||
use yazi_shared::{Ids, errors::PeekError, replace_to_printable};
|
use yazi_shared::{Ids, errors::PeekError, replace_to_printable};
|
||||||
|
|
||||||
static INCR: Ids = Ids::new();
|
static INCR: Ids = Ids::new();
|
||||||
static SYNTECT: OnceLock<(Theme, SyntaxSet)> = OnceLock::new();
|
static SYNTECT: OnceCell<(Theme, SyntaxSet)> = OnceCell::const_new();
|
||||||
|
|
||||||
pub struct Highlighter {
|
pub struct Highlighter {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
|
@ -18,8 +18,9 @@ impl Highlighter {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(path: &Path) -> Self { Self { path: path.to_owned() } }
|
pub fn new(path: &Path) -> Self { Self { path: path.to_owned() } }
|
||||||
|
|
||||||
pub fn init() -> (&'static Theme, &'static SyntaxSet) {
|
pub async fn init() -> (&'static Theme, &'static SyntaxSet) {
|
||||||
let r = SYNTECT.get_or_init(|| {
|
let f = || {
|
||||||
|
tokio::task::spawn_blocking(|| {
|
||||||
let theme = std::fs::File::open(&THEME.manager.syntect_theme)
|
let theme = std::fs::File::open(&THEME.manager.syntect_theme)
|
||||||
.map_err(LoadingError::Io)
|
.map_err(LoadingError::Io)
|
||||||
.and_then(|f| ThemeSet::load_from_reader(&mut std::io::BufReader::new(f)))
|
.and_then(|f| ThemeSet::load_from_reader(&mut std::io::BufReader::new(f)))
|
||||||
|
|
@ -28,9 +29,11 @@ impl Highlighter {
|
||||||
let syntaxes = dumps::from_uncompressed_data(yazi_prebuild::syntaxes());
|
let syntaxes = dumps::from_uncompressed_data(yazi_prebuild::syntaxes());
|
||||||
|
|
||||||
(theme.unwrap(), syntaxes.unwrap())
|
(theme.unwrap(), syntaxes.unwrap())
|
||||||
});
|
})
|
||||||
|
};
|
||||||
|
|
||||||
(&r.0, &r.1)
|
let (theme, syntaxes) = SYNTECT.get_or_try_init(f).await.unwrap();
|
||||||
|
(theme, syntaxes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -100,7 +103,7 @@ impl Highlighter {
|
||||||
syntax: &'static SyntaxReference,
|
syntax: &'static SyntaxReference,
|
||||||
) -> Result<Text<'static>, PeekError> {
|
) -> Result<Text<'static>, PeekError> {
|
||||||
let ticket = INCR.current();
|
let ticket = INCR.current();
|
||||||
let (theme, syntaxes) = Self::init();
|
let (theme, syntaxes) = Self::init().await;
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let mut h = HighlightLines::new(syntax, theme);
|
let mut h = HighlightLines::new(syntax, theme);
|
||||||
|
|
@ -128,7 +131,7 @@ impl Highlighter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_syntax(path: &Path) -> Result<&'static SyntaxReference> {
|
async fn find_syntax(path: &Path) -> Result<&'static SyntaxReference> {
|
||||||
let (_, syntaxes) = Self::init();
|
let (_, syntaxes) = Self::init().await;
|
||||||
let name = path.file_name().map(|n| n.to_string_lossy()).unwrap_or_default();
|
let name = path.file_name().map(|n| n.to_string_lossy()).unwrap_or_default();
|
||||||
if let Some(s) = syntaxes.find_syntax_by_extension(&name) {
|
if let Some(s) = syntaxes.find_syntax_by_extension(&name) {
|
||||||
return Ok(s);
|
return Ok(s);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use anyhow::bail;
|
||||||
use mlua::{Lua, Table};
|
use mlua::{Lua, Table};
|
||||||
use yazi_shared::event::{Cmd, Data};
|
use yazi_shared::event::{Cmd, Data};
|
||||||
|
|
||||||
pub type PluginCallback = Box<dyn FnOnce(&Lua, Table) -> mlua::Result<()> + Send>;
|
pub type PluginCallback = Box<dyn FnOnce(&Lua, Table) -> mlua::Result<()> + Send + Sync>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct PluginOpt {
|
pub struct PluginOpt {
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ impl Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_any(mut self, name: impl ToString, data: impl Any + Send) -> Self {
|
pub fn with_any(mut self, name: impl ToString, data: impl Any + Send + Sync) -> Self {
|
||||||
self.args.insert(name.to_string(), Data::Any(Box::new(data)));
|
self.args.insert(name.to_string(), Data::Any(Box::new(data)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ pub enum Data {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
Url(Url),
|
Url(Url),
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
Any(Box<dyn Any + Send>),
|
Any(Box<dyn Any + Send + Sync>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue