mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
c4f76bd778
commit
a7e8567e81
10 changed files with 55 additions and 43 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use std::{env, fs, path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
use std::{env, fs, path::{Path, PathBuf}, process, time::{self, SystemTime}};
|
||||
|
||||
use clap::{command, Parser};
|
||||
use md5::{Digest, Md5};
|
||||
|
|
@ -30,6 +30,10 @@ struct Args {
|
|||
/// Write the selected files on open emitted by the chooser mode
|
||||
#[arg(long)]
|
||||
chooser_file: Option<PathBuf>,
|
||||
|
||||
/// Clear the cache directory
|
||||
#[arg(long, action)]
|
||||
clear_cache: bool,
|
||||
}
|
||||
|
||||
impl Default for Boot {
|
||||
|
|
@ -58,6 +62,12 @@ impl Default for Boot {
|
|||
fs::create_dir_all(&boot.state_dir).unwrap();
|
||||
}
|
||||
|
||||
if args.clear_cache {
|
||||
println!("Clearing cache directory: {:?}", boot.cache_dir);
|
||||
fs::remove_dir_all(&boot.cache_dir).unwrap();
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
boot
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
core/src/external/ffmpegthumbnailer.rs
vendored
8
core/src/external/ffmpegthumbnailer.rs
vendored
|
|
@ -1,13 +1,13 @@
|
|||
use std::path::Path;
|
||||
|
||||
use config::PREVIEW;
|
||||
use shared::PagedError;
|
||||
use shared::PeekError;
|
||||
use tokio::process::Command;
|
||||
|
||||
pub async fn ffmpegthumbnailer(src: &Path, dest: &Path, skip: usize) -> Result<(), PagedError> {
|
||||
pub async fn ffmpegthumbnailer(src: &Path, dest: &Path, skip: usize) -> Result<(), PeekError> {
|
||||
let percentage = 5 + skip;
|
||||
if percentage >= 100 {
|
||||
return Err(PagedError::Exceed(94));
|
||||
if percentage > 95 {
|
||||
return Err(PeekError::Exceed(95 - 5));
|
||||
}
|
||||
|
||||
let output = Command::new("ffmpegthumbnailer")
|
||||
|
|
|
|||
6
core/src/external/jq.rs
vendored
6
core/src/external/jq.rs
vendored
|
|
@ -2,10 +2,10 @@ use std::{path::Path, process::Stdio};
|
|||
|
||||
use anyhow::Result;
|
||||
use config::PREVIEW;
|
||||
use shared::PagedError;
|
||||
use shared::PeekError;
|
||||
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command};
|
||||
|
||||
pub async fn jq(path: &Path, skip: usize, limit: usize) -> Result<String, PagedError> {
|
||||
pub async fn jq(path: &Path, skip: usize, limit: usize) -> Result<String, PeekError> {
|
||||
let mut child = Command::new("jq")
|
||||
.args(["-C", "--indent", &PREVIEW.tab_size.to_string(), "."])
|
||||
.arg(path)
|
||||
|
|
@ -30,7 +30,7 @@ pub async fn jq(path: &Path, skip: usize, limit: usize) -> Result<String, PagedE
|
|||
}
|
||||
|
||||
if skip > 0 && i < skip + limit {
|
||||
Err(PagedError::Exceed(i.saturating_sub(limit)))
|
||||
Err(PeekError::Exceed(i.saturating_sub(limit)))
|
||||
} else {
|
||||
Ok(lines)
|
||||
}
|
||||
|
|
|
|||
6
core/src/external/lsar.rs
vendored
6
core/src/external/lsar.rs
vendored
|
|
@ -3,7 +3,7 @@ use std::path::Path;
|
|||
use anyhow::anyhow;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
use shared::PagedError;
|
||||
use shared::PeekError;
|
||||
use tokio::process::Command;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -31,7 +31,7 @@ pub struct LsarFile {
|
|||
}
|
||||
|
||||
#[allow(clippy::manual_map)]
|
||||
pub async fn lsar(path: &Path, skip: usize, limit: usize) -> Result<Vec<LsarFile>, PagedError> {
|
||||
pub async fn lsar(path: &Path, skip: usize, limit: usize) -> Result<Vec<LsarFile>, PeekError> {
|
||||
let output =
|
||||
Command::new("lsar").args(["-j", "-jss"]).arg(path).kill_on_drop(true).output().await?;
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ pub async fn lsar(path: &Path, skip: usize, limit: usize) -> Result<Vec<LsarFile
|
|||
}
|
||||
|
||||
if skip > 0 && files.len() < limit {
|
||||
Err(PagedError::Exceed(i.saturating_sub(limit)))
|
||||
Err(PeekError::Exceed(i.saturating_sub(limit)))
|
||||
} else {
|
||||
Ok(files)
|
||||
}
|
||||
|
|
|
|||
6
core/src/external/pdftoppm.rs
vendored
6
core/src/external/pdftoppm.rs
vendored
|
|
@ -2,10 +2,10 @@ use std::path::Path;
|
|||
|
||||
use adaptor::Image;
|
||||
use regex::Regex;
|
||||
use shared::PagedError;
|
||||
use shared::PeekError;
|
||||
use tokio::process::Command;
|
||||
|
||||
pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result<(), PagedError> {
|
||||
pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result<(), PeekError> {
|
||||
let output = Command::new("pdftoppm")
|
||||
.args(["-singlefile", "-jpeg", "-jpegopt", "quality=75", "-f"])
|
||||
.arg((skip + 1).to_string())
|
||||
|
|
@ -22,7 +22,7 @@ pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result
|
|||
.map(|cap| cap[1].parse().unwrap())
|
||||
.unwrap_or(0);
|
||||
|
||||
return if pages > 0 { Err(PagedError::Exceed(pages - 1)) } else { Err(s.to_string().into()) };
|
||||
return if pages > 0 { Err(PeekError::Exceed(pages - 1)) } else { Err(s.to_string().into()) };
|
||||
}
|
||||
|
||||
Ok(Image::precache_anyway(output.stdout.into(), dest).await?)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{mem, path::{Path, PathBuf}, sync::atomic::Ordering};
|
|||
|
||||
use adaptor::Adaptor;
|
||||
use config::MANAGER;
|
||||
use shared::{MimeKind, PagedError};
|
||||
use shared::{MimeKind, PeekError};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use super::{provider::INCR, Provider};
|
||||
|
|
@ -51,7 +51,6 @@ impl Preview {
|
|||
|
||||
self.handle.take().map(|h| h.abort());
|
||||
INCR.fetch_add(1, Ordering::Relaxed);
|
||||
Adaptor::image_hide(MANAGER.layout.preview_rect()).ok();
|
||||
|
||||
self.skip = skip;
|
||||
self.handle = Some(tokio::spawn(async move {
|
||||
|
|
@ -59,7 +58,7 @@ impl Preview {
|
|||
Ok(result) => {
|
||||
emit!(Preview(path, mime, result));
|
||||
}
|
||||
Err(PagedError::Exceed(max)) => {
|
||||
Err(PeekError::Exceed(max)) => {
|
||||
emit!(Peek(path, max));
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{io::BufRead, path::Path, sync::atomic::{AtomicUsize, Ordering}};
|
|||
use adaptor::Adaptor;
|
||||
use anyhow::anyhow;
|
||||
use config::{BOOT, MANAGER, PREVIEW};
|
||||
use shared::{MimeKind, PagedError};
|
||||
use shared::{MimeKind, PeekError};
|
||||
use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped};
|
||||
use tokio::fs;
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ impl Provider {
|
|||
kind: MimeKind,
|
||||
path: &Path,
|
||||
skip: usize,
|
||||
) -> Result<PreviewData, PagedError> {
|
||||
) -> Result<PreviewData, PeekError> {
|
||||
match kind {
|
||||
MimeKind::Empty => Ok(PreviewData::None),
|
||||
MimeKind::Archive => Provider::archive(path, skip).await.map(PreviewData::Text),
|
||||
|
|
@ -47,7 +47,7 @@ impl Provider {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) async fn folder(path: &Path) -> Result<PreviewData, PagedError> {
|
||||
pub(super) async fn folder(path: &Path) -> Result<PreviewData, PeekError> {
|
||||
emit!(Files(match Files::read_dir(path).await {
|
||||
Ok(items) => FilesOp::Read(path.to_path_buf(), items),
|
||||
Err(_) => FilesOp::IOErr(path.to_path_buf()),
|
||||
|
|
@ -56,12 +56,12 @@ impl Provider {
|
|||
Ok(PreviewData::Folder)
|
||||
}
|
||||
|
||||
pub(super) async fn image(path: &Path) -> Result<PreviewData, PagedError> {
|
||||
pub(super) async fn image(path: &Path) -> Result<PreviewData, PeekError> {
|
||||
Adaptor::image_show(path, MANAGER.layout.preview_rect()).await?;
|
||||
Ok(PreviewData::Image)
|
||||
}
|
||||
|
||||
pub(super) async fn video(path: &Path, skip: usize) -> Result<PreviewData, PagedError> {
|
||||
pub(super) async fn video(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
|
||||
let cache = BOOT.cache(path, skip);
|
||||
if fs::metadata(&cache).await.is_err() {
|
||||
external::ffmpegthumbnailer(path, &cache, skip).await?;
|
||||
|
|
@ -70,7 +70,7 @@ impl Provider {
|
|||
Self::image(&cache).await
|
||||
}
|
||||
|
||||
pub(super) async fn pdf(path: &Path, skip: usize) -> Result<PreviewData, PagedError> {
|
||||
pub(super) async fn pdf(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
|
||||
let cache = BOOT.cache(path, skip);
|
||||
if fs::metadata(&cache).await.is_err() {
|
||||
external::pdftoppm(path, &cache, skip).await?;
|
||||
|
|
@ -79,11 +79,11 @@ impl Provider {
|
|||
Self::image(&cache).await
|
||||
}
|
||||
|
||||
pub(super) async fn json(path: &Path, skip: usize) -> Result<String, PagedError> {
|
||||
pub(super) async fn json(path: &Path, skip: usize) -> Result<String, PeekError> {
|
||||
external::jq(path, skip, MANAGER.layout.preview_height()).await
|
||||
}
|
||||
|
||||
pub(super) async fn archive(path: &Path, skip: usize) -> Result<String, PagedError> {
|
||||
pub(super) async fn archive(path: &Path, skip: usize) -> Result<String, PeekError> {
|
||||
Ok(
|
||||
external::lsar(path, skip, MANAGER.layout.preview_height())
|
||||
.await?
|
||||
|
|
@ -94,13 +94,13 @@ impl Provider {
|
|||
)
|
||||
}
|
||||
|
||||
pub(super) async fn highlight(path: &Path, skip: usize) -> Result<String, PagedError> {
|
||||
pub(super) async fn highlight(path: &Path, skip: usize) -> Result<String, PeekError> {
|
||||
let tick = INCR.load(Ordering::Relaxed);
|
||||
let path = path.to_path_buf();
|
||||
let spaces = " ".repeat(PREVIEW.tab_size as usize);
|
||||
|
||||
let (syntaxes, theme) = highlighter();
|
||||
tokio::task::spawn_blocking(move || -> Result<String, PagedError> {
|
||||
tokio::task::spawn_blocking(move || -> Result<String, PeekError> {
|
||||
let mut h = HighlightFile::new(path, syntaxes, theme)?;
|
||||
let mut line = String::new();
|
||||
let mut buf = String::new();
|
||||
|
|
@ -109,25 +109,25 @@ impl Provider {
|
|||
let limit = MANAGER.layout.preview_height();
|
||||
while h.reader.read_line(&mut line)? > 0 {
|
||||
if tick != INCR.load(Ordering::Relaxed) {
|
||||
return Err("Preview cancelled".into());
|
||||
return Err("Highlighting cancelled".into());
|
||||
}
|
||||
|
||||
i += 1;
|
||||
if i > skip + limit {
|
||||
break;
|
||||
} else if i <= skip {
|
||||
line.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
line = line.replace('\t', &spaces);
|
||||
let regions = h.highlight_lines.highlight_line(&line, syntaxes).map_err(|e| anyhow!(e))?;
|
||||
buf.push_str(&as_24_bit_terminal_escaped(®ions, false));
|
||||
|
||||
if i > skip {
|
||||
buf.push_str(&as_24_bit_terminal_escaped(®ions, false));
|
||||
}
|
||||
line.clear();
|
||||
}
|
||||
|
||||
if skip > 0 && i < skip + limit {
|
||||
return Err(PagedError::Exceed(i.saturating_sub(limit)));
|
||||
return Err(PeekError::Exceed(i.saturating_sub(limit)));
|
||||
}
|
||||
|
||||
buf.push_str("\x1b[0m");
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ impl Tab {
|
|||
};
|
||||
|
||||
let path = self.preview.lock.as_ref().unwrap().0.clone();
|
||||
if let Some(dir) = self.history(&path) {
|
||||
let max = dir.files.len().saturating_sub(MANAGER.layout.preview_height());
|
||||
if let Some(folder) = self.history(&path) {
|
||||
let max = folder.files.len().saturating_sub(MANAGER.layout.preview_height());
|
||||
if new > max {
|
||||
emit!(Peek(path, max));
|
||||
return false;
|
||||
|
|
|
|||
3
shared/src/errors/mod.rs
Normal file
3
shared/src/errors/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
mod peek;
|
||||
|
||||
pub use peek::*;
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
use std::{error::Error, fmt::{self, Display}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PagedError {
|
||||
pub enum PeekError {
|
||||
Exceed(usize),
|
||||
Unexpected(String),
|
||||
}
|
||||
|
||||
impl Display for PagedError {
|
||||
impl Display for PeekError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Exceed(lines) => write!(f, "Exceed: {lines}"),
|
||||
|
|
@ -15,20 +15,20 @@ impl Display for PagedError {
|
|||
}
|
||||
}
|
||||
|
||||
impl Error for PagedError {}
|
||||
impl Error for PeekError {}
|
||||
|
||||
impl From<String> for PagedError {
|
||||
impl From<String> for PeekError {
|
||||
fn from(error: String) -> Self { Self::Unexpected(error) }
|
||||
}
|
||||
impl From<&str> for PagedError {
|
||||
impl From<&str> for PeekError {
|
||||
fn from(error: &str) -> Self { Self::from(error.to_owned()) }
|
||||
}
|
||||
impl From<anyhow::Error> for PagedError {
|
||||
impl From<anyhow::Error> for PeekError {
|
||||
fn from(error: anyhow::Error) -> Self { Self::from(error.to_string()) }
|
||||
}
|
||||
impl From<std::io::Error> for PagedError {
|
||||
impl From<std::io::Error> for PeekError {
|
||||
fn from(error: std::io::Error) -> Self { Self::from(error.to_string()) }
|
||||
}
|
||||
impl From<tokio::task::JoinError> for PagedError {
|
||||
impl From<tokio::task::JoinError> for PeekError {
|
||||
fn from(error: tokio::task::JoinError) -> Self { Self::from(error.to_string()) }
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue