add placeholder button for retrieving additional context

KCaverly created

Change summary

crates/assistant/src/assistant_panel.rs | 34 ++++++++++++++++
crates/theme/src/theme.rs               |  1 
styles/src/style_tree/assistant.ts      | 56 +++++++++++++++++++++++++++
3 files changed, 91 insertions(+)

Detailed changes

crates/assistant/src/assistant_panel.rs 🔗

@@ -73,6 +73,7 @@ actions!(
         ResetKey,
         InlineAssist,
         ToggleIncludeConversation,
+        ToggleRetrieveContext,
     ]
 );
 
@@ -109,6 +110,7 @@ pub fn init(cx: &mut AppContext) {
     cx.add_action(InlineAssistant::confirm);
     cx.add_action(InlineAssistant::cancel);
     cx.add_action(InlineAssistant::toggle_include_conversation);
+    cx.add_action(InlineAssistant::toggle_retrieve_context);
     cx.add_action(InlineAssistant::move_up);
     cx.add_action(InlineAssistant::move_down);
 }
@@ -147,6 +149,7 @@ pub struct AssistantPanel {
     inline_prompt_history: VecDeque<String>,
     _watch_saved_conversations: Task<Result<()>>,
     semantic_index: Option<ModelHandle<SemanticIndex>>,
+    retrieve_context_in_next_inline_assist: bool,
 }
 
 impl AssistantPanel {
@@ -221,6 +224,7 @@ impl AssistantPanel {
                         inline_prompt_history: Default::default(),
                         _watch_saved_conversations,
                         semantic_index,
+                        retrieve_context_in_next_inline_assist: false,
                     };
 
                     let mut old_dock_position = this.position(cx);
@@ -314,6 +318,7 @@ impl AssistantPanel {
                 codegen.clone(),
                 self.workspace.clone(),
                 cx,
+                self.retrieve_context_in_next_inline_assist,
             );
             cx.focus_self();
             assistant
@@ -446,6 +451,9 @@ impl AssistantPanel {
             } => {
                 self.include_conversation_in_next_inline_assist = *include_conversation;
             }
+            InlineAssistantEvent::RetrieveContextToggled { retrieve_context } => {
+                self.retrieve_context_in_next_inline_assist = *retrieve_context
+            }
         }
     }
 
@@ -2679,6 +2687,9 @@ enum InlineAssistantEvent {
     IncludeConversationToggled {
         include_conversation: bool,
     },
+    RetrieveContextToggled {
+        retrieve_context: bool,
+    },
 }
 
 struct InlineAssistant {
@@ -2694,6 +2705,7 @@ struct InlineAssistant {
     pending_prompt: String,
     codegen: ModelHandle<Codegen>,
     _subscriptions: Vec<Subscription>,
+    retrieve_context: bool,
 }
 
 impl Entity for InlineAssistant {
@@ -2722,6 +2734,18 @@ impl View for InlineAssistant {
                             .element()
                             .aligned(),
                     )
+                    .with_child(
+                        Button::action(ToggleRetrieveContext)
+                            .with_tooltip("Retrieve Context", theme.tooltip.clone())
+                            .with_id(self.id)
+                            .with_contents(theme::components::svg::Svg::new(
+                                "icons/magnifying_glass.svg",
+                            ))
+                            .toggleable(self.retrieve_context)
+                            .with_style(theme.assistant.inline.retrieve_context.clone())
+                            .element()
+                            .aligned(),
+                    )
                     .with_children(if let Some(error) = self.codegen.read(cx).error() {
                         Some(
                             Svg::new("icons/error.svg")
@@ -2802,6 +2826,7 @@ impl InlineAssistant {
         codegen: ModelHandle<Codegen>,
         workspace: WeakViewHandle<Workspace>,
         cx: &mut ViewContext<Self>,
+        retrieve_context: bool,
     ) -> Self {
         let prompt_editor = cx.add_view(|cx| {
             let mut editor = Editor::single_line(
@@ -2832,6 +2857,7 @@ impl InlineAssistant {
             pending_prompt: String::new(),
             codegen,
             _subscriptions: subscriptions,
+            retrieve_context,
         }
     }
 
@@ -2902,6 +2928,14 @@ impl InlineAssistant {
         }
     }
 
+    fn toggle_retrieve_context(&mut self, _: &ToggleRetrieveContext, cx: &mut ViewContext<Self>) {
+        self.retrieve_context = !self.retrieve_context;
+        cx.emit(InlineAssistantEvent::RetrieveContextToggled {
+            retrieve_context: self.retrieve_context,
+        });
+        cx.notify();
+    }
+
     fn toggle_include_conversation(
         &mut self,
         _: &ToggleIncludeConversation,

crates/theme/src/theme.rs 🔗

@@ -1190,6 +1190,7 @@ pub struct InlineAssistantStyle {
     pub disabled_editor: FieldEditor,
     pub pending_edit_background: Color,
     pub include_conversation: ToggleIconButtonStyle,
+    pub retrieve_context: ToggleIconButtonStyle,
 }
 
 #[derive(Clone, Deserialize, Default, JsonSchema)]

styles/src/style_tree/assistant.ts 🔗

@@ -79,6 +79,62 @@ export default function assistant(): any {
                 },
             },
             pending_edit_background: background(theme.highest, "positive"),
+            retrieve_context: toggleable({
+                base: interactive({
+                    base: {
+                        icon_size: 12,
+                        color: foreground(theme.highest, "variant"),
+
+                        button_width: 12,
+                        background: background(theme.highest, "on"),
+                        corner_radius: 2,
+                        border: {
+                            width: 1., color: background(theme.highest, "on")
+                        },
+                        padding: {
+                            left: 4,
+                            right: 4,
+                            top: 4,
+                            bottom: 4,
+                        },
+                    },
+                    state: {
+                        hovered: {
+                            ...text(theme.highest, "mono", "variant", "hovered"),
+                            background: background(theme.highest, "on", "hovered"),
+                            border: {
+                                width: 1., color: background(theme.highest, "on", "hovered")
+                            },
+                        },
+                        clicked: {
+                            ...text(theme.highest, "mono", "variant", "pressed"),
+                            background: background(theme.highest, "on", "pressed"),
+                            border: {
+                                width: 1., color: background(theme.highest, "on", "pressed")
+                            },
+                        },
+                    },
+                }),
+                state: {
+                    active: {
+                        default: {
+                            icon_size: 12,
+                            button_width: 12,
+                            color: foreground(theme.highest, "variant"),
+                            background: background(theme.highest, "accent"),
+                            border: border(theme.highest, "accent"),
+                        },
+                        hovered: {
+                            background: background(theme.highest, "accent", "hovered"),
+                            border: border(theme.highest, "accent", "hovered"),
+                        },
+                        clicked: {
+                            background: background(theme.highest, "accent", "pressed"),
+                            border: border(theme.highest, "accent", "pressed"),
+                        },
+                    },
+                },
+            }),
             include_conversation: toggleable({
                 base: interactive({
                     base: {