mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
111 lines
2.7 KiB
Rust
111 lines
2.7 KiB
Rust
use anyhow::Result;
|
|
use yazi_core::tab::Folder;
|
|
use yazi_fs::FilesOp;
|
|
use yazi_macro::{act, render, succ};
|
|
use yazi_parser::mgr::UpdateFilesForm;
|
|
use yazi_shared::{data::Data, url::{UrlLike, UrlMapExt}};
|
|
use yazi_watcher::local::LINKED;
|
|
|
|
use crate::{Actor, Ctx};
|
|
|
|
pub struct UpdateFiles;
|
|
|
|
impl Actor for UpdateFiles {
|
|
type Form = UpdateFilesForm;
|
|
|
|
const NAME: &str = "update_files";
|
|
|
|
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
|
|
let revision = cx.current().entries.revision;
|
|
let linked: Vec<_> = LINKED.read().from_dir(form.op.cwd()).map(|u| form.op.chdir(u)).collect();
|
|
|
|
for op in [form.op].into_iter().chain(linked) {
|
|
cx.mgr.yanked.apply_op(&op);
|
|
Self::update_tab(cx, op).ok();
|
|
}
|
|
|
|
render!(cx.mgr.yanked.catchup_revision(false));
|
|
act!(mgr:hidden, cx).ok();
|
|
act!(mgr:sort, cx).ok();
|
|
|
|
if revision != cx.current().entries.revision {
|
|
act!(mgr:hover, cx)?;
|
|
act!(mgr:peek, cx)?;
|
|
act!(mgr:watch, cx)?;
|
|
act!(mgr:update_paged, cx)?;
|
|
}
|
|
succ!();
|
|
}
|
|
}
|
|
|
|
impl UpdateFiles {
|
|
fn update_tab(cx: &mut Ctx, op: FilesOp) -> Result<Data> {
|
|
let url = op.cwd();
|
|
cx.tab_mut().selected.apply_op(&op);
|
|
|
|
if url == cx.cwd() {
|
|
Self::update_current(cx, op)
|
|
} else if matches!(cx.parent(), Some(p) if *url == p.url) {
|
|
Self::update_parent(cx, op)
|
|
} else if matches!(cx.hovered(), Some(h) if *url == h.url) {
|
|
Self::update_hovered(cx, op)
|
|
} else {
|
|
Self::update_history(cx, op)
|
|
}
|
|
}
|
|
|
|
fn update_parent(cx: &mut Ctx, op: FilesOp) -> Result<Data> {
|
|
let tab = cx.tab_mut();
|
|
|
|
let key = tab.current.url.entry_key();
|
|
let leave = matches!(op, FilesOp::Deleting(_, ref keys) if keys.contains(&key));
|
|
|
|
if let Some(f) = tab.parent.as_mut() {
|
|
render!(f.update_pub(tab.id, op));
|
|
render!(f.hover(key));
|
|
}
|
|
|
|
if leave {
|
|
act!(mgr:leave, cx)?;
|
|
}
|
|
succ!();
|
|
}
|
|
|
|
fn update_current(cx: &mut Ctx, op: FilesOp) -> Result<Data> {
|
|
let calc = !matches!(op, FilesOp::Size(..) | FilesOp::Deleting(..));
|
|
|
|
let id = cx.tab().id;
|
|
if !cx.current_mut().update_pub(id, op) {
|
|
succ!();
|
|
}
|
|
|
|
if calc {
|
|
cx.tasks.prework_sorted(&cx.current().entries);
|
|
}
|
|
succ!();
|
|
}
|
|
|
|
fn update_hovered(cx: &mut Ctx, op: FilesOp) -> Result<Data> {
|
|
let (id, url) = (cx.tab().id, op.cwd());
|
|
let folder = cx.tab_mut().history.get_or_insert_with(url, |u| Folder::from(u));
|
|
|
|
if folder.update_pub(id, op) {
|
|
act!(mgr:peek, cx, true)?;
|
|
}
|
|
succ!();
|
|
}
|
|
|
|
fn update_history(cx: &mut Ctx, op: FilesOp) -> Result<Data> {
|
|
let tab = &mut cx.tab_mut();
|
|
let leave = tab.parent.as_ref().and_then(|f| f.url.pair2()).is_some_and(
|
|
|(pp, key)| matches!(&op, FilesOp::Deleting(parent, keys) if parent == pp && keys.contains(&key)),
|
|
);
|
|
|
|
tab.history.get_or_insert_with(op.cwd(), |u| Folder::from(u)).update_pub(tab.id, op);
|
|
if leave {
|
|
act!(mgr:leave, cx)?;
|
|
}
|
|
|
|
succ!();
|
|
}
|
|
}
|