diff --git a/crates/ai/src/ai.rs b/crates/ai/src/ai.rs index 89999f26f3..fe1125bb98 100644 --- a/crates/ai/src/ai.rs +++ b/crates/ai/src/ai.rs @@ -1,9 +1,8 @@ -mod assistant; - -use gpui::{actions, AppContext}; -use serde::{Deserialize, Serialize}; +pub mod assistant; pub use assistant::AssistantPanel; +use gpui::{actions, AppContext}; +use serde::{Deserialize, Serialize}; actions!(ai, [Assist]); diff --git a/crates/ai/src/assistant.rs b/crates/ai/src/assistant.rs index 38b64587a5..6f5cbd6416 100644 --- a/crates/ai/src/assistant.rs +++ b/crates/ai/src/assistant.rs @@ -19,9 +19,18 @@ use workspace::{ pane, Pane, Workspace, }; -actions!(assistant, [NewContext, Assist, QuoteSelection]); +actions!(assistant, [NewContext, Assist, QuoteSelection, ToggleFocus]); pub fn init(cx: &mut AppContext) { + cx.add_action( + |workspace: &mut Workspace, _: &NewContext, cx: &mut ViewContext| { + if let Some(this) = workspace.panel::(cx) { + this.update(cx, |this, cx| this.add_context(cx)) + } + + workspace.focus_panel::(cx); + }, + ); cx.add_action(AssistantEditor::assist); cx.capture_action(AssistantEditor::cancel_last_assist); cx.add_action(AssistantEditor::quote_selection); @@ -49,7 +58,8 @@ impl AssistantPanel { cx.spawn(|mut cx| async move { // TODO: deserialize state. workspace.update(&mut cx, |workspace, cx| { - cx.add_view(|cx| { + cx.add_view::(|cx| { + let weak_self = cx.weak_handle(); let pane = cx.add_view(|cx| { let mut pane = Pane::new( workspace.weak_handle(), @@ -62,6 +72,7 @@ impl AssistantPanel { pane.set_can_navigate(false, cx); pane.on_can_drop(move |_, _| false); pane.set_render_tab_bar_buttons(cx, move |pane, cx| { + let weak_self = weak_self.clone(); Flex::row() .with_child(Pane::render_tab_bar_button( 0, @@ -69,7 +80,14 @@ impl AssistantPanel { false, Some(("New Context".into(), Some(Box::new(NewContext)))), cx, - move |_, _| todo!(), + move |_, cx| { + let weak_self = weak_self.clone(); + cx.window_context().defer(move |cx| { + if let Some(this) = weak_self.upgrade(cx) { + this.update(cx, |this, cx| this.add_context(cx)); + } + }) + }, None, )) .with_child(Pane::render_tab_bar_button( @@ -125,6 +143,14 @@ impl AssistantPanel { _ => {} } } + + fn add_context(&mut self, cx: &mut ViewContext) { + let focus = self.has_focus(cx); + let editor = cx.add_view(|cx| AssistantEditor::new(self.languages.clone(), cx)); + self.pane.update(cx, |pane, cx| { + pane.add_item(Box::new(editor), true, focus, None, cx) + }); + } } impl Entity for AssistantPanel { @@ -187,11 +213,7 @@ impl Panel for AssistantPanel { fn set_active(&mut self, active: bool, cx: &mut ViewContext) { if active && self.pane.read(cx).items_len() == 0 { - let focus = self.has_focus(cx); - let editor = cx.add_view(|cx| AssistantEditor::new(self.languages.clone(), cx)); - self.pane.update(cx, |pane, cx| { - pane.add_item(Box::new(editor), true, focus, None, cx) - }); + self.add_context(cx); } } @@ -200,7 +222,7 @@ impl Panel for AssistantPanel { } fn icon_tooltip(&self) -> (String, Option>) { - ("Assistant Panel".into(), None) + ("Assistant Panel".into(), Some(Box::new(ToggleFocus))) } fn should_change_position_on_event(_: &Self::Event) -> bool { @@ -231,7 +253,7 @@ struct Assistant { messages_by_id: HashMap, completion_count: usize, pending_completions: Vec, - language_registry: Arc, + languages: Arc, } impl Entity for Assistant { @@ -246,7 +268,7 @@ impl Assistant { messages_by_id: Default::default(), completion_count: Default::default(), pending_completions: Default::default(), - language_registry, + languages: language_registry, }; this.push_message(Role::User, cx); this @@ -310,7 +332,7 @@ impl Assistant { fn push_message(&mut self, role: Role, cx: &mut ModelContext) -> Message { let content = cx.add_model(|cx| { let mut buffer = Buffer::new(0, "", cx); - let markdown = self.language_registry.language_for_name("Markdown"); + let markdown = self.languages.language_for_name("Markdown"); cx.spawn_weak(|buffer, mut cx| async move { let markdown = markdown.await?; let buffer = buffer @@ -322,7 +344,7 @@ impl Assistant { anyhow::Ok(()) }) .detach_and_log_err(cx); - buffer.set_language_registry(self.language_registry.clone()); + buffer.set_language_registry(self.languages.clone()); buffer }); let excerpt_id = self.buffer.update(cx, |buffer, cx| { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 8379251485..38e7a20d31 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -235,6 +235,13 @@ pub fn init(app_state: &Arc, cx: &mut gpui::AppContext) { workspace.toggle_panel_focus::(cx); }, ); + cx.add_action( + |workspace: &mut Workspace, + _: &ai::assistant::ToggleFocus, + cx: &mut ViewContext| { + workspace.toggle_panel_focus::(cx); + }, + ); cx.add_global_action({ let app_state = Arc::downgrade(&app_state); move |_: &NewWindow, cx: &mut AppContext| {