mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
refactor: add tmpfile function to Boot
This commit is contained in:
parent
acb2eee65f
commit
aa441cd7f0
11 changed files with 66 additions and 38 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -348,6 +348,8 @@ dependencies = [
|
|||
"crossterm 0.27.0",
|
||||
"futures",
|
||||
"glob",
|
||||
"indexmap 2.0.0",
|
||||
"md-5",
|
||||
"once_cell",
|
||||
"ratatui",
|
||||
"regex",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use std::{path::{Path, PathBuf}, sync::atomic::{AtomicBool, Ordering}};
|
||||
|
||||
use anyhow::Result;
|
||||
use config::{preview::PreviewAdaptor, PREVIEW};
|
||||
use config::{preview::PreviewAdaptor, BOOT, PREVIEW};
|
||||
use once_cell::sync::Lazy;
|
||||
use ratatui::prelude::Rect;
|
||||
use tokio::{fs, sync::mpsc::UnboundedSender};
|
||||
|
||||
use super::{Iterm2, Kitty, Ueberzug};
|
||||
use crate::{Image, Sixel};
|
||||
use crate::Sixel;
|
||||
|
||||
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ impl Adaptor {
|
|||
Self::image_hide(rect);
|
||||
}
|
||||
|
||||
let cache = Image::cache(path);
|
||||
let cache = BOOT.cache(path);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
path = cache.as_path();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use std::{path::{Path, PathBuf}, sync::Arc};
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use anyhow::Result;
|
||||
use config::{BOOT, PREVIEW};
|
||||
use config::PREVIEW;
|
||||
use image::{imageops::FilterType, DynamicImage, ImageFormat};
|
||||
use md5::{Digest, Md5};
|
||||
use shared::tty_ratio;
|
||||
use tokio::fs;
|
||||
|
||||
|
|
@ -54,11 +53,4 @@ impl Image {
|
|||
_ => fs::write(cache, &*img).await?,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cache(path: &Path) -> PathBuf {
|
||||
BOOT
|
||||
.cache_dir
|
||||
.join(format!("{:x}", Md5::new_with_prefix(path.to_string_lossy().as_bytes()).finalize()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ clap = { version = "^4", features = [ "derive" ] }
|
|||
crossterm = "^0"
|
||||
futures = "^0"
|
||||
glob = "^0"
|
||||
indexmap = "^2"
|
||||
md-5 = "^0"
|
||||
once_cell = "^1"
|
||||
ratatui = "^0"
|
||||
regex = "^1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::{env, fs, path::PathBuf};
|
||||
use std::{env, fs, path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
|
||||
use clap::Parser;
|
||||
use md5::{Digest, Md5};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Boot {
|
||||
|
|
@ -37,3 +38,18 @@ impl Default for Boot {
|
|||
boot
|
||||
}
|
||||
}
|
||||
|
||||
impl Boot {
|
||||
#[inline]
|
||||
pub fn cache(&self, path: &Path) -> PathBuf {
|
||||
self
|
||||
.cache_dir
|
||||
.join(format!("{:x}", Md5::new_with_prefix(path.to_string_lossy().as_bytes()).finalize()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tmpfile(&self) -> PathBuf {
|
||||
let nanos = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_nanos();
|
||||
self.cache_dir.join(format!("{:x}", Md5::new_with_prefix(nanos.to_le_bytes()).finalize()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{collections::{BTreeMap, BTreeSet}, path::Path};
|
||||
use std::{collections::BTreeMap, path::Path};
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use shared::MIME_DIR;
|
||||
|
||||
|
|
@ -8,7 +9,7 @@ use crate::{Pattern, MERGED_YAZI};
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Open {
|
||||
openers: BTreeMap<String, Vec<Opener>>,
|
||||
openers: BTreeMap<String, IndexSet<Opener>>,
|
||||
rules: Vec<OpenRule>,
|
||||
}
|
||||
|
||||
|
|
@ -25,26 +26,36 @@ impl Default for Open {
|
|||
}
|
||||
|
||||
impl Open {
|
||||
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<Vec<&Opener>>
|
||||
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<&IndexSet<Opener>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
M: AsRef<str>,
|
||||
{
|
||||
self.rules.iter().find_map(|rule| {
|
||||
if rule.name.as_ref().map_or(false, |e| e.match_path(&path, Some(mime.as_ref() == MIME_DIR)))
|
||||
|| rule.mime.as_ref().map_or(false, |m| m.matches(&mime))
|
||||
let is_folder = Some(mime.as_ref() == MIME_DIR);
|
||||
if rule.mime.as_ref().map_or(false, |m| m.matches(&mime))
|
||||
|| rule.name.as_ref().map_or(false, |n| n.match_path(&path, is_folder))
|
||||
{
|
||||
self.openers.get(&rule.use_).map(|v| v.iter().collect())
|
||||
self.openers.get(&rule.use_)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn block_opener<P, M>(&self, path: P, mime: M) -> Option<&Opener>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
M: AsRef<str>,
|
||||
{
|
||||
self.openers(path, mime).and_then(|o| o.iter().find(|o| o.block))
|
||||
}
|
||||
|
||||
pub fn common_openers(&self, targets: &[(impl AsRef<Path>, impl AsRef<str>)]) -> Vec<&Opener> {
|
||||
let grouped = targets.iter().filter_map(|(p, m)| self.openers(p, m)).collect::<Vec<_>>();
|
||||
let flat = grouped.iter().flatten().cloned().collect::<BTreeSet<_>>();
|
||||
flat.into_iter().filter(|o| grouped.iter().all(|g| g.contains(o))).collect()
|
||||
let flat = grouped.iter().flat_map(|&g| g).collect::<IndexSet<_>>();
|
||||
flat.into_iter().filter(|&o| grouped.iter().all(|g| g.contains(o))).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +75,7 @@ impl<'de> Deserialize<'de> for Open {
|
|||
}
|
||||
|
||||
let outer = Outer::deserialize(deserializer)?;
|
||||
Ok(Self { openers: outer.opener, rules: outer.open.rules })
|
||||
let openers = outer.opener.into_iter().map(|(k, v)| (k, IndexSet::from_iter(v))).collect();
|
||||
Ok(Self { openers, rules: outer.open.rules })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
clippy::if_same_then_else,
|
||||
clippy::len_without_is_empty,
|
||||
clippy::module_inception,
|
||||
clippy::option_map_unit_fn
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::unit_arg
|
||||
)]
|
||||
|
||||
mod blocker;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::{io::BufRead, mem, path::{Path, PathBuf}, sync::{atomic::{AtomicUsize, Ordering}, Arc}};
|
||||
|
||||
use adaptor::{Adaptor, Image};
|
||||
use adaptor::Adaptor;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use config::PREVIEW;
|
||||
use config::{BOOT, PREVIEW};
|
||||
use ratatui::prelude::Rect;
|
||||
use shared::{tty_size, MimeKind};
|
||||
use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped};
|
||||
|
|
@ -113,7 +113,7 @@ impl Preview {
|
|||
}
|
||||
|
||||
pub async fn video(path: &Path) -> Result<PreviewData> {
|
||||
let cache = Image::cache(path);
|
||||
let cache = BOOT.cache(path);
|
||||
if fs::metadata(&cache).await.is_err() {
|
||||
external::ffmpegthumbnailer(path, &cache).await?;
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ impl Preview {
|
|||
}
|
||||
|
||||
pub async fn pdf(path: &Path) -> Result<PreviewData> {
|
||||
let cache = Image::cache(path);
|
||||
let cache = BOOT.cache(path);
|
||||
if fs::metadata(&cache).await.is_err() {
|
||||
external::pdftoppm(path, &cache).await?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ use std::{collections::{BTreeMap, HashMap, HashSet}, ffi::OsStr, io::{stdout, Wr
|
|||
|
||||
use config::{manager::SortBy, open::Opener, OPEN};
|
||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||
use shared::{tty_size, MimeKind};
|
||||
use shared::{tty_size, Defer, MimeKind};
|
||||
use tokio::{io::AsyncReadExt, select, sync::mpsc, time};
|
||||
use tracing::trace;
|
||||
|
||||
use super::{task::TaskSummary, Scheduler, TASKS_PADDING, TASKS_PERCENT};
|
||||
use crate::{emit, files::{File, Files}, input::InputOpt, BLOCKER};
|
||||
use crate::{emit, files::{File, Files}, input::InputOpt, Event, BLOCKER};
|
||||
|
||||
pub struct Tasks {
|
||||
scheduler: Arc<Scheduler>,
|
||||
|
|
@ -80,6 +80,11 @@ impl Tasks {
|
|||
};
|
||||
|
||||
emit!(Stop(true)).await;
|
||||
let _defer = Defer::new(|| {
|
||||
disable_raw_mode().ok();
|
||||
Event::Stop(false, None).emit()
|
||||
});
|
||||
|
||||
stdout().write_all("\n".repeat(tty_size().ws_row as usize).as_bytes()).ok();
|
||||
stdout().write_all(buffered.as_bytes()).ok();
|
||||
enable_raw_mode().ok();
|
||||
|
|
@ -112,9 +117,6 @@ impl Tasks {
|
|||
while quit[0] != b'q' {
|
||||
stdin.read(&mut quit).await.ok();
|
||||
}
|
||||
|
||||
disable_raw_mode().ok();
|
||||
emit!(Stop(false)).await;
|
||||
});
|
||||
false
|
||||
}
|
||||
|
|
@ -132,7 +134,7 @@ impl Tasks {
|
|||
pub fn file_open(&self, targets: &[(impl AsRef<Path>, impl AsRef<str>)]) -> bool {
|
||||
let mut openers = BTreeMap::new();
|
||||
for (path, mime) in targets {
|
||||
if let Some(opener) = OPEN.openers(path, mime).and_then(|o| o.first().cloned()) {
|
||||
if let Some(opener) = OPEN.openers(path, mime).and_then(|o| o.first()) {
|
||||
openers.entry(opener).or_insert_with(Vec::new).push(path.as_ref().as_os_str());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::{collections::{BTreeMap, BTreeSet}, path::PathBuf, sync::Arc};
|
|||
|
||||
use adaptor::Image;
|
||||
use anyhow::Result;
|
||||
use config::BOOT;
|
||||
use parking_lot::Mutex;
|
||||
use shared::{calculate_size, Throttle};
|
||||
use tokio::{fs, sync::mpsc};
|
||||
|
|
@ -73,7 +74,7 @@ impl Precache {
|
|||
pub(crate) async fn work(&self, task: &mut PrecacheOp) -> Result<()> {
|
||||
match task {
|
||||
PrecacheOp::Image(task) => {
|
||||
let cache = Image::cache(&task.target);
|
||||
let cache = BOOT.cache(&task.target);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
|
||||
}
|
||||
|
|
@ -83,7 +84,7 @@ impl Precache {
|
|||
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
|
||||
}
|
||||
PrecacheOp::Video(task) => {
|
||||
let cache = Image::cache(&task.target);
|
||||
let cache = BOOT.cache(&task.target);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
|
||||
}
|
||||
|
|
@ -92,7 +93,7 @@ impl Precache {
|
|||
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
|
||||
}
|
||||
PrecacheOp::Pdf(task) => {
|
||||
let cache = Image::cache(&task.target);
|
||||
let cache = BOOT.cache(&task.target);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nocapture"],"version":"0.2"}
|
||||
{"language":"en","version":"0.2","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos"]}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue