Merge pull request #2601 from pravdomil/claude/ecproj-compact-opt-in

Project files: opt-in compact .ecproj JSON (Save Compact Project Files)
This commit is contained in:
BFlat
2026-10-30 04:10:07 +07:00
committed by GitHub
8 changed files with 37 additions and 8 deletions
+1 -1
View File
@@ -152,7 +152,7 @@ fn clear_recent_presets(s: &mut Session, _: &Value) -> Result<Value> {
fn save_copy_xml(s: &mut Session, p: &Value) -> Result<Value> {
let path = str_p(p, "path").ok_or_else(|| bad("file.saveCopyAsXml", "missing `path` (.ecprojx)"))?;
let xml = crate::xml_project::to_xml(&s.project.to_file_json_with_view(&s.saved_view())?).map_err(EngineError::Other)?;
let xml = crate::xml_project::to_xml(&s.project.to_file_json_with_view(&s.saved_view(), false)?).map_err(EngineError::Other)?;
s.services.write_file(path, xml.as_bytes()).map_err(|e| EngineError::Other(format!("cannot write {path}: {e}")))?;
s.toast(format!("Saved an XML copy to {path}"));
Ok(json!({"path": path, "bytes": xml.len()}))
+2 -1
View File
@@ -87,7 +87,8 @@ pub(crate) fn open(s: &mut Session, p: &Value) -> Result<Value> {
/// project opened from an XML copy saves as XML again). Fails, writing nothing, when the project
/// wouldn't read back.
pub(crate) fn file_text(s: &Session, path: &str) -> Result<String> {
let json = s.project.to_file_json_with_view(&s.saved_view())?;
let compact = s.prefs.project.compact_project_files && !crate::xml_project::is_xml_path(path);
let json = s.project.to_file_json_with_view(&s.saved_view(), compact)?;
if crate::xml_project::is_xml_path(path) { crate::xml_project::to_xml(&json).map_err(EngineError::Other) } else { Ok(json) }
}
@@ -122,6 +122,11 @@ pub fn pages() -> Vec<Page> {
Section("New Project"),
s("project.useTemplate", "New Project Loads Template", B, true),
s("project.templatePath", "Template Project", Kind::Path, true),
Section("Project Files"),
s("project.compactProjectFiles", "Save Compact Project Files", B, true),
Note(
"Saves .ecproj files as compact JSON on one line: smaller and faster to save and open, but hard to read or diff in version control. Off, they are indented, one value per line.",
),
Section("Auto-Save"),
s("autoSave.enabled", "Automatically Save Projects", B, true),
s("autoSave.intervalMinutes", "Save Every", Kind::Int(1, 240, "Minutes"), true),
@@ -62,6 +62,9 @@ page!(ProjectPrefs {
/// Open a template project for File ▸ New ▸ New Project.
use_template: bool = false,
template_path: String = String::new(),
/// Write `.ecproj` files as compact JSON on one line (smaller, faster to save and open). Off:
/// indented, one value per line, so they read and diff cleanly in version control.
compact_project_files: bool = false,
});
page!(AutoSave {
+17
View File
@@ -389,6 +389,23 @@ fn new_project_template_and_default_renderer() {
let _ = std::fs::remove_dir_all(d);
}
#[test]
fn project_files_are_indented_unless_compact_is_on() {
let d = tmp("compact-project-files");
let path = d.join("p.ecproj");
let mut s = session_with_comp();
s.execute("file.saveAs", json!({"path": path.to_string_lossy()})).unwrap();
let pretty = std::fs::read_to_string(&path).unwrap();
assert!(pretty.starts_with("{\n \"savedBy\""), "indented by default");
s.execute("prefs.set", json!({"key": "project.compactProjectFiles", "value": true})).unwrap();
s.execute("file.saveAs", json!({"path": path.to_string_lossy()})).unwrap();
let compact = std::fs::read_to_string(&path).unwrap();
assert!(!compact.contains('\n'), "one line when Save Compact Project Files is on");
let open = |text: &str| effectcraft_project::Project::from_json(text).unwrap();
assert_eq!(open(&compact), open(&pretty), "both read back as the same project");
let _ = std::fs::remove_dir_all(d);
}
// ---------------------------------------------------------------- shortcuts
#[test]