diff --git a/crates/engine/src/cmd/fileio/load.rs b/crates/engine/src/cmd/fileio/load.rs index b7bb78098..1ef1b1e8c 100644 --- a/crates/engine/src/cmd/fileio/load.rs +++ b/crates/engine/src/cmd/fileio/load.rs @@ -369,6 +369,11 @@ pub fn open_bytes(s: &mut Session, name: &str, bytes: &[u8], path: Option, p: &Value) -> Result { + if let Some(path) = path.as_deref() + && let Some(index) = document_index_for_path(s, path) + { + return activate_open_document(s, index); + } let update_links = s.prefs.update_links == "automatically"; open_read(s, read_for_open(name, bytes, path, p, update_links)?) } @@ -704,3 +709,22 @@ fn same_file(a: &str, b: &str) -> bool { _ => a == b, } } + +/// The open document whose saved path is the same file as `path`, if any. +fn document_index_for_path(s: &Session, path: &str) -> Option { + s.documents().iter().position(|st| st.path.as_deref().is_some_and(|p| same_file(p, path))) +} + +/// Bring an already-open document to the front instead of reading the file again (Home › Recent). +fn activate_open_document(s: &mut Session, index: usize) -> Result { + s.set_active(index); + let st = &s.documents()[index]; + Ok(json!({ + "index": index, + "title": st.title(), + "format": st.format, + "warnings": [], + "restored": false, + "activated": true, + })) +} diff --git a/crates/engine/src/cmd/fileio/tests.rs b/crates/engine/src/cmd/fileio/tests.rs index e656965e1..dab9c929e 100644 --- a/crates/engine/src/cmd/fileio/tests.rs +++ b/crates/engine/src/cmd/fileio/tests.rs @@ -363,6 +363,25 @@ fn templates_open_untitled() { let _ = std::fs::remove_dir_all(dir); } +#[test] +fn open_same_path_activates_existing_document() { + let mut s = Session::new(); + let dir = tmp_dir("reopen"); + let path = dir.join("doc.vectorcraft").to_string_lossy().to_string(); + let mut fresh = Session::new(); + fresh.execute("file.new", &json!({"width": 100, "height": 100})).unwrap(); + std::fs::write(&path, b64(&fresh.execute("document.serialize", &json!({})).unwrap())).unwrap(); + s.execute("document.open", &json!({"path": path})).unwrap(); + assert_eq!(s.documents().len(), 1); + s.execute("shape.rectangle", &json!({"x": 1, "y": 2, "width": 10, "height": 10})).unwrap(); + let r = s.execute("document.open", &json!({"path": path})).unwrap(); + assert_eq!(r["activated"], true); + assert_eq!(s.documents().len(), 1); + assert_eq!(s.active_index(), Some(0)); + assert_eq!(s.doc().unwrap().doc.layers[0].children().unwrap().len(), 1); + let _ = std::fs::remove_dir_all(dir); +} + #[test] fn open_exts_cover_every_readable_format() { for f in FORMATS.iter().filter(|f| f.read) {