fix: propagate and update the directory node till its first parent when the files of a directory change (#1987)

This commit is contained in:
三咲雅 · Misaki Masa 2024-12-04 22:44:35 +08:00 committed by GitHub
parent b4d1174f46
commit 2771aef677
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 29 deletions

View file

@ -25,12 +25,8 @@ impl Manager {
return; return;
}; };
let mut ops = vec![opt.op]; let linked: Vec<_> = LINKED.read().from_dir(opt.op.cwd()).map(|u| opt.op.rebase(u)).collect();
for u in LINKED.read().from_dir(ops[0].cwd()) { for op in [opt.op].into_iter().chain(linked) {
ops.push(ops[0].rebase(u));
}
for op in ops {
let idx = self.tabs.cursor; let idx = self.tabs.cursor;
self.yanked.apply_op(&op); self.yanked.apply_op(&op);

View file

@ -16,29 +16,27 @@ impl DerefMut for Linked {
} }
impl Linked { impl Linked {
pub fn from_dir(&self, url: &Url) -> Vec<&Url> { pub fn from_dir<'a, 'b>(&'a self, url: &'b Url) -> Box<dyn Iterator<Item = &'a Url> + 'b>
where
'a: 'b,
{
if let Some(to) = self.get(url) { if let Some(to) = self.get(url) {
self.iter().filter(|(k, v)| *v == to && *k != url).map(|(k, _)| k).collect() Box::new(self.iter().filter(move |(k, v)| *v == to && *k != url).map(|(k, _)| k))
} else { } else {
self.iter().filter(|(_, v)| *v == url).map(|(k, _)| k).collect() Box::new(self.iter().filter(move |(_, v)| *v == url).map(|(k, _)| k))
} }
} }
pub fn from_file(&self, url: &Url) -> Vec<Url> { pub fn from_file(&self, url: &Url) -> Vec<Url> {
if self.is_empty() { if self.is_empty() {
return Default::default(); return vec![];
} }
let Some(p) = url.parent_url() else { let Some(p) = url.parent_url() else {
return Default::default(); return vec![];
}; };
let relatives = self.from_dir(&p);
if relatives.is_empty() {
return Default::default();
}
let name = url.file_name().unwrap(); let name = url.file_name().unwrap();
relatives.into_iter().map(|u| u.join(name)).collect() self.from_dir(&p).map(|u| u.join(name)).collect()
} }
} }

View file

@ -34,9 +34,7 @@ impl Watcher {
if event.kind.is_access() { if event.kind.is_access() {
return; return;
} }
for path in event.paths { Self::push_files_impl(&out_tx_, event.paths.into_iter().map(Url::from));
out_tx_.send(Url::from(path)).ok();
}
}; };
let config = notify::Config::default().with_poll_interval(Duration::from_millis(500)); let config = notify::Config::default().with_poll_interval(Duration::from_millis(500));
@ -55,11 +53,23 @@ impl Watcher {
self.in_tx.send(new.into_iter().cloned().collect()).ok(); self.in_tx.send(new.into_iter().cloned().collect()).ok();
} }
pub(super) fn push_files(&self, url: Vec<Url>) { pub(super) fn push_files(&self, urls: Vec<Url>) {
let watched = WATCHED.read(); Self::push_files_impl(&self.out_tx, urls.into_iter());
for u in url { }
if u.parent_url().is_some_and(|p| watched.contains(&p)) {
self.out_tx.send(u).ok(); fn push_files_impl(out_tx: &mpsc::UnboundedSender<Url>, urls: impl Iterator<Item = Url>) {
let (mut parents, watched) = (HashSet::new(), WATCHED.read());
for u in urls {
let Some(p) = u.parent_url() else { continue };
if !watched.contains(&p)
&& LINKED.read().from_dir(&p).find(|&u| watched.contains(u)).is_none()
{
continue;
}
out_tx.send(u).ok();
if !parents.contains(&p) {
out_tx.send(p.clone()).ok();
parents.insert(p);
} }
} }
} }

View file

@ -1,4 +1,3 @@
table.unpack = table.unpack or unpack
function Err(s, ...) return Error.custom(string.format(s, ...)) end function Err(s, ...) return Error.custom(string.format(s, ...)) end
function ya.clamp(min, x, max) function ya.clamp(min, x, max)
@ -30,11 +29,11 @@ end
function ya.readable_size(size) function ya.readable_size(size)
local units = { "B", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q" } local units = { "B", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q" }
local i = 1 local i = 1
while size > 1024.0 and i < #units do while size > 1024 and i < #units do
size = size / 1024.0 size = size / 1024
i = i + 1 i = i + 1
end end
return string.format("%.1f%s", size, units[i]) return string.format("%.1f%s", size, units[i]):gsub("[.,]0", "", 1)
end end
function ya.readable_path(path) function ya.readable_path(path)