From 753e00566485f481728feb6488c7a37f4e8a69ab Mon Sep 17 00:00:00 2001 From: sxyazi Date: Mon, 16 Sep 2024 18:54:01 +0800 Subject: [PATCH] .. --- yazi-config/preset/keymap.toml | 10 +++---- yazi-core/src/manager/commands/open.rs | 5 ++-- .../src/manager/commands/update_files.rs | 8 +++--- yazi-core/src/manager/watcher.rs | 17 +++++------ yazi-core/src/tab/commands/cd.rs | 4 +-- yazi-core/src/tab/preview.rs | 14 +++++----- yazi-core/src/tab/selected.rs | 4 +-- yazi-fm/src/lives/folder.rs | 2 +- yazi-fs/src/files.rs | 28 +++++++++---------- yazi-plugin/src/external/fd.rs | 2 +- yazi-plugin/src/external/rg.rs | 2 +- yazi-shared/src/fs/file.rs | 4 +-- yazi-shared/src/fs/loc.rs | 6 ++-- yazi-shared/src/fs/op.rs | 24 ++++++++-------- yazi-shared/src/fs/url.rs | 13 +++++++++ 15 files changed, 76 insertions(+), 67 deletions(-) diff --git a/yazi-config/preset/keymap.toml b/yazi-config/preset/keymap.toml index 7c08299e..adf82fc2 100644 --- a/yazi-config/preset/keymap.toml +++ b/yazi-config/preset/keymap.toml @@ -36,8 +36,8 @@ keymap = [ { on = "h", run = "leave", desc = "Go back to the parent directory" }, { on = "l", run = "enter", desc = "Enter the child directory" }, - { on = "", run = "leave", desc = "Go back to the parent directory" }, - { on = "", run = "enter", desc = "Enter the child directory" }, + { on = "", run = "leave", desc = "Go back to the parent directory" }, + { on = "", run = "enter", desc = "Enter the child directory" }, { on = "H", run = "back", desc = "Go back to the previous directory" }, { on = "L", run = "forward", desc = "Go forward to the next directory" }, @@ -249,9 +249,9 @@ keymap = [ { on = "c", run = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" }, { on = "C", run = [ "delete --cut --insert", "move 999" ], desc = "Cut until the EOL, and enter insert mode" }, { on = "x", run = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut the current character" }, - { on = "y", run = "yank", desc = "Copy the selected characters" }, - { on = "p", run = "paste", desc = "Paste the copied characters after the cursor" }, - { on = "P", run = "paste --before", desc = "Paste the copied characters before the cursor" }, + { on = "y", run = "yank", desc = "Copy the selected characters" }, + { on = "p", run = "paste", desc = "Paste the copied characters after the cursor" }, + { on = "P", run = "paste --before", desc = "Paste the copied characters before the cursor" }, # Undo/Redo { on = "u", run = "undo", desc = "Undo the last operation" }, diff --git a/yazi-core/src/manager/commands/open.rs b/yazi-core/src/manager/commands/open.rs index b0af78bf..5fe8b9ac 100644 --- a/yazi-core/src/manager/commands/open.rs +++ b/yazi-core/src/manager/commands/open.rs @@ -110,8 +110,9 @@ impl Manager { }; let find = |folder: Option<&Folder>| { - folder.is_some_and(|folder| { - p == *folder.loc && folder.files.iter().any(|f| f.is_dir() && url == f.url()) + folder.filter(|&f| p == *f.loc).is_some_and(|folder| { + let loc = url.to_loc(&folder.loc); + folder.files.iter().any(|f| f.is_dir() && f.urn() == loc.urn()) }) }; diff --git a/yazi-core/src/manager/commands/update_files.rs b/yazi-core/src/manager/commands/update_files.rs index 9fe09e6f..8f98b22a 100644 --- a/yazi-core/src/manager/commands/update_files.rs +++ b/yazi-core/src/manager/commands/update_files.rs @@ -25,7 +25,7 @@ impl Manager { }; let mut ops = vec![opt.op]; - for u in LINKED.read().from_dir(ops[0].url()) { + for u in LINKED.read().from_dir(ops[0].cwd()) { ops.push(ops[0].chroot(u)); } @@ -44,7 +44,7 @@ impl Manager { } fn update_tab(tab: &mut Tab, op: Cow, tasks: &Tasks) { - let url = op.url(); + let url = op.cwd(); tab.selected.apply_op(&op); if url == tab.cwd().url() { @@ -97,7 +97,7 @@ impl Manager { } fn update_hovered(tab: &mut Tab, op: Cow) { - let url = op.url(); + let url = op.cwd(); let folder = tab.history.entry(url.clone()).or_insert_with(|| Folder::from(url)); let foreign = matches!(op, Cow::Borrowed(_)); @@ -115,7 +115,7 @@ impl Manager { |(p, pp)| matches!(*op, FilesOp::Deleting(ref parent, ref urls) if *parent == pp && urls.contains(p)), ); - let folder = tab.history.entry(op.url().clone()).or_insert_with(|| Folder::from(op.url())); + let folder = tab.history.entry(op.cwd().clone()).or_insert_with(|| Folder::from(op.cwd())); let hovered = folder.hovered().filter(|_| folder.tracing).map(|h| h.urn_owned()); if folder.update(op.into_owned()) { folder.repos(hovered.as_ref().map(|u| u._deref())); diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index 9be552fd..6756361e 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -60,25 +60,22 @@ impl Watcher { } pub(super) fn trigger_dirs(&self, folders: &[&Folder]) { - let todo: Vec<_> = folders - .iter() - .filter(|&f| f.loc.is_regular()) - .map(|&f| (f.loc.url().clone(), f.cha)) - .collect(); + let todo: Vec<_> = + folders.iter().filter(|&f| f.loc.is_regular()).map(|&f| (f.loc.url_owned(), f.cha)).collect(); if todo.is_empty() { return; } - async fn go(url: Url, cha: Cha) { - let Some(cha) = Files::assert_stale(&url, cha).await else { return }; + async fn go(cwd: Url, cha: Cha) { + let Some(cha) = Files::assert_stale(&cwd, cha).await else { return }; - if let Ok(files) = Files::from_dir_bulk(&url).await { - FilesOp::Full(url, files, cha).emit(); + if let Ok(files) = Files::from_dir_bulk(&cwd).await { + FilesOp::Full(cwd, files, cha).emit(); } } tokio::spawn(async move { - futures::future::join_all(todo.into_iter().map(|(url, cha)| go(url, cha))).await; + futures::future::join_all(todo.into_iter().map(|(cwd, cha)| go(cwd, cha))).await; }); } diff --git a/yazi-core/src/tab/commands/cd.rs b/yazi-core/src/tab/commands/cd.rs index 6d2cf7ae..70c2daa6 100644 --- a/yazi-core/src/tab/commands/cd.rs +++ b/yazi-core/src/tab/commands/cd.rs @@ -45,14 +45,14 @@ impl Tab { // Take parent to history if let Some(rep) = self.parent.take() { - self.history.insert(rep.loc.url().clone(), rep); + self.history.insert(rep.loc.url_owned(), rep); } // Current let rep = self.history.remove_or(&opt.target); let rep = mem::replace(&mut self.current, rep); if rep.loc.is_regular() { - self.history.insert(rep.loc.url().clone(), rep); + self.history.insert(rep.loc.url_owned(), rep); } // Parent diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index 2ae1881a..9e29e43b 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -38,29 +38,29 @@ impl Preview { } pub fn go_folder(&mut self, file: File, dir: Option, force: bool) { - let (cha, url) = (file.cha, file.url_owned()); + let (cha, cwd) = (file.cha, file.url_owned()); self.go(file, MIME_DIR, force); - if self.content_unchanged(&url, cha) { + if self.content_unchanged(&cwd, cha) { return; } self.folder_loader.take().map(|h| h.abort()); self.folder_loader = Some(tokio::spawn(async move { - let Some(new) = Files::assert_stale(&url, dir.unwrap_or(Cha::dummy())).await else { + let Some(new) = Files::assert_stale(&cwd, dir.unwrap_or(Cha::dummy())).await else { return; }; - let Ok(rx) = Files::from_dir(&url).await else { return }; + let Ok(rx) = Files::from_dir(&cwd).await else { return }; let stream = UnboundedReceiverStream::new(rx).chunks_timeout(50000, Duration::from_millis(500)); pin!(stream); - let ticket = FilesOp::prepare(&url); + let ticket = FilesOp::prepare(&cwd); while let Some(chunk) = stream.next().await { - FilesOp::Part(url.clone(), chunk, ticket).emit(); + FilesOp::Part(cwd.clone(), chunk, ticket).emit(); } - FilesOp::Done(url, new, ticket).emit(); + FilesOp::Done(cwd, new, ticket).emit(); })); } diff --git a/yazi-core/src/tab/selected.rs b/yazi-core/src/tab/selected.rs index d98e47a7..75600396 100644 --- a/yazi-core/src/tab/selected.rs +++ b/yazi-core/src/tab/selected.rs @@ -112,10 +112,10 @@ impl Selected { }; if !removal.is_empty() { - self.remove_many(&removal, !op.url().is_search()); + self.remove_many(&removal, !op.cwd().is_search()); } if !addition.is_empty() { - self.add_many(&addition, !op.url().is_search()); + self.add_many(&addition, !op.cwd().is_search()); } } } diff --git a/yazi-fm/src/lives/folder.rs b/yazi-fm/src/lives/folder.rs index 8d1e06e3..2d0e854b 100644 --- a/yazi-fm/src/lives/folder.rs +++ b/yazi-fm/src/lives/folder.rs @@ -38,7 +38,7 @@ impl Folder { pub(super) fn register(lua: &Lua) -> mlua::Result<()> { lua.register_userdata_type::(|reg| { - reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.loc.url().clone())); + reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.loc.url_owned())); reg.add_field_method_get("files", |_, me| Files::make(0..me.files.len(), me, me.tab())); reg.add_field_method_get("stage", |lua, me| lua.create_any_userdata(me.stage)); reg.add_field_method_get("window", |_, me| Files::make(me.window.clone(), me, me.tab())); diff --git a/yazi-fs/src/files.rs b/yazi-fs/src/files.rs index 2fce87c0..c3fce4d9 100644 --- a/yazi-fs/src/files.rs +++ b/yazi-fs/src/files.rs @@ -96,19 +96,19 @@ impl Files { ) } - pub async fn assert_stale(url: &Url, cha: Cha) -> Option { - match fs::metadata(url).await.map(Cha::from) { + pub async fn assert_stale(cwd: &Url, cha: Cha) -> Option { + match fs::metadata(cwd).await.map(Cha::from) { Ok(c) if !c.is_dir() => { // FIXME: use `ErrorKind::NotADirectory` instead once it gets stabilized - FilesOp::IOErr(url.clone(), std::io::ErrorKind::AlreadyExists).emit(); + FilesOp::IOErr(cwd.clone(), std::io::ErrorKind::AlreadyExists).emit(); } Ok(c) if c.hits(cha) => {} Ok(c) => return Some(c), Err(e) => { - if maybe_exists(url).await { - FilesOp::IOErr(url.clone(), e.kind()).emit(); - } else if let Some(p) = url.parent_url() { - FilesOp::Deleting(p, vec![url.clone()]).emit(); + if maybe_exists(cwd).await { + FilesOp::IOErr(cwd.clone(), e.kind()).emit(); + } else if let Some(p) = cwd.parent_url() { + FilesOp::Deleting(p, vec![cwd.clone()]).emit(); } } } @@ -280,10 +280,9 @@ impl Files { } let (mut hidden, mut items) = if let Some(filter) = &self.filter { - files.into_iter().partition(|(_, f)| { - (f.is_hidden() && !self.show_hidden) - || !f.url().file_name().is_some_and(|s| filter.matches(s)) - }) + files + .into_iter() + .partition(|(_, f)| (f.is_hidden() && !self.show_hidden) || !filter.matches(f.name())) } else if self.show_hidden { (HashMap::new(), files) } else { @@ -330,10 +329,9 @@ impl Files { fn split_files(&self, files: impl IntoIterator) -> (Vec, Vec) { if let Some(filter) = &self.filter { - files.into_iter().partition(|f| { - (f.is_hidden() && !self.show_hidden) - || !f.url().file_name().is_some_and(|s| filter.matches(s)) - }) + files + .into_iter() + .partition(|f| (f.is_hidden() && !self.show_hidden) || !filter.matches(f.name())) } else if self.show_hidden { (vec![], files.into_iter().collect()) } else { diff --git a/yazi-plugin/src/external/fd.rs b/yazi-plugin/src/external/fd.rs index b26ae6aa..40de3262 100644 --- a/yazi-plugin/src/external/fd.rs +++ b/yazi-plugin/src/external/fd.rs @@ -29,7 +29,7 @@ pub fn fd(opt: FdOpt) -> Result> { tokio::spawn(async move { while let Ok(Some(line)) = it.next_line().await { - if let Ok(file) = File::from_search(&opt.cwd, opt.cwd.join(line)).await { + if let Ok(file) = File::from_search_item(&opt.cwd, opt.cwd.join(line)).await { tx.send(file).ok(); } } diff --git a/yazi-plugin/src/external/rg.rs b/yazi-plugin/src/external/rg.rs index 72e0d3bb..17440e2b 100644 --- a/yazi-plugin/src/external/rg.rs +++ b/yazi-plugin/src/external/rg.rs @@ -28,7 +28,7 @@ pub fn rg(opt: RgOpt) -> Result> { tokio::spawn(async move { while let Ok(Some(line)) = it.next_line().await { - if let Ok(file) = File::from_search(&opt.cwd, opt.cwd.join(line)).await { + if let Ok(file) = File::from_search_item(&opt.cwd, opt.cwd.join(line)).await { tx.send(file).ok(); } } diff --git a/yazi-shared/src/fs/file.rs b/yazi-shared/src/fs/file.rs index f94f14ae..e8c40e72 100644 --- a/yazi-shared/src/fs/file.rs +++ b/yazi-shared/src/fs/file.rs @@ -34,8 +34,8 @@ impl File { } #[inline] - pub async fn from_search(cwd: &Url, url: Url) -> Result { - let loc = Loc::from_search(cwd, url); + pub async fn from_search_item(cwd: &Url, url: Url) -> Result { + let loc = Loc::from_search_item(cwd, url); let meta = fs::symlink_metadata(loc.url()).await?; Ok(Self::from_loc(loc, meta).await) } diff --git a/yazi-shared/src/fs/loc.rs b/yazi-shared/src/fs/loc.rs index 1841c975..33562e79 100644 --- a/yazi-shared/src/fs/loc.rs +++ b/yazi-shared/src/fs/loc.rs @@ -36,7 +36,7 @@ impl Clone for Loc { fn clone(&self) -> Self { let url = self.url.clone(); let name = url.file_name().unwrap_or(OsStr::new("")) as *const OsStr; - let urn = if url.is_search() { self.twin_urn(&url) } else { name }; + let urn = if url.is_search_item() { self.twin_urn(&url) } else { name }; Self { url, urn, name } } } @@ -57,7 +57,7 @@ impl Loc { Self { url, urn, name: urn } } - pub fn from_search(cwd: &Url, url: Url) -> Self { + pub fn from_search_item(cwd: &Url, url: Url) -> Self { let urn = url.strip_prefix(cwd).unwrap_or(&url).as_os_str() as *const OsStr; let name = url.file_name().unwrap_or(OsStr::new("")) as *const OsStr; Self { url, urn, name } @@ -66,7 +66,7 @@ impl Loc { pub fn rebase(&self, parent: &Url) -> Self { let url = parent.join(self.name()); let name = url.file_name().unwrap_or(OsStr::new("")) as *const OsStr; - let urn = if url.is_search() { self.twin_urn(&url) } else { name }; + let urn = if url.is_search_item() { self.twin_urn(&url) } else { name }; Self { url, urn, name } } diff --git a/yazi-shared/src/fs/op.rs b/yazi-shared/src/fs/op.rs index 32338506..a15f3eb5 100644 --- a/yazi-shared/src/fs/op.rs +++ b/yazi-shared/src/fs/op.rs @@ -21,18 +21,18 @@ pub enum FilesOp { impl FilesOp { #[inline] - pub fn url(&self) -> &Url { + pub fn cwd(&self) -> &Url { match self { - Self::Full(url, ..) => url, - Self::Part(url, ..) => url, - Self::Done(url, ..) => url, - Self::Size(url, _) => url, - Self::IOErr(url, _) => url, + Self::Full(u, ..) => u, + Self::Part(u, ..) => u, + Self::Done(u, ..) => u, + Self::Size(u, _) => u, + Self::IOErr(u, _) => u, - Self::Creating(url, _) => url, - Self::Deleting(url, _) => url, - Self::Updating(url, _) => url, - Self::Upserting(url, _) => url, + Self::Creating(u, _) => u, + Self::Deleting(u, _) => u, + Self::Updating(u, _) => u, + Self::Upserting(u, _) => u, } } @@ -41,9 +41,9 @@ impl FilesOp { emit!(Call(Cmd::new("update_files").with_any("op", self), Layer::Manager)); } - pub fn prepare(url: &Url) -> u64 { + pub fn prepare(cwd: &Url) -> u64 { let ticket = FILES_TICKET.fetch_add(1, Ordering::Relaxed); - Self::Part(url.clone(), vec![], ticket).emit(); + Self::Part(cwd.clone(), vec![], ticket).emit(); ticket } diff --git a/yazi-shared/src/fs/url.rs b/yazi-shared/src/fs/url.rs index 7d1fc90a..a1f1b525 100644 --- a/yazi-shared/src/fs/url.rs +++ b/yazi-shared/src/fs/url.rs @@ -3,6 +3,8 @@ use std::{ffi::{OsStr, OsString}, fmt::{Debug, Display, Formatter}, ops::{Deref, use percent_encoding::{percent_decode_str, percent_encode, AsciiSet, CONTROLS}; use serde::{Deserialize, Serialize}; +use super::Loc; + const ENCODE_SET: &AsciiSet = &CONTROLS.add(b'#'); #[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -161,6 +163,14 @@ impl Url { pub fn is_hidden(&self) -> bool { self.file_name().map_or(false, |s| s.as_encoded_bytes().starts_with(b".")) } + + #[inline] + pub fn to_loc(&self, cwd: &Url) -> Loc { self.clone().into_loc(cwd) } + + #[inline] + pub fn into_loc(self, cwd: &Url) -> Loc { + if self.is_search_item() { Loc::from_search_item(cwd, self) } else { Loc::from(self) } + } } impl Url { @@ -189,6 +199,9 @@ impl Url { Self { scheme: UrlScheme::Search, path: self.path.clone(), frag: frag.to_owned() } } + #[inline] + pub fn is_search_item(&self) -> bool { self.scheme == UrlScheme::SearchItem } + #[inline] pub fn into_search_item(mut self) -> Self { self.scheme = UrlScheme::SearchItem;