mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: new cache_dir option (#96)
This commit is contained in:
parent
4d4586409d
commit
c0c1a6cae6
10 changed files with 85 additions and 50 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use std::{path::{Path, PathBuf}, sync::atomic::{AtomicBool, Ordering}};
|
||||
|
||||
use anyhow::Result;
|
||||
use config::{preview::PreviewAdaptor, BOOT, PREVIEW};
|
||||
use config::{preview::PreviewAdaptor, PREVIEW};
|
||||
use ratatui::prelude::Rect;
|
||||
use shared::RoCell;
|
||||
use tokio::{fs, sync::mpsc::UnboundedSender};
|
||||
|
|
@ -19,7 +19,7 @@ pub struct Adaptor;
|
|||
|
||||
impl Adaptor {
|
||||
pub async fn image_show(mut path: &Path, rect: Rect) -> Result<()> {
|
||||
let cache = BOOT.cache(path, 0);
|
||||
let cache = PREVIEW.cache(path, 0);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
path = cache.as_path();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
- tab_size: Tab width
|
||||
- max_width: Maximum preview width for images and videos
|
||||
- max_height: Maximum preview height for images and videos
|
||||
- cache_dir: The system cache directory is used by default, and the cached files will go away on a reboot automatically. If you want to make it more persistent, you can specify the cache directory manually as an absolute path.
|
||||
|
||||
## opener
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ show_symlink = true
|
|||
tab_size = 2
|
||||
max_width = 600
|
||||
max_height = 900
|
||||
cache_dir = ""
|
||||
|
||||
[opener]
|
||||
folder = [
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
use std::{env, fs, path::{Path, PathBuf}, process, time::{self, SystemTime}};
|
||||
use std::{env, fs, path::PathBuf, process};
|
||||
|
||||
use clap::{command, Parser};
|
||||
use md5::{Digest, Md5};
|
||||
use shared::absolute_path;
|
||||
|
||||
use crate::Xdg;
|
||||
use crate::{Xdg, PREVIEW};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Boot {
|
||||
pub cwd: PathBuf,
|
||||
pub cache_dir: PathBuf,
|
||||
pub state_dir: PathBuf,
|
||||
|
||||
pub cwd_file: Option<PathBuf>,
|
||||
|
|
@ -43,46 +41,37 @@ impl Default for Boot {
|
|||
let cwd = args
|
||||
.cwd
|
||||
.map(|p| futures::executor::block_on(absolute_path(p)))
|
||||
.and_then(|p| p.is_dir().then_some(p))
|
||||
.filter(|p| p.is_dir())
|
||||
.or_else(|| env::current_dir().ok());
|
||||
|
||||
let boot = Self {
|
||||
cwd: cwd.unwrap_or("/".into()),
|
||||
cache_dir: env::temp_dir().join("yazi"),
|
||||
state_dir: Xdg::state_dir().unwrap(),
|
||||
|
||||
cwd_file: args.cwd_file,
|
||||
chooser_file: args.chooser_file,
|
||||
};
|
||||
|
||||
if !boot.cache_dir.is_dir() {
|
||||
fs::create_dir(&boot.cache_dir).unwrap();
|
||||
}
|
||||
if !boot.state_dir.is_dir() {
|
||||
fs::create_dir_all(&boot.state_dir).unwrap();
|
||||
}
|
||||
if !PREVIEW.cache_dir.is_dir() {
|
||||
fs::create_dir(&PREVIEW.cache_dir).unwrap();
|
||||
}
|
||||
|
||||
if args.clear_cache {
|
||||
println!("Clearing cache directory: {:?}", boot.cache_dir);
|
||||
fs::remove_dir_all(&boot.cache_dir).unwrap();
|
||||
if PREVIEW.cache_dir == Xdg::cache_dir() {
|
||||
println!("Clearing cache directory: \n{:?}", PREVIEW.cache_dir);
|
||||
fs::remove_dir_all(&PREVIEW.cache_dir).unwrap();
|
||||
} else {
|
||||
println!(
|
||||
"You've changed the default cache directory, for your data's safety, please clear it manually: \n{:?}",
|
||||
PREVIEW.cache_dir
|
||||
);
|
||||
}
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
boot
|
||||
}
|
||||
}
|
||||
|
||||
impl Boot {
|
||||
#[inline]
|
||||
pub fn cache(&self, path: &Path, skip: usize) -> PathBuf {
|
||||
self
|
||||
.cache_dir
|
||||
.join(format!("{:x}", Md5::new_with_prefix(format!("{:?}///{}", path, skip)).finalize()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tmpfile(&self, prefix: &str) -> PathBuf {
|
||||
let nanos = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_nanos();
|
||||
self.cache_dir.join(format!("{prefix}-{}", nanos / 1000))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ static MERGED_KEYMAP: RoCell<String> = RoCell::new();
|
|||
static MERGED_THEME: RoCell<String> = RoCell::new();
|
||||
static MERGED_YAZI: RoCell<String> = RoCell::new();
|
||||
|
||||
pub static BOOT: RoCell<boot::Boot> = RoCell::new();
|
||||
pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new();
|
||||
pub static LOG: RoCell<log::Log> = RoCell::new();
|
||||
pub static MANAGER: RoCell<manager::Manager> = RoCell::new();
|
||||
|
|
@ -32,12 +31,13 @@ pub static PREVIEW: RoCell<preview::Preview> = RoCell::new();
|
|||
pub static TASKS: RoCell<tasks::Tasks> = RoCell::new();
|
||||
pub static THEME: RoCell<theme::Theme> = RoCell::new();
|
||||
|
||||
pub static BOOT: RoCell<boot::Boot> = RoCell::new();
|
||||
|
||||
pub fn init() {
|
||||
MERGED_KEYMAP.with(Preset::keymap);
|
||||
MERGED_THEME.with(Preset::theme);
|
||||
MERGED_YAZI.with(Preset::yazi);
|
||||
|
||||
BOOT.with(Default::default);
|
||||
KEYMAP.with(Default::default);
|
||||
LOG.with(Default::default);
|
||||
MANAGER.with(Default::default);
|
||||
|
|
@ -45,4 +45,6 @@ pub fn init() {
|
|||
PREVIEW.with(Default::default);
|
||||
TASKS.with(Default::default);
|
||||
THEME.with(Default::default);
|
||||
|
||||
BOOT.with(Default::default);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,65 @@
|
|||
use std::{path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
|
||||
use md5::{Digest, Md5};
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::PreviewAdaptor;
|
||||
use crate::MERGED_YAZI;
|
||||
use crate::{xdg::Xdg, MERGED_YAZI};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
pub struct Preview {
|
||||
#[serde(skip)]
|
||||
pub adaptor: PreviewAdaptor,
|
||||
pub tab_size: u32,
|
||||
pub adaptor: PreviewAdaptor,
|
||||
|
||||
pub tab_size: u32,
|
||||
pub max_width: u32,
|
||||
pub max_height: u32,
|
||||
|
||||
pub cache_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl Default for Preview {
|
||||
fn default() -> Self {
|
||||
#[derive(Deserialize)]
|
||||
struct Outer {
|
||||
preview: Preview,
|
||||
preview: Shadow,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct Shadow {
|
||||
pub tab_size: u32,
|
||||
pub max_width: u32,
|
||||
pub max_height: u32,
|
||||
|
||||
pub cache_dir: Option<String>,
|
||||
}
|
||||
|
||||
let outer: Outer = toml::from_str(&MERGED_YAZI).unwrap();
|
||||
outer.preview
|
||||
let preview = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().preview;
|
||||
|
||||
let cache_dir =
|
||||
preview.cache_dir.filter(|p| !p.is_empty()).map_or_else(Xdg::cache_dir, PathBuf::from);
|
||||
|
||||
Preview {
|
||||
adaptor: Default::default(),
|
||||
|
||||
tab_size: preview.tab_size,
|
||||
max_width: preview.max_width,
|
||||
max_height: preview.max_height,
|
||||
|
||||
cache_dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Preview {
|
||||
#[inline]
|
||||
pub fn cache(&self, path: &Path, skip: usize) -> PathBuf {
|
||||
self
|
||||
.cache_dir
|
||||
.join(format!("{:x}", Md5::new_with_prefix(format!("{:?}///{}", path, skip)).finalize()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tmpfile(&self, prefix: &str) -> PathBuf {
|
||||
let nanos = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_nanos();
|
||||
self.cache_dir.join(format!("{prefix}-{}", nanos / 1000))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
pub(super) struct Xdg;
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ impl Xdg {
|
|||
{
|
||||
std::env::var_os("XDG_CONFIG_HOME")
|
||||
.map(PathBuf::from)
|
||||
.and_then(|p| p.is_absolute().then_some(p))
|
||||
.filter(|p| p.is_absolute())
|
||||
.or_else(|| dirs::home_dir().map(|h| h.join(".config")))
|
||||
.map(|p| p.join("yazi"))
|
||||
}
|
||||
|
|
@ -27,9 +27,12 @@ impl Xdg {
|
|||
{
|
||||
std::env::var_os("XDG_STATE_HOME")
|
||||
.map(PathBuf::from)
|
||||
.and_then(|p| p.is_absolute().then_some(p))
|
||||
.filter(|p| p.is_absolute())
|
||||
.or_else(|| dirs::home_dir().map(|h| h.join(".local/state")))
|
||||
.map(|p| p.join("yazi"))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn cache_dir() -> PathBuf { env::temp_dir().join("yazi") }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, ffi::OsStr, io::{stdout, BufWriter, Write}, mem, path::{Path, PathBuf}};
|
||||
|
||||
use anyhow::{anyhow, bail, Error, Result};
|
||||
use config::{BOOT, OPEN};
|
||||
use config::{OPEN, PREVIEW};
|
||||
use shared::{max_common_root, Defer, Term, MIME_DIR};
|
||||
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
|
||||
|
||||
|
|
@ -222,7 +222,7 @@ impl Manager {
|
|||
let root = max_common_root(&old);
|
||||
let old: Vec<_> = old.into_iter().map(|p| p.strip_prefix(&root).unwrap().to_owned()).collect();
|
||||
|
||||
let tmp = BOOT.tmpfile("bulk");
|
||||
let tmp = PREVIEW.tmpfile("bulk");
|
||||
tokio::spawn(async move {
|
||||
let Some(opener) = OPEN.block_opener("bulk.txt", "text/plain") else {
|
||||
bail!("No opener for bulk rename");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{io::BufRead, path::Path, sync::atomic::{AtomicUsize, Ordering}};
|
|||
|
||||
use adaptor::Adaptor;
|
||||
use anyhow::anyhow;
|
||||
use config::{BOOT, MANAGER, PREVIEW};
|
||||
use config::{MANAGER, PREVIEW};
|
||||
use shared::{MimeKind, PeekError};
|
||||
use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped};
|
||||
use tokio::fs;
|
||||
|
|
@ -62,7 +62,7 @@ impl Provider {
|
|||
}
|
||||
|
||||
pub(super) async fn video(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
|
||||
let cache = BOOT.cache(path, skip);
|
||||
let cache = PREVIEW.cache(path, skip);
|
||||
if fs::metadata(&cache).await.is_err() {
|
||||
external::ffmpegthumbnailer(path, &cache, skip).await?;
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ impl Provider {
|
|||
}
|
||||
|
||||
pub(super) async fn pdf(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
|
||||
let cache = BOOT.cache(path, skip);
|
||||
let cache = PREVIEW.cache(path, skip);
|
||||
if fs::metadata(&cache).await.is_err() {
|
||||
external::pdftoppm(path, &cache, skip).await?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{collections::{BTreeMap, BTreeSet}, path::PathBuf, sync::Arc};
|
|||
|
||||
use adaptor::Image;
|
||||
use anyhow::Result;
|
||||
use config::BOOT;
|
||||
use config::PREVIEW;
|
||||
use parking_lot::Mutex;
|
||||
use shared::{calculate_size, Throttle};
|
||||
use tokio::{fs, sync::mpsc};
|
||||
|
|
@ -74,7 +74,7 @@ impl Precache {
|
|||
pub(crate) async fn work(&self, task: &mut PrecacheOp) -> Result<()> {
|
||||
match task {
|
||||
PrecacheOp::Image(task) => {
|
||||
let cache = BOOT.cache(&task.target, 0);
|
||||
let cache = PREVIEW.cache(&task.target, 0);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ impl Precache {
|
|||
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
|
||||
}
|
||||
PrecacheOp::Video(task) => {
|
||||
let cache = BOOT.cache(&task.target, 0);
|
||||
let cache = PREVIEW.cache(&task.target, 0);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ impl Precache {
|
|||
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
|
||||
}
|
||||
PrecacheOp::Pdf(task) => {
|
||||
let cache = BOOT.cache(&task.target, 0);
|
||||
let cache = PREVIEW.cache(&task.target, 0);
|
||||
if fs::metadata(&cache).await.is_ok() {
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue