diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index c4e4041f718abff536102d302d1e2ee271a263fb..b93e14e5d2137815b6b1895a4dc99973b817ec1a 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -58,6 +58,14 @@ gpui::actions!( RemoveSelectedWorkspace, /// Removes the selected entry: archives a thread or closes a workspace. RemoveSelected, + /// Stops the currently selected running thread. + StopSelectedThread, + /// Activates the workspace that owns the currently selected entry. + ActivateSelectedWorkspace, + /// Expands the selected group to show more threads. + ShowMoreThreads, + /// Collapses expanded threads in the selected group back to the default count. + ShowFewerThreads, ] ); @@ -2494,6 +2502,124 @@ impl Sidebar { } } + fn stop_selected_thread( + &mut self, + _: &StopSelectedThread, + _window: &mut Window, + cx: &mut Context, + ) { + let Some(ix) = self.selection else { + return; + }; + let Some(ListEntry::Thread(thread)) = self.contents.entries.get(ix) else { + return; + }; + let session_id = thread.session_info.session_id.clone(); + self.stop_thread(&session_id, cx); + } + + fn activate_selected_workspace( + &mut self, + _: &ActivateSelectedWorkspace, + window: &mut Window, + cx: &mut Context, + ) { + let Some(ix) = self.selection else { + return; + }; + + let workspace = match self.contents.entries.get(ix) { + Some(ListEntry::ProjectHeader { workspace, .. }) => Some(workspace.clone()), + Some(ListEntry::Thread(_) | ListEntry::ViewMore { .. } | ListEntry::NewThread { .. }) => { + self.contents.entries[..ix] + .iter() + .rev() + .find_map(|entry| match entry { + ListEntry::ProjectHeader { workspace, .. } => Some(workspace.clone()), + _ => None, + }) + } + _ => None, + }; + + let Some(workspace) = workspace else { + return; + }; + + self.focused_thread = None; + if let Some(multi_workspace) = self.multi_workspace.upgrade() { + multi_workspace.update(cx, |multi_workspace, cx| { + multi_workspace.activate(workspace.clone(), cx); + }); + } + if AgentPanel::is_visible(&workspace, cx) { + workspace.update(cx, |workspace, cx| { + workspace.focus_panel::(window, cx); + }); + } + } + + fn show_more_threads( + &mut self, + _: &ShowMoreThreads, + _window: &mut Window, + cx: &mut Context, + ) { + let Some(ix) = self.selection else { + return; + }; + + let path_list = match self.contents.entries.get(ix) { + Some(ListEntry::ProjectHeader { path_list, .. }) => Some(path_list.clone()), + Some(ListEntry::Thread(_) | ListEntry::ViewMore { .. } | ListEntry::NewThread { .. }) => { + self.contents.entries[..ix] + .iter() + .rev() + .find_map(|entry| match entry { + ListEntry::ProjectHeader { path_list, .. } => Some(path_list.clone()), + _ => None, + }) + } + _ => None, + }; + + if let Some(path_list) = path_list { + let current = self.expanded_groups.get(&path_list).copied().unwrap_or(0); + self.expanded_groups.insert(path_list, current + 1); + self.update_entries(cx); + } + } + + fn show_fewer_threads( + &mut self, + _: &ShowFewerThreads, + _window: &mut Window, + cx: &mut Context, + ) { + let Some(ix) = self.selection else { + return; + }; + + let path_list = match self.contents.entries.get(ix) { + Some(ListEntry::ProjectHeader { path_list, .. }) => Some(path_list.clone()), + Some(ListEntry::Thread(_) | ListEntry::ViewMore { .. } | ListEntry::NewThread { .. }) => { + self.contents.entries[..ix] + .iter() + .rev() + .find_map(|entry| match entry { + ListEntry::ProjectHeader { path_list, .. } => Some(path_list.clone()), + _ => None, + }) + } + _ => None, + }; + + if let Some(path_list) = path_list { + self.expanded_groups.remove(&path_list); + self.update_entries(cx); + } + } + fn render_thread( &self, ix: usize, @@ -3203,6 +3329,10 @@ impl Render for Sidebar { .on_action(cx.listener(Self::remove_selected_thread)) .on_action(cx.listener(Self::remove_selected_workspace)) .on_action(cx.listener(Self::remove_selected)) + .on_action(cx.listener(Self::stop_selected_thread)) + .on_action(cx.listener(Self::activate_selected_workspace)) + .on_action(cx.listener(Self::show_more_threads)) + .on_action(cx.listener(Self::show_fewer_threads)) .on_action(cx.listener(Self::new_thread_in_group)) .on_action(cx.listener(Self::toggle_archive)) .on_action(cx.listener(Self::focus_sidebar_filter))