aboutsummaryrefslogtreecommitdiff
path: root/src/app/input/navigate.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-18 01:55:46 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-18 01:55:46 +0300
commite298e4589050349630d0faaec00ef11555b83ae1 (patch)
treef9487e37bb641cb99e5bb053d7ad8106db13b047 /src/app/input/navigate.rs
parent13ce20c4f536892c5b939bd62e5286fac9c2eaee (diff)
feat: add optional workspace name prompt
Diffstat (limited to 'src/app/input/navigate.rs')
-rw-r--r--src/app/input/navigate.rs79
1 files changed, 69 insertions, 10 deletions
diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs
index 33177624..e1ffeb5d 100644
--- a/src/app/input/navigate.rs
+++ b/src/app/input/navigate.rs
@@ -184,16 +184,7 @@ impl App {
let previous_mode = self.state.mode;
match action {
NavigateAction::NewWorkspace => {
- self.runtime_workspace_create(
- "tui.key.workspace.create",
- crate::api::schema::WorkspaceCreateParams {
- cwd: None,
- focus: true,
- label: None,
- env: Default::default(),
- },
- );
- leave_navigate_mode(&mut self.state);
+ self.begin_tui_workspace_create("tui.key.workspace.create");
}
NavigateAction::NewWorktree => {
if let Some(ws_idx) = workspace_action_target(&self.state, context).filter(|idx| {
@@ -1999,6 +1990,74 @@ mod tests {
assert_eq!(state.mode, Mode::Terminal);
}
+ #[tokio::test]
+ async fn new_workspace_key_opens_prefilled_prompt_and_preserves_captured_cwd() {
+ let cwd = unique_temp_path("workspace-name-suggestion");
+ std::fs::create_dir_all(&cwd).unwrap();
+ let suggested_name = crate::workspace::derive_label_from_cwd(&cwd);
+ let mut app = app_with_test_workspaces(&["test"]);
+ app.state.new_terminal_cwd =
+ crate::config::NewTerminalCwdConfig::Path(cwd.display().to_string());
+ app.state.prompt_new_workspace_name = true;
+ app.state.mode = Mode::Navigate;
+ app.state.keybinds.new_workspace = crate::config::ActionKeybinds::prefix("g");
+
+ app.handle_navigate_key(TerminalKey::new(KeyCode::Char('g'), KeyModifiers::empty()));
+
+ assert_eq!(app.state.mode, Mode::RenameWorkspace);
+ assert_eq!(app.state.name_input, suggested_name);
+ assert!(app.state.name_input_replace_on_type);
+ assert_eq!(app.state.pending_workspace_create_cwd.as_ref(), Some(&cwd));
+ assert_eq!(app.state.workspaces.len(), 1);
+
+ app.state.new_terminal_cwd =
+ crate::config::NewTerminalCwdConfig::Path("/tmp/changed-after-prompt".into());
+ app.handle_rename_key_via_api(KeyEvent::new(KeyCode::Enter, KeyModifiers::empty()));
+
+ assert_eq!(app.state.workspaces.len(), 2);
+ assert_eq!(app.state.workspaces[1].identity_cwd, cwd);
+ assert!(app.state.workspaces[1].custom_name.is_none());
+ assert!(app.state.pending_workspace_create_cwd.is_none());
+ assert_eq!(app.state.mode, Mode::Terminal);
+ crate::app::api::test_support::shutdown_test_runtimes(&mut app);
+ let _ = std::fs::remove_dir_all(&cwd);
+ }
+
+ #[tokio::test]
+ async fn new_workspace_prompt_saves_custom_name_atomically() {
+ let cwd = unique_temp_path("workspace-custom-name");
+ std::fs::create_dir_all(&cwd).unwrap();
+ let mut app = app_with_test_workspaces(&["test"]);
+ app.state.new_terminal_cwd =
+ crate::config::NewTerminalCwdConfig::Path(cwd.display().to_string());
+ app.state.prompt_new_workspace_name = true;
+ app.state.mode = Mode::Navigate;
+
+ app.execute_tui_navigate_action(NavigateAction::NewWorkspace, ActionContext::Navigate);
+ app.state.name_input = " logs ".into();
+ app.handle_rename_key_via_api(KeyEvent::new(KeyCode::Enter, KeyModifiers::empty()));
+
+ assert_eq!(app.state.workspaces.len(), 2);
+ assert_eq!(app.state.workspaces[1].custom_name.as_deref(), Some("logs"));
+ assert_eq!(app.state.workspaces[1].identity_cwd, cwd);
+ crate::app::api::test_support::shutdown_test_runtimes(&mut app);
+ let _ = std::fs::remove_dir_all(&cwd);
+ }
+
+ #[test]
+ fn cancelling_new_workspace_prompt_creates_nothing() {
+ let mut app = app_with_test_workspaces(&["test"]);
+ app.state.prompt_new_workspace_name = true;
+ app.state.mode = Mode::Navigate;
+
+ app.execute_tui_navigate_action(NavigateAction::NewWorkspace, ActionContext::Navigate);
+ app.handle_rename_key_via_api(KeyEvent::new(KeyCode::Esc, KeyModifiers::empty()));
+
+ assert_eq!(app.state.workspaces.len(), 1);
+ assert!(app.state.pending_workspace_create_cwd.is_none());
+ assert_eq!(app.state.mode, Mode::Terminal);
+ }
+
#[test]
fn custom_new_worktree_key_requests_selected_workspace() {
let mut state = state_with_workspaces(&["main", "scratch"]);