From 63f81f643112183f5a172a27aa4e729360f258da Mon Sep 17 00:00:00 2001 From: sxyazi Date: Wed, 3 Jan 2024 09:46:47 +0800 Subject: [PATCH] refactor: replace `FilesOp::IOErr` with `FilesOp::Deleting` --- yazi-config/src/keymap/keymap.rs | 6 +- yazi-config/src/open/opener.rs | 18 +---- yazi-core/src/folder/folder.rs | 1 - yazi-core/src/input/commands/show.rs | 7 +- yazi-core/src/manager/commands/refresh.rs | 2 +- yazi-core/src/manager/commands/tab_create.rs | 2 +- .../src/manager/commands/update_files.rs | 76 +++++++++++-------- yazi-core/src/manager/watcher.rs | 13 ++-- yazi-core/src/select/commands/show.rs | 8 +- yazi-core/src/tab/commands/hidden.rs | 2 +- yazi-core/src/tab/commands/preview.rs | 7 +- yazi-core/src/tab/commands/sort.rs | 2 +- yazi-core/src/tab/preview.rs | 2 +- yazi-core/src/tab/tab.rs | 5 +- yazi-core/src/tasks/commands/open.rs | 7 +- yazi-core/src/tasks/commands/update.rs | 7 +- yazi-core/src/which/which.rs | 10 ++- yazi-fm/src/app/commands/stop.rs | 9 +-- yazi-fm/src/executor.rs | 2 +- yazi-shared/src/fs/op.rs | 4 +- 20 files changed, 82 insertions(+), 108 deletions(-) diff --git a/yazi-config/src/keymap/keymap.rs b/yazi-config/src/keymap/keymap.rs index 2455dbb8..b5f2c5e2 100644 --- a/yazi-config/src/keymap/keymap.rs +++ b/yazi-config/src/keymap/keymap.rs @@ -35,15 +35,15 @@ impl<'de> Deserialize<'de> for Keymap { let shadow = Shadow::deserialize(deserializer)?; - // TODO: remove this when v0.1.6 is released -- + // TODO: remove this when v0.2.0 is released -- if !shadow.input.keymap.iter().any(|c| c.on() == "") { println!( "WARNING: Default keybinding for `` is missing, please add a `{}` to the `[input]` section of `keymap.toml`. -In Yazi v0.1.6, `` previously hardcoded within the Input component has been moved to `keymap.toml` to allow users to customize it.", +In Yazi v0.2.0, `` previously hardcoded within the input component has been moved to `keymap.toml` to allow users to customize it.", r#"{ on = [ "" ], exec = "backspace" }"# ); } - // TODO: -- remove this when v0.1.6 is released + // TODO: -- remove this when v0.2.0 is released Ok(Self { manager: shadow.manager.keymap, diff --git a/yazi-config/src/open/opener.rs b/yazi-config/src/open/opener.rs index c3cb9a29..29f07d02 100644 --- a/yazi-config/src/open/opener.rs +++ b/yazi-config/src/open/opener.rs @@ -40,29 +40,13 @@ impl<'de> Deserialize<'de> for Opener { desc: Option, #[serde(rename = "for")] for_: Option, - - // TODO: remove this when v0.1.6 is released -- - display_name: Option, - // TODO: -- remove this when v0.1.6 is released } - let mut shadow = Shadow::deserialize(deserializer)?; + let shadow = Shadow::deserialize(deserializer)?; if shadow.exec.is_empty() { return Err(serde::de::Error::custom("`exec` cannot be empty")); } - // TODO: remove this when v0.1.6 is released -- - if shadow.display_name.is_some() { - println!( - "WARNING: `display_name` is deprecated and will be removed in Yazi v0.1.7. Use `desc` instead.\ne.g. {}\n\n", - r#"{ exec = 'nvim "$@"', display_name = "Edit" } ==> { exec = 'nvim "$@"', desc = "Edit" }"# - ); - } - if shadow.display_name.is_some() && shadow.desc.is_none() { - shadow.desc = shadow.display_name.clone(); - } - // TODO: -- remove this when v0.1.6 is released - let desc = shadow.desc.unwrap_or_else(|| shadow.exec.split_whitespace().next().unwrap().to_string()); diff --git a/yazi-core/src/folder/folder.rs b/yazi-core/src/folder/folder.rs index 45292d4f..2b8a9b35 100644 --- a/yazi-core/src/folder/folder.rs +++ b/yazi-core/src/folder/folder.rs @@ -34,7 +34,6 @@ impl Folder { FilesOp::Deleting(_, urls) => self.files.update_deleting(urls), FilesOp::Updating(_, files) => _ = self.files.update_updating(files), FilesOp::Upserting(_, files) => self.files.update_upserting(files), - _ => unreachable!(), } if !self.files.catchup_revision() { return false; diff --git a/yazi-core/src/input/commands/show.rs b/yazi-core/src/input/commands/show.rs index ce2a44b7..0ff6aa3a 100644 --- a/yazi-core/src/input/commands/show.rs +++ b/yazi-core/src/input/commands/show.rs @@ -1,4 +1,3 @@ -use anyhow::anyhow; use tokio::sync::mpsc; use yazi_config::popup::InputCfg; use yazi_shared::{emit, event::Exec, render, InputError, Layer}; @@ -11,11 +10,9 @@ pub struct Opt { } impl TryFrom<&Exec> for Opt { - type Error = anyhow::Error; + type Error = (); - fn try_from(e: &Exec) -> Result { - e.take_data().ok_or_else(|| anyhow!("invalid data")) - } + fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } } impl Input { diff --git a/yazi-core/src/manager/commands/refresh.rs b/yazi-core/src/manager/commands/refresh.rs index 27d7f54c..f538e4af 100644 --- a/yazi-core/src/manager/commands/refresh.rs +++ b/yazi-core/src/manager/commands/refresh.rs @@ -14,7 +14,7 @@ impl Manager { env::set_current_dir(self.cwd()).ok(); env::set_var("PWD", self.cwd()); - self.active_mut().apply_files_attrs(false); + self.active_mut().apply_files_attrs(); if let Some(p) = self.parent() { self.watcher.trigger_dirs(&[self.cwd(), &p.cwd]); diff --git a/yazi-core/src/manager/commands/tab_create.rs b/yazi-core/src/manager/commands/tab_create.rs index 556dabe1..2ad51d0a 100644 --- a/yazi-core/src/manager/commands/tab_create.rs +++ b/yazi-core/src/manager/commands/tab_create.rs @@ -31,7 +31,7 @@ impl Tabs { let mut tab = Tab::from(url); tab.conf = self.active().conf.clone(); - tab.apply_files_attrs(false); + tab.apply_files_attrs(); self.items.insert(self.idx + 1, tab); self.set_idx(self.idx + 1); diff --git a/yazi-core/src/manager/commands/update_files.rs b/yazi-core/src/manager/commands/update_files.rs index 19f79ad3..491d596f 100644 --- a/yazi-core/src/manager/commands/update_files.rs +++ b/yazi-core/src/manager/commands/update_files.rs @@ -13,43 +13,52 @@ impl TryFrom<&Exec> for Opt { } impl Manager { - // TODO: refactor this - fn handle_read(&mut self, op: FilesOp) { - let url = op.url().clone(); - let cwd = self.cwd().to_owned(); - let hovered = self.hovered().map(|h| h.url()); + fn update_parent(&mut self, op: FilesOp) { + let cwd = self.cwd().clone(); + let leave = matches!(op, FilesOp::Deleting(_, ref urls) if urls.contains(&cwd)); - if cwd == url { - render!(self.current_mut().update(op)); - } else if matches!(self.parent(), Some(p) if p.cwd == url) { - render!(self.active_mut().parent.as_mut().unwrap().update(op)); - } else if matches!(self.hovered(), Some(h) if h.url == url) { - self.active_mut().history.entry(url.clone()).or_insert_with(|| Folder::from(&url)); - self.active_mut().apply_files_attrs(true); - render!(self.active_mut().history.get_mut(&url).unwrap().update(op)); - self.peek(true); - } else { - self.active_mut().history.entry(url.clone()).or_insert_with(|| Folder::from(&url)).update(op); + if let Some(p) = self.active_mut().parent.as_mut() { + render!(p.update(op)); + render!(p.hover(&cwd)); } - render!(self.active_mut().parent.as_mut().is_some_and(|p| p.hover(&cwd))); + if leave { + self.active_mut().leave(()); + } + } + + fn update_current(&mut self, op: FilesOp, tasks: &Tasks) { + let hovered = self.hovered().map(|h| h.url()); + let calc = !matches!(op, FilesOp::Size(..) | FilesOp::Deleting(..)); + + render!(self.current_mut().update(op)); render!(hovered.as_ref().is_some_and(|h| self.current_mut().hover(h))); if hovered.as_ref() != self.hovered().map(|h| &h.url) { self.hover(None); } + if calc { + tasks.preload_sorted(&self.current().files); + } } - fn handle_ioerr(&mut self, op: FilesOp) { + fn update_hovered(&mut self, op: FilesOp) { let url = op.url(); - let op = FilesOp::Full(url.clone(), vec![]); + self.active_mut().history.entry(url.clone()).or_insert_with(|| Folder::from(url)).update(op); - if url == self.cwd() { - self.current_mut().update(op); + self.peek(true); + } + + fn update_history(&mut self, op: FilesOp) { + let leave = self.parent().and_then(|f| f.cwd.parent_url().map(|p| (&f.cwd, p))).is_some_and( + |(p, pp)| matches!(op, FilesOp::Deleting(ref parent, ref urls) if *parent == pp && urls.contains(p)), + ); + + let url = op.url(); + self.active_mut().history.entry(url.clone()).or_insert_with(|| Folder::from(url)).update(op); + + if leave { self.active_mut().leave(()); - render!(); - } else if matches!(self.parent(), Some(p) if &p.cwd == url) { - render!(self.active_mut().parent.as_mut().unwrap().update(op)); } } @@ -57,7 +66,6 @@ impl Manager { let Ok(opt) = opt.try_into() else { return; }; - let calc = !matches!(opt.op, FilesOp::Size(..) | FilesOp::IOErr(_) | FilesOp::Deleting(..)); let mut ops = vec![opt.op]; for u in self.watcher.linked.read().from_dir(ops[0].url()) { @@ -65,14 +73,18 @@ impl Manager { } for op in ops { - match op { - FilesOp::IOErr(..) => self.handle_ioerr(op), - _ => self.handle_read(op), - }; + let url = op.url(); + if self.cwd() == url { + self.update_current(op, tasks); + } else if matches!(self.parent(), Some(p) if p.cwd == *url) { + self.update_parent(op); + } else if matches!(self.hovered(), Some(h) if h.url == *url) { + self.update_hovered(op); + } else { + self.update_history(op); + } } - if calc { - tasks.preload_sorted(&self.current().files); - } + self.active_mut().apply_files_attrs(); } } diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index 3e272f05..6b251744 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -91,13 +91,12 @@ impl Watcher { tokio::spawn(async move { for u in urls { - let Ok(rx) = Files::from_dir(&u).await else { - FilesOp::IOErr(u).emit(); - return; - }; - - let files: Vec<_> = UnboundedReceiverStream::new(rx).collect().await; - FilesOp::Full(u, files).emit(); + if let Ok(rx) = Files::from_dir(&u).await { + let files: Vec<_> = UnboundedReceiverStream::new(rx).collect().await; + FilesOp::Full(u, files).emit(); + } else if let Some(p) = u.parent_url() { + FilesOp::Deleting(p, vec![u]).emit(); + } } }); } diff --git a/yazi-core/src/select/commands/show.rs b/yazi-core/src/select/commands/show.rs index 617a209f..d817df5e 100644 --- a/yazi-core/src/select/commands/show.rs +++ b/yazi-core/src/select/commands/show.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::Result; use tokio::sync::oneshot; use yazi_config::popup::SelectCfg; use yazi_shared::{emit, event::Exec, render, term::Term, Layer}; @@ -11,11 +11,9 @@ pub struct Opt { } impl TryFrom<&Exec> for Opt { - type Error = anyhow::Error; + type Error = (); - fn try_from(e: &Exec) -> Result { - e.take_data().ok_or_else(|| anyhow!("invalid data")) - } + fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } } impl Select { diff --git a/yazi-core/src/tab/commands/hidden.rs b/yazi-core/src/tab/commands/hidden.rs index 8761865a..333fd454 100644 --- a/yazi-core/src/tab/commands/hidden.rs +++ b/yazi-core/src/tab/commands/hidden.rs @@ -10,7 +10,7 @@ impl Tab { _ => !self.conf.show_hidden, }; - self.apply_files_attrs(false); + self.apply_files_attrs(); Manager::_hover(None); } } diff --git a/yazi-core/src/tab/commands/preview.rs b/yazi-core/src/tab/commands/preview.rs index 291e327d..6c35dabc 100644 --- a/yazi-core/src/tab/commands/preview.rs +++ b/yazi-core/src/tab/commands/preview.rs @@ -1,4 +1,3 @@ -use anyhow::anyhow; use yazi_plugin::utils::PreviewLock; use yazi_shared::{event::Exec, render}; @@ -9,11 +8,9 @@ pub struct Opt { } impl TryFrom<&Exec> for Opt { - type Error = anyhow::Error; + type Error = (); - fn try_from(e: &Exec) -> Result { - Ok(Self { lock: e.take_data().ok_or_else(|| anyhow!("invalid data"))? }) - } + fn try_from(e: &Exec) -> Result { Ok(Self { lock: e.take_data().ok_or(())? }) } } impl Tab { diff --git a/yazi-core/src/tab/commands/sort.rs b/yazi-core/src/tab/commands/sort.rs index 56a53292..20dbd96c 100644 --- a/yazi-core/src/tab/commands/sort.rs +++ b/yazi-core/src/tab/commands/sort.rs @@ -14,6 +14,6 @@ impl Tab { self.conf.sort_reverse = e.named.contains_key("reverse"); self.conf.sort_dir_first = e.named.contains_key("dir-first"); - self.apply_files_attrs(false); + self.apply_files_attrs(); } } diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index 0ab91c79..ea310cef 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -48,7 +48,7 @@ impl Preview { self.folder_handle.take().map(|h| h.abort()); self.folder_handle = Some(tokio::spawn(async move { let Ok(rx) = Files::from_dir(&file.url).await else { - FilesOp::IOErr(file.url).emit(); + file.url.parent_url().map(|p| FilesOp::Deleting(p, vec![file.url]).emit()); return; }; diff --git a/yazi-core/src/tab/tab.rs b/yazi-core/src/tab/tab.rs index 15ee5534..31694759 100644 --- a/yazi-core/src/tab/tab.rs +++ b/yazi-core/src/tab/tab.rs @@ -72,7 +72,7 @@ impl Tab { self.history.remove(url).unwrap_or_else(|| Folder::from(url)) } - pub fn apply_files_attrs(&mut self, just_preview: bool) { + pub fn apply_files_attrs(&mut self) { let apply = |f: &mut Folder| { let hovered = f.hovered().map(|h| h.url()); @@ -87,9 +87,6 @@ impl Tab { { apply(f); } - if just_preview { - return; - } apply(&mut self.current); if let Some(parent) = self.parent.as_mut() { diff --git a/yazi-core/src/tasks/commands/open.rs b/yazi-core/src/tasks/commands/open.rs index a29d92d8..ac2106b5 100644 --- a/yazi-core/src/tasks/commands/open.rs +++ b/yazi-core/src/tasks/commands/open.rs @@ -1,4 +1,3 @@ -use anyhow::anyhow; use yazi_config::open::Opener; use yazi_shared::{emit, event::Exec, fs::Url, Layer}; @@ -10,11 +9,9 @@ pub struct Opt { } impl TryFrom<&Exec> for Opt { - type Error = anyhow::Error; + type Error = (); - fn try_from(e: &Exec) -> Result { - e.take_data().ok_or_else(|| anyhow!("invalid data")) - } + fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } } impl Tasks { diff --git a/yazi-core/src/tasks/commands/update.rs b/yazi-core/src/tasks/commands/update.rs index 0cdcdb13..1a0a1dee 100644 --- a/yazi-core/src/tasks/commands/update.rs +++ b/yazi-core/src/tasks/commands/update.rs @@ -1,4 +1,3 @@ -use anyhow::anyhow; use yazi_shared::{emit, event::Exec, render, Layer}; use crate::tasks::{Tasks, TasksProgress}; @@ -8,11 +7,9 @@ pub struct Opt { } impl TryFrom<&Exec> for Opt { - type Error = anyhow::Error; + type Error = (); - fn try_from(e: &Exec) -> Result { - e.take_data().ok_or_else(|| anyhow!("invalid data")) - } + fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } } impl Tasks { diff --git a/yazi-core/src/which/which.rs b/yazi-core/src/which/which.rs index b70dcc18..df096002 100644 --- a/yazi-core/src/which/which.rs +++ b/yazi-core/src/which/which.rs @@ -1,7 +1,7 @@ use std::mem; use yazi_config::{keymap::{Control, Key}, KEYMAP}; -use yazi_shared::{emit, Layer}; +use yazi_shared::{emit, render, Layer}; pub struct Which { layer: Layer, @@ -18,15 +18,15 @@ impl Default for Which { } impl Which { - pub fn show(&mut self, key: &Key, layer: Layer) -> bool { + pub fn show(&mut self, key: &Key, layer: Layer) { self.layer = layer; self.times = 1; self.cands = KEYMAP.get(layer).iter().filter(|s| s.on.len() > 1 && &s.on[0] == key).collect(); self.visible = true; - true + render!(); } - pub fn press(&mut self, key: Key) -> bool { + pub fn type_(&mut self, key: Key) -> bool { self.cands = mem::take(&mut self.cands) .into_iter() .filter(|s| s.on.len() > self.times && s.on[self.times] == key) @@ -43,6 +43,8 @@ impl Which { } self.times += 1; + render!(); + true } } diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index bffe882c..53ce49bc 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use tokio::sync::oneshot; use yazi_shared::{event::Exec, term::Term}; @@ -9,11 +8,9 @@ pub struct Opt { tx: Option>, } -impl TryFrom<&Exec> for Opt { - type Error = anyhow::Error; - - fn try_from(e: &Exec) -> Result { - Ok(Self { state: e.args.first().map_or(false, |s| s == "true"), tx: e.take_data() }) +impl From<&Exec> for Opt { + fn from(e: &Exec) -> Self { + Self { state: e.args.first().map_or(false, |s| s == "true"), tx: e.take_data() } } } diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index dd1b8bce..2a3fc366 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -16,7 +16,7 @@ impl<'a> Executor<'a> { let cx = &mut self.app.cx; if cx.which.visible { - return cx.which.press(key); + return cx.which.type_(key); } if cx.help.visible && cx.help.type_(&key) { return true; diff --git a/yazi-shared/src/fs/op.rs b/yazi-shared/src/fs/op.rs index 401af58d..7310ae35 100644 --- a/yazi-shared/src/fs/op.rs +++ b/yazi-shared/src/fs/op.rs @@ -10,7 +10,6 @@ pub enum FilesOp { Full(Url, Vec), Part(Url, Vec, u64), Size(Url, BTreeMap), - IOErr(Url), Creating(Url, Vec), Deleting(Url, Vec), @@ -25,7 +24,6 @@ impl FilesOp { Self::Full(url, _) => url, Self::Part(url, ..) => url, Self::Size(url, _) => url, - Self::IOErr(url) => url, Self::Creating(url, _) => url, Self::Deleting(url, _) => url, @@ -80,7 +78,7 @@ impl FilesOp { Self::Full(_, files) => Self::Full(u, files!(files)), Self::Part(_, files, ticket) => Self::Part(u, files!(files), *ticket), Self::Size(_, map) => Self::Size(u, map.iter().map(|(k, v)| (new!(k), *v)).collect()), - Self::IOErr(_) => Self::IOErr(u), + Self::Creating(_, files) => Self::Creating(u, files!(files)), Self::Deleting(_, urls) => Self::Deleting(u, urls.iter().map(|u| new!(u)).collect()), Self::Updating(_, map) => Self::Updating(u, map!(map)),