diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-22 02:21:12 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-22 02:23:35 +0300 |
| commit | 0148c1379b76c5c0a9d05588c07dcb06ec32f93f (patch) | |
| tree | 554766d959c738ca2aa433c3d4b4a7de25568008 /src/persist/snapshot.rs | |
| parent | a9ff4012bdca0dbdbc77bc6e53a430689fc899be (diff) | |
feat: add git worktree workspace management
refs #137
Diffstat (limited to 'src/persist/snapshot.rs')
| -rw-r--r-- | src/persist/snapshot.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/persist/snapshot.rs b/src/persist/snapshot.rs index a3811c36..79d5c406 100644 --- a/src/persist/snapshot.rs +++ b/src/persist/snapshot.rs @@ -26,6 +26,8 @@ pub struct SessionSnapshot { pub sidebar_width: Option<u16>, #[serde(default)] pub sidebar_section_split: Option<f32>, + #[serde(default)] + pub collapsed_space_keys: std::collections::HashSet<String>, } #[derive(Serialize, Deserialize)] @@ -35,6 +37,8 @@ pub struct WorkspaceSnapshot { #[serde(default)] pub custom_name: Option<String>, pub identity_cwd: PathBuf, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub worktree_space: Option<crate::workspace::WorktreeSpaceMembership>, pub tabs: Vec<TabSnapshot>, #[serde(default)] pub active_tab: usize, @@ -109,6 +113,7 @@ impl From<LegacyWorkspaceSnapshot> for WorkspaceSnapshot { id: None, custom_name: snap.custom_name, identity_cwd, + worktree_space: None, tabs: vec![tab], active_tab: 0, } @@ -131,6 +136,8 @@ struct RawSessionSnapshot { sidebar_width: Option<u16>, #[serde(default)] sidebar_section_split: Option<f32>, + #[serde(default)] + collapsed_space_keys: std::collections::HashSet<String>, } fn migrate_snapshot(raw: RawSessionSnapshot) -> Result<SessionSnapshot, String> { @@ -146,6 +153,7 @@ fn migrate_snapshot(raw: RawSessionSnapshot) -> Result<SessionSnapshot, String> agent_panel_scope: raw.agent_panel_scope, sidebar_width: raw.sidebar_width, sidebar_section_split: raw.sidebar_section_split, + collapsed_space_keys: raw.collapsed_space_keys, }) } @@ -208,6 +216,7 @@ pub fn capture( agent_panel_scope: crate::app::state::AgentPanelScope, sidebar_width: u16, sidebar_section_split: f32, + collapsed_space_keys: std::collections::HashSet<String>, ) -> SessionSnapshot { SessionSnapshot { version: SNAPSHOT_VERSION, @@ -220,6 +229,7 @@ pub fn capture( agent_panel_scope, sidebar_width: Some(sidebar_width), sidebar_section_split: Some(sidebar_section_split), + collapsed_space_keys, } } @@ -237,6 +247,7 @@ fn capture_workspace( identity_cwd: ws .resolved_identity_cwd_from(terminals, terminal_runtimes) .unwrap_or_else(|| ws.identity_cwd.clone()), + worktree_space: ws.worktree_space.clone(), tabs: ws .tabs .iter() @@ -375,6 +386,7 @@ mod tests { state.agent_panel_scope, state.sidebar_width, state.sidebar_section_split, + state.collapsed_space_keys.clone(), ) } @@ -395,6 +407,7 @@ mod tests { agent_panel_scope: AgentPanelScope::CurrentWorkspace, sidebar_width: Some(26), sidebar_section_split: Some(0.5), + collapsed_space_keys: std::collections::HashSet::new(), }; let json = serde_json::to_string(&snap).unwrap(); let restored = parse_snapshot(&json).unwrap(); @@ -451,6 +464,7 @@ mod tests { id: Some("wproj".to_string()), custom_name: Some("pi-mono".to_string()), identity_cwd: PathBuf::from("/home/can/Projects/herdr"), + worktree_space: None, tabs: vec![TabSnapshot { custom_name: Some("api".to_string()), layout: LayoutSnapshot::Split { @@ -471,6 +485,7 @@ mod tests { agent_panel_scope: AgentPanelScope::CurrentWorkspace, sidebar_width: Some(26), sidebar_section_split: Some(0.5), + collapsed_space_keys: std::collections::HashSet::new(), version: SNAPSHOT_VERSION, }; @@ -622,11 +637,32 @@ mod tests { state.sidebar_width = 31; state.sidebar_section_split = 0.4; state.agent_panel_scope = AgentPanelScope::AllWorkspaces; + state.collapsed_space_keys.insert("repo-key".into()); let snapshot = capture_from_state(&state); assert_eq!(snapshot.sidebar_width, Some(31)); assert_eq!(snapshot.sidebar_section_split, Some(0.4)); assert_eq!(snapshot.agent_panel_scope, AgentPanelScope::AllWorkspaces); + assert!(snapshot.collapsed_space_keys.contains("repo-key")); + } + + #[test] + fn capture_contract_tracks_worktree_space_membership() { + let mut state = state_with_workspaces(&["main"]); + state.workspaces[0].worktree_space = Some(crate::workspace::WorktreeSpaceMembership { + key: "repo-key".into(), + label: "herdr".into(), + repo_root: PathBuf::from("/repo/herdr"), + checkout_path: PathBuf::from("/repo/herdr/worktree-a"), + is_linked_worktree: true, + }); + + let snapshot = capture_from_state(&state); + + assert_eq!( + snapshot.workspaces[0].worktree_space, + state.workspaces[0].worktree_space + ); } #[test] @@ -776,6 +812,7 @@ mod tests { id: Some("test-ws".to_string()), custom_name: Some("fallback test".to_string()), identity_cwd: PathBuf::from("/tmp"), + worktree_space: None, tabs: vec