From b066652b65d369105e2a36a52d5dd99b9f1d951c Mon Sep 17 00:00:00 2001 From: sxyazi Date: Sat, 10 Aug 2024 20:25:35 +0800 Subject: [PATCH] refactor: tab locking --- yazi-core/src/manager/commands/hover.rs | 14 +++++++---- yazi-core/src/manager/commands/refresh.rs | 22 ++++++++--------- .../src/manager/commands/update_files.rs | 2 +- yazi-core/src/manager/manager.rs | 24 +++++++++++++++---- yazi-core/src/manager/tabs.rs | 14 +++++++++++ yazi-core/src/notify/commands/push.rs | 2 +- yazi-core/src/notify/commands/tick.rs | 2 +- yazi-core/src/tab/commands/arrow.rs | 2 +- yazi-core/src/tab/commands/filter.rs | 4 ++-- yazi-core/src/tab/commands/find.rs | 2 +- yazi-core/src/tab/commands/hidden.rs | 2 +- yazi-core/src/tab/commands/reveal.rs | 2 +- yazi-plugin/src/opt.rs | 2 +- yazi-plugin/src/utils/layer.rs | 2 +- yazi-plugin/src/utils/sync.rs | 4 +--- yazi-proxy/src/completion.rs | 5 +--- yazi-proxy/src/input.rs | 2 +- yazi-proxy/src/manager.rs | 6 ++--- yazi-proxy/src/tab.rs | 6 ++--- yazi-scheduler/src/process/process.rs | 2 +- yazi-shared/src/event/cmd.rs | 8 +++++-- 21 files changed, 81 insertions(+), 48 deletions(-) diff --git a/yazi-core/src/manager/commands/hover.rs b/yazi-core/src/manager/commands/hover.rs index cfcc2331..0fd3f9d6 100644 --- a/yazi-core/src/manager/commands/hover.rs +++ b/yazi-core/src/manager/commands/hover.rs @@ -7,13 +7,19 @@ use crate::manager::Manager; pub struct Opt { url: Option, + tab: Option, } impl From for Opt { - fn from(mut c: Cmd) -> Self { Self { url: c.take_first().and_then(Data::into_url) } } + fn from(mut c: Cmd) -> Self { + Self { + url: c.take_first().and_then(Data::into_url), + tab: c.get("tab").and_then(Data::as_usize), + } + } } impl From> for Opt { - fn from(url: Option) -> Self { Self { url } } + fn from(url: Option) -> Self { Self { url, tab: None } } } impl Manager { @@ -21,11 +27,11 @@ impl Manager { let opt = opt.into() as Opt; // Hover on the file - render!(self.current_mut().repos(opt.url.as_ref())); + render!(self.current_or_mut(opt.tab).repos(opt.url.as_ref())); if opt.url.zip(self.current().hovered()).is_some_and(|(u, f)| u == f.url) { // `hover(Some)` occurs after user actions, such as create, rename, reveal, etc. // At this point, it's intuitive to track the location of this file regardless. - self.current_mut().tracing = true; + self.current_or_mut(opt.tab).tracing = true; } // Repeek diff --git a/yazi-core/src/manager/commands/refresh.rs b/yazi-core/src/manager/commands/refresh.rs index 553e8cb7..346cd182 100644 --- a/yazi-core/src/manager/commands/refresh.rs +++ b/yazi-core/src/manager/commands/refresh.rs @@ -7,17 +7,6 @@ use yazi_shared::event::Cmd; use crate::{manager::Manager, tasks::Tasks}; impl Manager { - fn title(&self) -> String { - let home = dirs::home_dir().unwrap_or_default(); - let cwd = if let Some(p) = self.cwd().strip_prefix(home) { - format!("~{}{}", MAIN_SEPARATOR, p.display()) - } else { - format!("{}", self.cwd().display()) - }; - - MANAGER.title_format.replace("{cwd}", &cwd) - } - pub fn refresh(&mut self, _: Cmd, tasks: &Tasks) { env::set_current_dir(self.cwd()).ok(); env::set_var("PWD", self.cwd()); @@ -39,4 +28,15 @@ impl Manager { tasks.prework_sorted(&self.current().files); } + + fn title(&self) -> String { + let home = dirs::home_dir().unwrap_or_default(); + let cwd = if let Some(p) = self.cwd().strip_prefix(home) { + format!("~{}{}", MAIN_SEPARATOR, p.display()) + } else { + format!("{}", self.cwd().display()) + }; + + MANAGER.title_format.replace("{cwd}", &cwd) + } } diff --git a/yazi-core/src/manager/commands/update_files.rs b/yazi-core/src/manager/commands/update_files.rs index 3f5e630b..e49bab2f 100644 --- a/yazi-core/src/manager/commands/update_files.rs +++ b/yazi-core/src/manager/commands/update_files.rs @@ -86,7 +86,7 @@ impl Manager { return; } - ManagerProxy::hover(None); // Re-hover in next loop + ManagerProxy::hover(None, tab.idx); // Re-hover in next loop ManagerProxy::update_paged(); // Update for paged files in next loop if calc { tasks.prework_sorted(&tab.current.files); diff --git a/yazi-core/src/manager/manager.rs b/yazi-core/src/manager/manager.rs index 91831f0a..4214e1bf 100644 --- a/yazi-core/src/manager/manager.rs +++ b/yazi-core/src/manager/manager.rs @@ -39,19 +39,33 @@ impl Manager { pub fn active_mut(&mut self) -> &mut Tab { self.tabs.active_mut() } #[inline] - pub fn current(&self) -> &Folder { &self.tabs.active().current } + pub fn active_or(&self, idx: Option) -> &Tab { self.tabs.active_or(idx) } #[inline] - pub fn current_mut(&mut self) -> &mut Folder { &mut self.tabs.active_mut().current } + pub fn active_or_mut(&mut self, idx: Option) -> &mut Tab { self.tabs.active_or_mut(idx) } #[inline] - pub fn parent(&self) -> Option<&Folder> { self.tabs.active().parent.as_ref() } + pub fn current(&self) -> &Folder { &self.active().current } #[inline] - pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered() } + pub fn current_mut(&mut self) -> &mut Folder { &mut self.active_mut().current } #[inline] - pub fn hovered_folder(&self) -> Option<&Folder> { self.tabs.active().hovered_folder() } + pub fn current_or(&self, idx: Option) -> &Folder { &self.active_or(idx).current } + + #[inline] + pub fn current_or_mut(&mut self, idx: Option) -> &mut Folder { + &mut self.active_or_mut(idx).current + } + + #[inline] + pub fn parent(&self) -> Option<&Folder> { self.active().parent.as_ref() } + + #[inline] + pub fn hovered(&self) -> Option<&File> { self.active().current.hovered() } + + #[inline] + pub fn hovered_folder(&self) -> Option<&Folder> { self.active().hovered_folder() } #[inline] pub fn selected_or_hovered(&self, reorder: bool) -> Box + '_> { diff --git a/yazi-core/src/manager/tabs.rs b/yazi-core/src/manager/tabs.rs index 100f6afe..91cf11ea 100644 --- a/yazi-core/src/manager/tabs.rs +++ b/yazi-core/src/manager/tabs.rs @@ -59,6 +59,20 @@ impl Tabs { #[inline] pub(super) fn active_mut(&mut self) -> &mut Tab { &mut self.items[self.cursor] } + + #[inline] + pub fn active_or(&self, idx: Option) -> &Tab { + idx.and_then(|i| self.items.get(i)).unwrap_or(&self.items[self.cursor]) + } + + #[inline] + pub(super) fn active_or_mut(&mut self, idx: Option) -> &mut Tab { + if let Some(i) = idx.filter(|&i| i < self.items.len()) { + &mut self.items[i] + } else { + &mut self.items[self.cursor] + } + } } impl Deref for Tabs { diff --git a/yazi-core/src/notify/commands/push.rs b/yazi-core/src/notify/commands/push.rs index 0851895f..facc5888 100644 --- a/yazi-core/src/notify/commands/push.rs +++ b/yazi-core/src/notify/commands/push.rs @@ -12,6 +12,6 @@ impl Notify { msg.timeout += instant - self.messages.first().map_or(instant, |m| m.instant); self.messages.push(msg); - emit!(Call(Cmd::args("update_notify", vec![0.to_string()]), Layer::App)); + emit!(Call(Cmd::args("update_notify", &[0]), Layer::App)); } } diff --git a/yazi-core/src/notify/commands/tick.rs b/yazi-core/src/notify/commands/tick.rs index d37779c9..8e3f1bef 100644 --- a/yazi-core/src/notify/commands/tick.rs +++ b/yazi-core/src/notify/commands/tick.rs @@ -62,7 +62,7 @@ impl Notify { self.tick_handle = Some(tokio::spawn(async move { tokio::time::sleep(interval).await; - emit!(Call(Cmd::args("update_notify", vec![interval.as_secs_f64().to_string()]), Layer::App)); + emit!(Call(Cmd::args("update_notify", &[interval.as_secs_f64()]), Layer::App)); })); } } diff --git a/yazi-core/src/tab/commands/arrow.rs b/yazi-core/src/tab/commands/arrow.rs index 867bd918..cd6d3522 100644 --- a/yazi-core/src/tab/commands/arrow.rs +++ b/yazi-core/src/tab/commands/arrow.rs @@ -41,7 +41,7 @@ impl Tab { } } - ManagerProxy::hover(None); + ManagerProxy::hover(None, self.idx); render!(); } } diff --git a/yazi-core/src/tab/commands/filter.rs b/yazi-core/src/tab/commands/filter.rs index a6fdfc69..80a108f7 100644 --- a/yazi-core/src/tab/commands/filter.rs +++ b/yazi-core/src/tab/commands/filter.rs @@ -40,7 +40,7 @@ impl Tab { let (Ok(s) | Err(InputError::Typed(s))) = result else { continue }; emit!(Call( - Cmd::args("filter_do", vec![s]) + Cmd::args("filter_do", &[s]) .with_bool("smart", opt.case == FilterCase::Smart) .with_bool("insensitive", opt.case == FilterCase::Insensitive) .with_bool("done", done), @@ -72,7 +72,7 @@ impl Tab { self.current.repos(hovered.as_ref()); if self.current.hovered().map(|f| &f.url) != hovered.as_ref() { - ManagerProxy::hover(None); + ManagerProxy::hover(None, self.idx); } render!(); diff --git a/yazi-core/src/tab/commands/find.rs b/yazi-core/src/tab/commands/find.rs index 9dbd43cc..90f04943 100644 --- a/yazi-core/src/tab/commands/find.rs +++ b/yazi-core/src/tab/commands/find.rs @@ -40,7 +40,7 @@ impl Tab { while let Some(Ok(s)) | Some(Err(InputError::Typed(s))) = rx.next().await { emit!(Call( - Cmd::args("find_do", vec![s]) + Cmd::args("find_do", &[s]) .with_bool("previous", opt.prev) .with_bool("smart", opt.case == FilterCase::Smart) .with_bool("insensitive", opt.case == FilterCase::Insensitive), diff --git a/yazi-core/src/tab/commands/hidden.rs b/yazi-core/src/tab/commands/hidden.rs index 62b6e93c..2ae4d6e6 100644 --- a/yazi-core/src/tab/commands/hidden.rs +++ b/yazi-core/src/tab/commands/hidden.rs @@ -15,7 +15,7 @@ impl Tab { self.apply_files_attrs(); if hovered.as_ref() != self.current.hovered().map(|f| &f.url) { - ManagerProxy::hover(hovered); + ManagerProxy::hover(hovered, self.idx); } else if self.current.hovered().is_some_and(|f| f.is_dir()) { ManagerProxy::peek(true); } diff --git a/yazi-core/src/tab/commands/reveal.rs b/yazi-core/src/tab/commands/reveal.rs index a2171147..46df9fb8 100644 --- a/yazi-core/src/tab/commands/reveal.rs +++ b/yazi-core/src/tab/commands/reveal.rs @@ -31,6 +31,6 @@ impl Tab { self.cd(parent.clone()); FilesOp::Creating(parent, vec![File::from_dummy(opt.target.clone(), None)]).emit(); - ManagerProxy::hover(Some(opt.target)); + ManagerProxy::hover(Some(opt.target), self.idx); } } diff --git a/yazi-plugin/src/opt.rs b/yazi-plugin/src/opt.rs index 3407a497..38615e6c 100644 --- a/yazi-plugin/src/opt.rs +++ b/yazi-plugin/src/opt.rs @@ -33,7 +33,7 @@ impl TryFrom for Opt { impl From for Cmd { fn from(value: Opt) -> Self { let mut cmd = - Cmd::args("", vec![value.id]).with_bool("sync", value.sync).with_any("args", value.args); + Cmd::args("", &[value.id]).with_bool("sync", value.sync).with_any("args", value.args); if let Some(cb) = value.cb { cmd = cmd.with_any("callback", cb); diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 40c49d8a..2ec96b91 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -38,7 +38,7 @@ impl Utils { let cand = cand?; cands.push(Control { on: Self::parse_keys(cand.raw_get("on")?)?, - run: vec![Cmd::args("callback", vec![i.to_string()]).with_any("tx", tx.clone())], + run: vec![Cmd::args("callback", &[i]).with_any("tx", tx.clone())], desc: cand.raw_get("desc").ok(), }); } diff --git a/yazi-plugin/src/utils/sync.rs b/yazi-plugin/src/utils/sync.rs index 1e185b3b..b67941e3 100644 --- a/yazi-plugin/src/utils/sync.rs +++ b/yazi-plugin/src/utils/sync.rs @@ -71,9 +71,7 @@ impl Utils { }; emit!(Call( - Cmd::args("plugin", vec![name.to_owned()]) - .with_bool("sync", true) - .with_any("callback", callback), + Cmd::args("plugin", &[name]).with_bool("sync", true).with_any("callback", callback), Layer::App )); diff --git a/yazi-proxy/src/completion.rs b/yazi-proxy/src/completion.rs index 583c4b75..ca5c7174 100644 --- a/yazi-proxy/src/completion.rs +++ b/yazi-proxy/src/completion.rs @@ -10,9 +10,6 @@ impl CompletionProxy { #[inline] pub fn trigger(word: &str, ticket: usize) { - emit!(Call( - Cmd::args("trigger", vec![word.to_owned()]).with("ticket", ticket), - Layer::Completion - )); + emit!(Call(Cmd::args("trigger", &[word]).with("ticket", ticket), Layer::Completion)); } } diff --git a/yazi-proxy/src/input.rs b/yazi-proxy/src/input.rs index 5db82551..46a97267 100644 --- a/yazi-proxy/src/input.rs +++ b/yazi-proxy/src/input.rs @@ -14,6 +14,6 @@ impl InputProxy { #[inline] pub fn complete(word: &str, ticket: usize) { - emit!(Call(Cmd::args("complete", vec![word.to_owned()]).with("ticket", ticket), Layer::Input)); + emit!(Call(Cmd::args("complete", &[word]).with("ticket", ticket), Layer::Input)); } } diff --git a/yazi-proxy/src/manager.rs b/yazi-proxy/src/manager.rs index 2bfb5e0f..85fca9ad 100644 --- a/yazi-proxy/src/manager.rs +++ b/yazi-proxy/src/manager.rs @@ -11,9 +11,9 @@ impl ManagerProxy { } #[inline] - pub fn hover(url: Option) { + pub fn hover(url: Option, tab: usize) { emit!(Call( - Cmd::args("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])), + Cmd::args("hover", &url.map_or_else(Vec::new, |u| vec![u])).with("tab", tab), Layer::Manager )); } @@ -49,7 +49,7 @@ impl ManagerProxy { #[inline] pub fn update_paged_by(page: usize, only_if: &Url) { emit!(Call( - Cmd::args("update_paged", vec![page.to_string()]).with_any("only-if", only_if.clone()), + Cmd::args("update_paged", &[page]).with_any("only-if", only_if.clone()), Layer::Manager )); } diff --git a/yazi-proxy/src/tab.rs b/yazi-proxy/src/tab.rs index e6c4170f..977deaad 100644 --- a/yazi-proxy/src/tab.rs +++ b/yazi-proxy/src/tab.rs @@ -7,18 +7,18 @@ pub struct TabProxy; impl TabProxy { #[inline] pub fn cd(target: &Url) { - emit!(Call(Cmd::args("cd", vec![target.to_string()]), Layer::Manager)); + emit!(Call(Cmd::args("cd", &[target]), Layer::Manager)); } #[inline] pub fn reveal(target: &Url) { - emit!(Call(Cmd::args("reveal", vec![target.to_string()]), Layer::Manager)); + emit!(Call(Cmd::args("reveal", &[target]), Layer::Manager)); } #[inline] pub fn search_do(opt: SearchOpt) { emit!(Call( - Cmd::args("search_do", vec![opt.subject]).with("via", opt.via).with("args", opt.args_raw), + Cmd::args("search_do", &[opt.subject]).with("via", opt.via).with("args", opt.args_raw), Layer::Manager )); } diff --git a/yazi-scheduler/src/process/process.rs b/yazi-scheduler/src/process/process.rs index 13b745b4..04db007a 100644 --- a/yazi-scheduler/src/process/process.rs +++ b/yazi-scheduler/src/process/process.rs @@ -21,7 +21,7 @@ impl Process { let (id, cmd) = (task.id, task.cmd.clone()); let result = super::shell(task.into()); if let Err(e) = result { - AppProxy::notify_warn(&cmd.to_string_lossy(), &format!("Failed to spawn process: {e}")); + AppProxy::notify_warn(&cmd.to_string_lossy(), format!("Failed to spawn process: {e}")); return self.succ(id); } diff --git a/yazi-shared/src/event/cmd.rs b/yazi-shared/src/event/cmd.rs index 37c9f54c..10ae9304 100644 --- a/yazi-shared/src/event/cmd.rs +++ b/yazi-shared/src/event/cmd.rs @@ -16,10 +16,14 @@ impl Cmd { pub fn new(name: &str) -> Self { Self { name: name.to_owned(), ..Default::default() } } #[inline] - pub fn args(name: &str, args: Vec) -> Self { + pub fn args(name: &str, args: &[impl ToString]) -> Self { Self { name: name.to_owned(), - args: args.into_iter().enumerate().map(|(i, s)| (i.to_string(), Data::String(s))).collect(), + args: args + .iter() + .enumerate() + .map(|(i, s)| (i.to_string(), Data::String(s.to_string()))) + .collect(), } }