diff --git a/Cargo.lock b/Cargo.lock index 14a5a7e3..86413e34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2857,6 +2857,7 @@ dependencies = [ "tokio", "toml_edit", "vergen-gitcl", + "yazi-boot", "yazi-dds", "yazi-shared", ] diff --git a/yazi-adapter/src/lib.rs b/yazi-adapter/src/lib.rs index 0dfe8f9c..a0fe43cc 100644 --- a/yazi-adapter/src/lib.rs +++ b/yazi-adapter/src/lib.rs @@ -50,7 +50,7 @@ pub fn init() { .status(); } - SHOWN.with(Default::default); + SHOWN.with(<_>::default); ADAPTOR.init(Adapter::matches()); ADAPTOR.start(); diff --git a/yazi-boot/src/actions/actions.rs b/yazi-boot/src/actions/actions.rs new file mode 100644 index 00000000..191b2f55 --- /dev/null +++ b/yazi-boot/src/actions/actions.rs @@ -0,0 +1,22 @@ +use std::process; + +pub(crate) struct Actions; + +impl Actions { + pub(crate) fn act(args: &crate::Args) { + if args.debug { + println!("{}", Self::debug().unwrap()); + process::exit(0); + } + + if args.version { + println!("Yazi {}", Self::version()); + process::exit(0); + } + + if args.clear_cache { + Self::clear_cache(); + process::exit(0); + } + } +} diff --git a/yazi-boot/src/actions/clear_cache.rs b/yazi-boot/src/actions/clear_cache.rs new file mode 100644 index 00000000..75fe43ec --- /dev/null +++ b/yazi-boot/src/actions/clear_cache.rs @@ -0,0 +1,18 @@ +use yazi_config::PREVIEW; +use yazi_shared::Xdg; + +use super::Actions; + +impl Actions { + pub(super) fn clear_cache() { + if PREVIEW.cache_dir == Xdg::cache_dir() { + println!("Clearing cache directory: \n{:?}", PREVIEW.cache_dir); + std::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 + ); + } + } +} diff --git a/yazi-boot/src/actions/debug.rs b/yazi-boot/src/actions/debug.rs new file mode 100644 index 00000000..70ad74d6 --- /dev/null +++ b/yazi-boot/src/actions/debug.rs @@ -0,0 +1,105 @@ +use std::{env, ffi::OsStr, fmt::Write}; + +use regex::Regex; +use yazi_shared::Xdg; + +use super::Actions; + +impl Actions { + pub(super) fn debug() -> Result { + use std::env::consts::{ARCH, FAMILY, OS}; + let mut s = String::new(); + + writeln!(s, "\nYazi")?; + writeln!(s, " Version: {}", Self::version())?; + writeln!(s, " Debug : {}", cfg!(debug_assertions))?; + writeln!(s, " OS : {}-{} ({})", OS, ARCH, FAMILY)?; + + writeln!(s, "\nYa")?; + writeln!(s, " Version: {}", Self::process_output("ya", "--version"))?; + + writeln!(s, "\nEmulator")?; + writeln!(s, " Emulator.via_env: {:?}", yazi_adapter::Emulator::via_env())?; + writeln!(s, " Emulator.via_csi: {:?}", yazi_adapter::Emulator::via_csi())?; + writeln!(s, " Emulator.detect : {:?}", yazi_adapter::Emulator::detect())?; + + writeln!(s, "\nAdapter")?; + writeln!(s, " Adapter.matches: {:?}", yazi_adapter::Adapter::matches())?; + + writeln!(s, "\nDesktop")?; + writeln!(s, " XDG_SESSION_TYPE: {:?}", env::var_os("XDG_SESSION_TYPE"))?; + writeln!(s, " WAYLAND_DISPLAY : {:?}", env::var_os("WAYLAND_DISPLAY"))?; + writeln!(s, " DISPLAY : {:?}", env::var_os("DISPLAY"))?; + + writeln!(s, "\nSSH")?; + writeln!(s, " shared.in_ssh_connection: {:?}", yazi_shared::in_ssh_connection())?; + + writeln!(s, "\nWSL")?; + writeln!( + s, + " /proc/sys/fs/binfmt_misc/WSLInterop: {:?}", + std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() + )?; + + writeln!(s, "\nVariables")?; + writeln!(s, " SHELL : {:?}", env::var_os("SHELL"))?; + writeln!(s, " EDITOR : {:?}", env::var_os("EDITOR"))?; + writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?; + writeln!(s, " YAZI_FILE_ONE : {:?}", env::var_os("YAZI_FILE_ONE"))?; + writeln!(s, " YAZI_CONFIG_HOME : {:?}", env::var_os("YAZI_CONFIG_HOME"))?; + + writeln!(s, "\nText Opener")?; + writeln!( + s, + " default: {:?}", + yazi_config::OPEN.openers("f75a.txt", "text/plain").and_then(|a| a.first().cloned()) + )?; + writeln!(s, " block : {:?}", yazi_config::OPEN.block_opener("bulk.txt", "text/plain"))?; + + writeln!(s, "\ntmux")?; + writeln!(s, " TMUX : {:?}", *yazi_adapter::TMUX)?; + writeln!(s, " Version: {}", Self::process_output("tmux", "-V"))?; + + writeln!(s, "\nDependencies")?; + writeln!( + s, + " file : {}", + Self::process_output(env::var_os("YAZI_FILE_ONE").unwrap_or("file".into()), "--version") + )?; + writeln!(s, " ueberzugpp : {}", Self::process_output("ueberzugpp", "--version"))?; + writeln!(s, " ffmpegthumbnailer: {}", Self::process_output("ffmpegthumbnailer", "-v"))?; + writeln!(s, " magick : {}", Self::process_output("magick", "--version"))?; + writeln!(s, " fzf : {}", Self::process_output("fzf", "--version"))?; + writeln!(s, " fd : {}", Self::process_output("fd", "--version"))?; + writeln!(s, " rg : {}", Self::process_output("rg", "--version"))?; + writeln!(s, " chafa : {}", Self::process_output("chafa", "--version"))?; + writeln!(s, " zoxide : {}", Self::process_output("zoxide", "--version"))?; + writeln!(s, " unar : {}", Self::process_output("unar", "--version"))?; + writeln!(s, " jq : {}", Self::process_output("jq", "--version"))?; + + writeln!(s, "\n\n--------------------------------------------------")?; + writeln!( + s, + "When reporting a bug, please also upload the `yazi.log` log file - only upload the most recent content by time." + )?; + writeln!(s, "You can find it in the {:?} directory.", Xdg::state_dir())?; + + Ok(s) + } + + fn process_output(name: impl AsRef, arg: impl AsRef) -> String { + match std::process::Command::new(name.as_ref()).arg(arg).output() { + Ok(out) if out.status.success() => { + let line = + String::from_utf8_lossy(&out.stdout).trim().lines().next().unwrap_or_default().to_owned(); + Regex::new(r"\d+\.\d+(\.\d+-\d+|\.\d+|\b)") + .unwrap() + .find(&line) + .map(|m| m.as_str().to_owned()) + .unwrap_or(line) + } + Ok(out) => format!("{:?}, {:?}", out.status, String::from_utf8_lossy(&out.stderr)), + Err(e) => format!("{e}"), + } + } +} diff --git a/yazi-boot/src/actions/mod.rs b/yazi-boot/src/actions/mod.rs new file mode 100644 index 00000000..6b99cea4 --- /dev/null +++ b/yazi-boot/src/actions/mod.rs @@ -0,0 +1,8 @@ +#![allow(clippy::module_inception)] + +mod actions; +mod clear_cache; +mod debug; +mod version; + +pub(super) use actions::*; diff --git a/yazi-boot/src/actions/version.rs b/yazi-boot/src/actions/version.rs new file mode 100644 index 00000000..02d316e0 --- /dev/null +++ b/yazi-boot/src/actions/version.rs @@ -0,0 +1,12 @@ +use super::Actions; + +impl Actions { + pub(super) fn version() -> String { + format!( + "{} ({} {})", + env!("CARGO_PKG_VERSION"), + env!("VERGEN_GIT_SHA"), + env!("VERGEN_BUILD_DATE") + ) + } +} diff --git a/yazi-boot/src/args.rs b/yazi-boot/src/args.rs index 07e8c12f..15b81b15 100644 --- a/yazi-boot/src/args.rs +++ b/yazi-boot/src/args.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use clap::{command, Parser}; -#[derive(Debug, Parser)] +#[derive(Debug, Default, Parser)] #[command(name = "yazi")] pub struct Args { /// Set the current working entry @@ -20,6 +20,9 @@ pub struct Args { #[arg(long)] pub clear_cache: bool, + /// Use the specified client ID, must be a globally unique number + #[arg(long)] + pub client_id: Option, /// Report the specified local events to stdout #[arg(long)] pub local_events: Option, diff --git a/yazi-boot/src/boot.rs b/yazi-boot/src/boot.rs index 9f412674..928d970f 100644 --- a/yazi-boot/src/boot.rs +++ b/yazi-boot/src/boot.rs @@ -1,15 +1,9 @@ -use std::{collections::HashSet, env, ffi::{OsStr, OsString}, fmt::Write, path::{Path, PathBuf}, process}; +use std::{collections::HashSet, ffi::OsString, path::{Path, PathBuf}}; -use clap::Parser; -use regex::Regex; use serde::Serialize; -use yazi_config::PREVIEW; use yazi_shared::{fs::{current_cwd, expand_path}, Xdg}; -use super::Args; -use crate::ARGS; - -#[derive(Debug, Serialize)] +#[derive(Debug, Default, Serialize)] pub struct Boot { pub cwd: PathBuf, pub file: Option, @@ -37,137 +31,19 @@ impl Boot { (parent.unwrap().to_owned(), Some(entry.file_name().unwrap().to_owned())) } - - fn process_output(name: impl AsRef, arg: impl AsRef) -> String { - match std::process::Command::new(name.as_ref()).arg(arg).output() { - Ok(out) if out.status.success() => { - let line = - String::from_utf8_lossy(&out.stdout).trim().lines().next().unwrap_or_default().to_owned(); - Regex::new(r"\d+\.\d+(\.\d+-\d+|\.\d+|\b)") - .unwrap() - .find(&line) - .map(|m| m.as_str().to_owned()) - .unwrap_or(line) - } - Ok(out) => format!("{:?}, {:?}", out.status, String::from_utf8_lossy(&out.stderr)), - Err(e) => format!("{e}"), - } - } - - fn action_version() -> String { - format!( - "{} ({} {})", - env!("CARGO_PKG_VERSION"), - env!("VERGEN_GIT_SHA"), - env!("VERGEN_BUILD_DATE") - ) - } - - fn action_debug() -> Result { - use std::env::consts::{ARCH, FAMILY, OS}; - let mut s = String::new(); - - writeln!(s, "\nYazi")?; - writeln!(s, " Version: {}", Self::action_version())?; - writeln!(s, " Debug : {}", cfg!(debug_assertions))?; - writeln!(s, " OS : {}-{} ({})", OS, ARCH, FAMILY)?; - - writeln!(s, "\nYa")?; - writeln!(s, " Version: {}", Self::process_output("ya", "--version"))?; - - writeln!(s, "\nEmulator")?; - writeln!(s, " Emulator.via_env: {:?}", yazi_adapter::Emulator::via_env())?; - writeln!(s, " Emulator.via_csi: {:?}", yazi_adapter::Emulator::via_csi())?; - writeln!(s, " Emulator.detect : {:?}", yazi_adapter::Emulator::detect())?; - - writeln!(s, "\nAdapter")?; - writeln!(s, " Adapter.matches: {:?}", yazi_adapter::Adapter::matches())?; - - writeln!(s, "\nDesktop")?; - writeln!(s, " XDG_SESSION_TYPE: {:?}", env::var_os("XDG_SESSION_TYPE"))?; - writeln!(s, " WAYLAND_DISPLAY : {:?}", env::var_os("WAYLAND_DISPLAY"))?; - writeln!(s, " DISPLAY : {:?}", env::var_os("DISPLAY"))?; - - writeln!(s, "\nSSH")?; - writeln!(s, " shared.in_ssh_connection: {:?}", yazi_shared::in_ssh_connection())?; - - writeln!(s, "\nWSL")?; - writeln!( - s, - " /proc/sys/fs/binfmt_misc/WSLInterop: {:?}", - std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() - )?; - - writeln!(s, "\nVariables")?; - writeln!(s, " SHELL : {:?}", env::var_os("SHELL"))?; - writeln!(s, " EDITOR : {:?}", env::var_os("EDITOR"))?; - writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?; - writeln!(s, " YAZI_FILE_ONE : {:?}", env::var_os("YAZI_FILE_ONE"))?; - writeln!(s, " YAZI_CONFIG_HOME : {:?}", env::var_os("YAZI_CONFIG_HOME"))?; - - writeln!(s, "\nText Opener")?; - writeln!( - s, - " default: {:?}", - yazi_config::OPEN.openers("f75a.txt", "text/plain").and_then(|a| a.first().cloned()) - )?; - writeln!(s, " block : {:?}", yazi_config::OPEN.block_opener("bulk.txt", "text/plain"))?; - - writeln!(s, "\ntmux")?; - writeln!(s, " TMUX : {:?}", *yazi_adapter::TMUX)?; - writeln!(s, " Version: {}", Self::process_output("tmux", "-V"))?; - - writeln!(s, "\nDependencies")?; - writeln!( - s, - " file : {}", - Self::process_output(env::var_os("YAZI_FILE_ONE").unwrap_or("file".into()), "--version") - )?; - writeln!(s, " ueberzugpp : {}", Self::process_output("ueberzugpp", "--version"))?; - writeln!(s, " ffmpegthumbnailer: {}", Self::process_output("ffmpegthumbnailer", "-v"))?; - writeln!(s, " magick : {}", Self::process_output("magick", "--version"))?; - writeln!(s, " fzf : {}", Self::process_output("fzf", "--version"))?; - writeln!(s, " fd : {}", Self::process_output("fd", "--version"))?; - writeln!(s, " rg : {}", Self::process_output("rg", "--version"))?; - writeln!(s, " chafa : {}", Self::process_output("chafa", "--version"))?; - writeln!(s, " zoxide : {}", Self::process_output("zoxide", "--version"))?; - writeln!(s, " unar : {}", Self::process_output("unar", "--version"))?; - writeln!(s, " jq : {}", Self::process_output("jq", "--version"))?; - - writeln!(s, "\n\n--------------------------------------------------")?; - writeln!( - s, - "When reporting a bug, please also upload the `yazi.log` log file - only upload the most recent content by time." - )?; - writeln!(s, "You can find it in the {:?} directory.", Xdg::state_dir())?; - - Ok(s) - } - - fn action_clear_cache() { - if PREVIEW.cache_dir == Xdg::cache_dir() { - println!("Clearing cache directory: \n{:?}", PREVIEW.cache_dir); - std::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 - ); - } - } } -impl Default for Boot { - fn default() -> Self { +impl From<&crate::Args> for Boot { + fn from(args: &crate::Args) -> Self { let config_dir = Xdg::config_dir(); - let (cwd, file) = Self::parse_entry(ARGS.entry.as_deref()); + let (cwd, file) = Self::parse_entry(args.entry.as_deref()); - let local_events = ARGS + let local_events = args .local_events .as_ref() .map(|s| s.split(',').map(|s| s.to_owned()).collect()) .unwrap_or_default(); - let remote_events = ARGS + let remote_events = args .remote_events .as_ref() .map(|s| s.split(',').map(|s| s.to_owned()).collect()) @@ -187,26 +63,3 @@ impl Default for Boot { } } } - -impl Default for Args { - fn default() -> Self { - let args = Self::parse(); - - if args.debug { - println!("{}", Boot::action_debug().unwrap()); - process::exit(0); - } - - if args.version { - println!("Yazi {}", Boot::action_version()); - process::exit(0); - } - - if args.clear_cache { - Boot::action_clear_cache(); - process::exit(0); - } - - args - } -} diff --git a/yazi-boot/src/lib.rs b/yazi-boot/src/lib.rs index 569424dc..944d7800 100644 --- a/yazi-boot/src/lib.rs +++ b/yazi-boot/src/lib.rs @@ -1,5 +1,7 @@ +use clap::Parser; use yazi_shared::RoCell; +mod actions; mod args; mod boot; @@ -10,6 +12,13 @@ pub static ARGS: RoCell = RoCell::new(); pub static BOOT: RoCell = RoCell::new(); pub fn init() { - ARGS.with(Default::default); - BOOT.with(Default::default); + ARGS.with(<_>::parse); + BOOT.init(From::from(&*ARGS)); + + actions::Actions::act(&ARGS); +} + +pub fn init_default() { + ARGS.with(<_>::default); + BOOT.with(<_>::default); } diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index 25b4ae79..d7f73a64 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -9,6 +9,7 @@ homepage = "https://yazi-rs.github.io" repository = "https://github.com/sxyazi/yazi" [dependencies] +yazi-boot = { path = "../yazi-boot", version = "0.2.5" } yazi-dds = { path = "../yazi-dds", version = "0.2.5" } yazi-shared = { path = "../yazi-shared", version = "0.2.5" } diff --git a/yazi-cli/src/args.rs b/yazi-cli/src/args.rs index e18f6a99..479716fd 100644 --- a/yazi-cli/src/args.rs +++ b/yazi-cli/src/args.rs @@ -48,7 +48,7 @@ impl CommandPub { } else if let Some(s) = std::env::var("YAZI_PID").ok().filter(|s| !s.is_empty()) { Ok(s.parse()?) } else { - bail!("No receiver ID provided, also no YAZI_ID environment variable found.") + bail!("No receiver ID provided, neither YAZI_ID environment variable found.") } } diff --git a/yazi-cli/src/main.rs b/yazi-cli/src/main.rs index bfa09567..680c1b32 100644 --- a/yazi-cli/src/main.rs +++ b/yazi-cli/src/main.rs @@ -18,6 +18,7 @@ async fn main() -> anyhow::Result<()> { match Args::parse().command { Command::Pub(cmd) => { + yazi_boot::init_default(); yazi_dds::init(); if let Err(e) = yazi_dds::Client::shot(&cmd.kind, cmd.receiver()?, &cmd.body()?).await { eprintln!("Cannot send message: {e}"); @@ -41,6 +42,7 @@ async fn main() -> anyhow::Result<()> { } Command::Sub(cmd) => { + yazi_boot::init_default(); yazi_dds::init(); yazi_dds::Client::draw(cmd.kinds.split(',').collect()).await?; diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs index 82c63667..72b5cd25 100644 --- a/yazi-config/src/lib.rs +++ b/yazi-config/src/lib.rs @@ -44,7 +44,7 @@ pub fn init() -> anyhow::Result<()> { let keymap_toml = &Preset::keymap(&config_dir)?; let theme_toml = &Preset::theme(&config_dir)?; - LAYOUT.with(Default::default); + LAYOUT.with(<_>::default); KEYMAP.init(<_>::from_str(keymap_toml)?); LOG.init(<_>::from_str(yazi_toml)?); diff --git a/yazi-core/src/lib.rs b/yazi-core/src/lib.rs index 9850ca81..2d9696ec 100644 --- a/yazi-core/src/lib.rs +++ b/yazi-core/src/lib.rs @@ -21,6 +21,6 @@ pub mod which; pub use step::*; pub fn init() { - manager::WATCHED.with(Default::default); - manager::LINKED.with(Default::default); + manager::WATCHED.with(<_>::default); + manager::LINKED.with(<_>::default); } diff --git a/yazi-dds/src/lib.rs b/yazi-dds/src/lib.rs index 6a50bcde..66e45493 100644 --- a/yazi-dds/src/lib.rs +++ b/yazi-dds/src/lib.rs @@ -25,21 +25,21 @@ pub fn init() { let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); // Client - ID.init(yazi_shared::timestamp_us()); - PEERS.with(Default::default); + ID.init(yazi_boot::ARGS.client_id.unwrap_or(yazi_shared::timestamp_us())); + PEERS.with(<_>::default); QUEUE_TX.init(tx); QUEUE_RX.init(rx); // Server - CLIENTS.with(Default::default); - STATE.with(Default::default); + CLIENTS.with(<_>::default); + STATE.with(<_>::default); // Pubsub - LOCAL.with(Default::default); - REMOTE.with(Default::default); + LOCAL.with(<_>::default); + REMOTE.with(<_>::default); #[cfg(unix)] - USERS_CACHE.with(Default::default); + USERS_CACHE.with(<_>::default); // Env if let Some(s) = std::env::var("YAZI_ID").ok().filter(|s| !s.is_empty()) { diff --git a/yazi-dds/src/pump.rs b/yazi-dds/src/pump.rs index 39504768..2a9ebb33 100644 --- a/yazi-dds/src/pump.rs +++ b/yazi-dds/src/pump.rs @@ -42,7 +42,7 @@ impl Pump { let (trash_tx, trash_rx) = mpsc::unbounded_channel(); let (delete_tx, delete_rx) = mpsc::unbounded_channel(); - CT.with(Default::default); + CT.with(<_>::default); MOVE_TX.lock().replace(move_tx); TRASH_TX.lock().replace(trash_tx); DELETE_TX.lock().replace(delete_tx); diff --git a/yazi-plugin/src/lib.rs b/yazi-plugin/src/lib.rs index ed5cdace..ea2c42db 100644 --- a/yazi-plugin/src/lib.rs +++ b/yazi-plugin/src/lib.rs @@ -27,7 +27,7 @@ pub use opt::*; pub use runtime::*; pub fn init() -> anyhow::Result<()> { - CLIPBOARD.with(Default::default); + CLIPBOARD.with(<_>::default); crate::loader::init(); crate::init_lua()?; diff --git a/yazi-plugin/src/loader/mod.rs b/yazi-plugin/src/loader/mod.rs index 3dcbbf8c..6c59670a 100644 --- a/yazi-plugin/src/loader/mod.rs +++ b/yazi-plugin/src/loader/mod.rs @@ -6,7 +6,7 @@ mod require; pub use loader::*; use require::*; -pub(super) fn init() { LOADER.with(Default::default); } +pub(super) fn init() { LOADER.with(<_>::default); } pub(super) fn install(lua: &'static mlua::Lua) -> mlua::Result<()> { Require::install(lua)?;