mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 20:01:37 +00:00
Links: Find Linked Files resolves parent folders in a saved path
A saved link path such as `Disk:Projects:Art::photo.png` (classic Mac OS) or `/old/Projects/Art/../photo.png` names a file in `Projects`. Ranking the files found compared `Art` first, so a file under a folder named `Art` came before one under `Projects`. The `::` runs and `..` components are now resolved before the folder names are compared.
This commit is contained in:
@@ -177,9 +177,28 @@ fn find(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
/// How many folder names the file at `found` has in common with the saved path `saved` (whichever
|
||||
/// system's separators it uses, [`vectorcraft_doc::links::path_separators`]), counted from the
|
||||
/// innermost out up to the first that differs, compared in lowercase.
|
||||
/// innermost out up to the first that differs, compared in lowercase. The saved path's parent
|
||||
/// components are resolved first: `..` in a `/` or `\` path, and each colon after the first in a
|
||||
/// run of colons in a classic Mac OS path (`Disk:Projects:Art::photo.png` is in `Projects`).
|
||||
fn shared_folders(saved: &str, found: &Path) -> usize {
|
||||
let saved = saved.rsplit(vectorcraft_doc::links::path_separators(saved)).skip(1).filter(|c| !c.is_empty());
|
||||
let separators = vectorcraft_doc::links::path_separators(saved);
|
||||
let classic = separators == [':'];
|
||||
let mut up = 0usize;
|
||||
let saved = saved.rsplit(separators).skip(1).filter(move |c| {
|
||||
let parent = if classic { c.is_empty() } else { *c == ".." };
|
||||
if parent {
|
||||
up += 1;
|
||||
return false;
|
||||
}
|
||||
if c.is_empty() || *c == "." && !classic {
|
||||
return false;
|
||||
}
|
||||
if up > 0 {
|
||||
up -= 1;
|
||||
return false;
|
||||
}
|
||||
true
|
||||
});
|
||||
let found = found.parent().into_iter().flat_map(|p| p.components().rev()).map_while(|c| match c {
|
||||
Component::Normal(n) => n.to_str(),
|
||||
_ => None,
|
||||
|
||||
@@ -153,6 +153,37 @@ fn a_classic_mac_path_is_found_by_its_name_and_folders() {
|
||||
assert_eq!(found(&r, "photo.png", &root), files.map(|(p, k, c)| (p.to_string(), k.to_string(), c)));
|
||||
}
|
||||
|
||||
/// The folders a saved path shares with a file found are counted after its parent components are
|
||||
/// resolved: `Art::` in a classic Mac OS path and `Art/..` in any other path go back to `Projects`.
|
||||
#[test]
|
||||
fn parent_components_in_a_saved_path_are_resolved_before_ranking() {
|
||||
for (tag, saved) in [("classic-up", "Old Disk:Projects:Art::photo.png"), ("slash-up", "/old/Projects/Art/../photo.png")] {
|
||||
let root = folder(tag);
|
||||
let mut s = session_for(&root);
|
||||
let photo = png(50, 30, BLUE);
|
||||
write(&root.join("orig/photo.png"), &photo);
|
||||
let id = placed(&mut s, &root.join("orig/photo.png"));
|
||||
s.edit("saved path", |d, _| {
|
||||
if let NodeKind::Image(im) = &mut d.node_mut(NodeId(id)).unwrap().kind {
|
||||
im.link.as_mut().unwrap().path = saved.into();
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
std::fs::remove_dir_all(root.join("orig")).unwrap();
|
||||
let search = root.join("search");
|
||||
let mut changed = photo.clone();
|
||||
*changed.last_mut().unwrap() ^= 1;
|
||||
write(&search.join("Art/photo.png"), &changed);
|
||||
write(&search.join("Projects/photo.png"), &changed);
|
||||
s.execute("links.findFiles", &json!({"folder": search})).unwrap();
|
||||
let r = finished(&mut s);
|
||||
assert_eq!(r["state"].as_str(), Some("done"), "{saved}: {r}");
|
||||
let files = [("search/Projects/photo.png", "name", false), ("search/Art/photo.png", "name", false)];
|
||||
assert_eq!(found(&r, "photo.png", &root), files.map(|(p, k, c)| (p.to_string(), k.to_string(), c)), "{saved}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Without `ids`, a search looks for the files that can't be found; with them, for those objects'
|
||||
/// files, whatever their status.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user