diff options
Diffstat (limited to 'src/app/input/modal.rs')
| -rw-r--r-- | src/app/input/modal.rs | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/src/app/input/modal.rs b/src/app/input/modal.rs index 84aed8da..23134ddc 100644 --- a/src/app/input/modal.rs +++ b/src/app/input/modal.rs @@ -302,6 +302,7 @@ pub(super) fn open_rename_workspace( terminal_runtimes: &crate::terminal::TerminalRuntimeRegistry, ws_idx: usize, ) { + state.pending_workspace_create_cwd = None; state.selected = ws_idx; state.rename_pane_target = None; state.name_input = @@ -310,9 +311,21 @@ pub(super) fn open_rename_workspace( state.mode = Mode::RenameWorkspace; } +pub(crate) fn open_new_workspace_dialog(state: &mut AppState, cwd: std::path::PathBuf) { + let suggested_name = crate::workspace::derive_label_from_cwd(&cwd); + state.creating_new_tab = false; + state.requested_new_tab_name = None; + state.pending_workspace_create_cwd = Some(cwd); + state.rename_pane_target = None; + state.name_input = suggested_name; + state.name_input_replace_on_type = true; + state.mode = Mode::RenameWorkspace; +} + pub(super) fn open_rename_active_tab(state: &mut AppState, replace_on_type: bool) { state.creating_new_tab = false; state.requested_new_tab_name = None; + state.pending_workspace_create_cwd = None; state.rename_pane_target = None; if let Some(ws) = state.active.and_then(|i| state.workspaces.get(i)) { if let Some(name) = ws.active_tab_display_name() { @@ -333,6 +346,7 @@ pub(super) fn open_rename_pane(state: &mut AppState, pane_id: crate::layout::Pan let terminal = state.terminals.get(&pane.attached_terminal_id); state.creating_new_tab = false; state.requested_new_tab_name = None; + state.pending_workspace_create_cwd = None; state.rename_pane_target = Some(pane_id); state.name_input = terminal .and_then(|t| t.manual_label.clone()) @@ -341,6 +355,11 @@ pub(super) fn open_rename_pane(state: &mut AppState, pane_id: crate::layout::Pan state.mode = Mode::RenamePane; } +fn workspace_create_label(input: &str, suggested_name: &str) -> Option<String> { + let name = input.trim(); + (!name.is_empty() && name != suggested_name).then(|| name.to_string()) +} + fn next_new_tab_default_name(state: &AppState) -> String { state .active @@ -352,6 +371,7 @@ fn next_new_tab_default_name(state: &AppState) -> String { pub(super) fn open_new_tab_dialog(state: &mut AppState) { state.creating_new_tab = true; state.requested_new_tab_name = None; + state.pending_workspace_create_cwd = None; state.rename_pane_target = None; state.name_input = next_new_tab_default_name(state); state.name_input_replace_on_type = true; @@ -423,7 +443,11 @@ pub(super) fn apply_rename_action(state: &mut AppState, action: ModalAction) { state.name_input.trim().to_string() }; match state.mode { - Mode::RenameWorkspace if !state.workspaces.is_empty() && !new_name.is_empty() => { + Mode::RenameWorkspace + if state.pending_workspace_create_cwd.is_none() + && !state.workspaces.is_empty() + && !new_name.is_empty() => + { let workspace_id = state.workspaces[state.selected].id.clone(); state.workspaces[state.selected].set_custom_name(new_name); crate::logging::workspace_renamed(&workspace_id); @@ -487,6 +511,7 @@ pub(super) fn apply_rename_action(state: &mut AppState, action: ModalAction) { _ => {} } state.creating_new_tab = false; + state.pending_workspace_create_cwd = None; state.rename_pane_target = None; state.name_input.clear(); state.name_input_replace_on_type = false; @@ -499,6 +524,7 @@ pub(super) fn apply_rename_action(state: &mut AppState, action: ModalAction) { ModalAction::Cancel => { state.creating_new_tab = false; state.requested_new_tab_name = None; + state.pending_workspace_create_cwd = None; state.rename_pane_target = None; state.name_input.clear(); state.name_input_replace_on_type = false; @@ -916,15 +942,29 @@ impl App { }; match self.state.mode { - Mode::RenameWorkspace if !self.state.workspaces.is_empty() && !new_name.is_empty() => { - let workspace_id = self.public_workspace_id(self.state.selected); - self.runtime_workspace_rename( - "tui.workspace.rename", - crate::api::schema::WorkspaceRenameParams { - workspace_id, - label: new_name, - }, - ); + Mode::RenameWorkspace => { + if let Some(cwd) = self.state.pending_workspace_create_cwd.take() { + let suggested_name = crate::workspace::derive_label_from_cwd(&cwd); + let label = workspace_create_label(&new_name, &suggested_name); + self.runtime_workspace_create( + "tui.workspace.create_named", + crate::api::schema::WorkspaceCreateParams { + cwd: Some(cwd.display().to_string()), + focus: true, + label, + env: Default::default(), + }, + ); + } else if !self.state.workspaces.is_empty() && !new_name.is_empty() { + let workspace_id = self.public_workspace_id(self.state.selected); + self.runtime_workspace_rename( + "tui.workspace.rename", + crate::api::schema::WorkspaceRenameParams { + workspace_id, + label: new_name, + }, + ); + } } Mode::RenameTab if self.state.creating_new_tab => { let default_name = next_new_tab_default_name(&self.state); @@ -1256,6 +1296,7 @@ impl App { fn cancel_rename_modal(state: &mut AppState) { state.creating_new_tab = false; state.requested_new_tab_name = None; + state.pending_workspace_create_cwd = None; state.rename_pane_target = None; state.name_input.clear(); state.name_input_replace_on_type = false; @@ -1318,6 +1359,17 @@ mod tests { app } + #[test] + fn workspace_create_label_preserves_auto_name_for_suggestion_or_blank() { + assert_eq!(workspace_create_label("project", "project"), None); + assert_eq!(workspace_create_label("", "project"), None); + assert_eq!(workspace_create_label(" ", "project"), None); + assert_eq!( + workspace_create_label(" logs ", "project").as_deref(), + Some("logs") + ); + } + fn mark_worktree_space_member(state: &mut AppState, ws_idx: usize, key: &str) { state.workspaces[ws_idx].worktree_space = Some(crate::workspace::WorktreeSpaceMembership { key: key.into(), |
