diff --git a/Cargo.lock b/Cargo.lock index 3d25ad41..e99e9f20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,6 +60,55 @@ dependencies = [ "thiserror", ] +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + [[package]] name = "anyhow" version = "1.0.72" @@ -218,12 +267,59 @@ dependencies = [ "winapi", ] +[[package]] +name = "clap" +version = "4.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + [[package]] name = "color_quant" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "concurrent-queue" version = "2.2.0" @@ -238,6 +334,7 @@ name = "config" version = "0.1.0" dependencies = [ "anyhow", + "clap", "crossterm 0.27.0", "futures", "glob", @@ -419,6 +516,27 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -664,6 +782,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.2" @@ -768,6 +892,17 @@ dependencies = [ "libc", ] +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "itoa" version = "1.0.9" @@ -845,6 +980,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + [[package]] name = "lock_api" version = "0.4.10" @@ -1254,6 +1395,19 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustix" +version = "0.38.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "ryu" version = "1.0.15" @@ -1424,6 +1578,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "2.0.28" @@ -1741,6 +1901,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "valuable" version = "0.1.0" diff --git a/app/src/app.rs b/app/src/app.rs index 2bb3e21f..b7722650 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -1,7 +1,8 @@ use core::{emit, files::FilesOp, input::InputMode, Event}; +use std::os::unix::prelude::OsStrExt; use anyhow::{Ok, Result}; -use config::keymap::{Control, Key, KeymapLayer}; +use config::{keymap::{Control, Key, KeymapLayer}, BOOT}; use crossterm::event::KeyEvent; use shared::{absolute_path, Term}; use tokio::sync::oneshot; @@ -24,7 +25,10 @@ impl App { while let Some(event) = app.signals.recv().await { match event { - Event::Quit => break, + Event::Quit => { + app.dispatch_quit(); + break; + } Event::Key(key) => app.dispatch_key(key), Event::Paste(str) => app.dispatch_paste(str), Event::Render(_) => app.dispatch_render(), @@ -37,6 +41,13 @@ impl App { Ok(()) } + fn dispatch_quit(&mut self) { + if let Some(p) = &BOOT.cwd_file { + let cwd = self.cx.manager.cwd().as_os_str(); + std::fs::write(p, cwd.as_bytes()).ok(); + } + } + fn dispatch_key(&mut self, key: KeyEvent) { let key = Key::from(key); if Executor::handle(&mut self.cx, key) { diff --git a/app/src/executor.rs b/app/src/executor.rs index 7eea35b3..437bcef4 100644 --- a/app/src/executor.rs +++ b/app/src/executor.rs @@ -86,7 +86,7 @@ impl Executor { "open" => cx.manager.open(exec.named.contains_key("interactive")), "yank" => cx.manager.yank(exec.named.contains_key("cut")), "paste" => { - let dest = cx.manager.current().cwd.clone(); + let dest = cx.manager.cwd().to_owned(); let (cut, src) = cx.manager.yanked(); let force = exec.named.contains_key("force"); @@ -133,7 +133,7 @@ impl Executor { // Tabs "tab_create" => { let path = if exec.named.contains_key("current") { - cx.manager.current().cwd.clone() + cx.manager.cwd().to_owned() } else { exec.args.get(0).map(|p| p.into()).unwrap_or("/".into()) }; diff --git a/config/Cargo.toml b/config/Cargo.toml index f259b1ef..a2c2e90a 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -8,6 +8,7 @@ shared = { path = "../shared" } # External dependencies anyhow = "^1" +clap = { version = "^4", features = [ "derive" ] } crossterm = "^0" futures = "^0" glob = "^0" diff --git a/config/src/boot/boot.rs b/config/src/boot/boot.rs index a314ef24..dc41c5d0 100644 --- a/config/src/boot/boot.rs +++ b/config/src/boot/boot.rs @@ -1,16 +1,28 @@ use std::{env, fs, path::PathBuf}; +use clap::Parser; + #[derive(Debug)] pub struct Boot { pub cwd: PathBuf, + pub cwd_file: Option, pub cache_dir: PathBuf, pub state_dir: PathBuf, } +#[derive(Debug, Parser)] +struct Args { + /// Write the cwd on exit to this file + #[arg(long)] + cwd_file: Option, +} + impl Default for Boot { fn default() -> Self { + let args = Args::parse(); let boot = Self { cwd: env::current_dir().unwrap_or("/".into()), + cwd_file: args.cwd_file, cache_dir: env::temp_dir().join("yazi"), state_dir: xdg::BaseDirectories::with_prefix("yazi").unwrap().get_state_home(), }; diff --git a/core/src/manager/manager.rs b/core/src/manager/manager.rs index f2f0790a..be38d48a 100644 --- a/core/src/manager/manager.rs +++ b/core/src/manager/manager.rs @@ -1,4 +1,4 @@ -use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, mem, path::PathBuf}; +use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, mem, path::{Path, PathBuf}}; use anyhow::Error; use config::{open::Opener, OPEN}; @@ -28,9 +28,9 @@ impl Manager { } pub fn refresh(&mut self) { - env::set_current_dir(&self.current().cwd).ok(); + env::set_current_dir(self.cwd()).ok(); - self.watcher.trigger(&self.current().cwd); + self.watcher.trigger(self.cwd()); if let Some(p) = self.parent() { self.watcher.trigger(&p.cwd); } @@ -174,7 +174,7 @@ impl Manager { } pub fn create(&self) -> bool { - let cwd = self.current().cwd.clone(); + let cwd = self.cwd().to_owned(); tokio::spawn(async move { let result = emit!(Input(InputOpt::top("Create:"))); @@ -248,7 +248,7 @@ impl Manager { pub fn update_read(&mut self, op: FilesOp) -> bool { let path = op.path(); - let cwd = self.current().cwd.clone(); + let cwd = self.cwd().to_owned(); let hovered = self.hovered().map(|h| h.path()); let mut b = if cwd == path && !self.current().in_search { @@ -277,7 +277,7 @@ impl Manager { pub fn update_search(&mut self, op: FilesOp) -> bool { let path = op.path(); - if self.current().in_search && self.current().cwd == path { + if self.current().in_search && self.cwd() == path { return self.current_mut().update(op); } @@ -293,7 +293,7 @@ impl Manager { let path = op.path(); let op = FilesOp::read_empty(&path); - if path == self.current().cwd { + if path == self.cwd() { self.current_mut().update(op); } else if matches!(self.parent(), Some(p) if p.cwd == path) { self.active_mut().parent.as_mut().unwrap().update(op); @@ -338,6 +338,9 @@ impl Manager { } impl Manager { + #[inline] + pub fn cwd(&self) -> &Path { &self.current().cwd } + #[inline] pub fn tabs(&self) -> &Tabs { &self.tabs }