Merge pull request #3963 from dotCooCoo/feat/inspect-file-info-title

MCP: document.inspect and document.open report the File Info title as fileInfoTitle
This commit is contained in:
BFlat
2026-10-24 17:54:46 +07:00
committed by GitHub
4 changed files with 34 additions and 2 deletions
+6 -2
View File
@@ -463,8 +463,12 @@ fn open_loaded(s: &mut Session, loaded: Loaded, links: Resolved, path: Option<St
st.converted = converted;
st.imported_from = source_path;
st.import_losses = losses;
let title = s.documents()[index].title();
Ok(super::merge(json!({ "index": index, "title": title, "format": format.id, "warnings": warnings, "restored": restored }), links.to_json()))
let opened = &s.documents()[index];
let (title, file_info_title) = (opened.title(), opened.doc.title.clone());
Ok(super::merge(
json!({ "index": index, "title": title, "fileInfoTitle": file_info_title, "format": format.id, "warnings": warnings, "restored": restored }),
links.to_json(),
))
}
/// A file named by a command's params: `{path}` (read from disk) or `{name, dataBase64}`.
+2
View File
@@ -265,6 +265,8 @@ fn document_base(s: &Session) -> Value {
json!({
"uid": st.uid,
"title": st.title(),
// The File Info title (`file.info`), where `title` comes from the file name once the document has one.
"fileInfoTitle": d.title,
"path": st.path,
"dirty": st.is_dirty(),
"revision": st.revision,
+23
View File
@@ -112,6 +112,29 @@ fn saving_to_a_file_stamps_the_modified_date() {
assert!(s.execute("file.info", &json!({})).unwrap()["modified"].is_string());
}
#[test]
fn inspect_and_open_report_the_file_info_title_beside_the_file_name() {
let dir = std::env::temp_dir().join(format!("vc-fileinfotitle-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let path = dir.join("poster.vectorcraft");
let mut s = session();
// Untitled, the two are the same.
let r = s.execute("document.inspect", &json!({"depth": 0})).unwrap();
assert_eq!((r["title"].as_str(), r["fileInfoTitle"].as_str()), (Some("Poster"), Some("Poster")));
s.execute("file.info", &json!({"title": "Poster: final"})).unwrap();
s.execute("document.save", &json!({"path": path.to_str().unwrap()})).unwrap();
let r = s.execute("document.inspect", &json!({"depth": 0})).unwrap();
assert_eq!((r["title"].as_str(), r["fileInfoTitle"].as_str()), (Some("poster.vectorcraft"), Some("Poster: final")));
// Opened from the file, in another session.
let mut s = Session::new();
let opened = s.execute("document.open", &json!({"path": path.to_str().unwrap()})).unwrap();
assert_eq!((opened["title"].as_str(), opened["fileInfoTitle"].as_str()), (Some("poster.vectorcraft"), Some("Poster: final")));
let r = s.execute("document.inspect", &json!({"depth": 0})).unwrap();
assert_eq!((r["title"].as_str(), r["fileInfoTitle"].as_str()), (Some("poster.vectorcraft"), Some("Poster: final")));
assert_eq!(r["fileInfoTitle"], s.execute("file.info", &json!({})).unwrap()["title"]);
let _ = std::fs::remove_dir_all(dir);
}
#[test]
fn pdf_info_carries_author_subject_and_keywords() {
let mut s = session();
+3
View File
@@ -3184,6 +3184,9 @@ packet (`dc:creator`, `dc:description`, `dc:subject` or `pdf:Keywords`, `xmpRigh
`Subject`, `Keywords`, `CreationDate`, `ModDate`) give, the XMP packet's value where both give one. A value that
`file.info` would refuse is left out, and the title is set as for any other open (the file name, or a new untitled
name for a template).
`document.inspect` (`inspect_document`) and the `document.open` (`open_file`) reply report the File Info title as
`fileInfoTitle`. Their `title` is the document's tab name, which comes from the file name once the document is saved
to or opened from a file (with ` [Converted]` or ` [Recovered]` where that applies).
`file.new {created}` and a save to a file (`document.save` or `file.saveAs` with
`{path, modified}`) use the given date (Unix seconds, or `null` for none) instead of now. Their journal entries always
record the date they used, so replaying the journal makes the same document whenever it runs (an action recorded in