Allow using the inline assistant within the assistant panel (#11754)

Release Notes:

- Added the ability to use the inline assistant within the assistant
panel.
This commit is contained in:
Antonio Scandurra 2024-05-14 13:42:32 +02:00 committed by GitHub
parent 4766b41e96
commit e4c95b25bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -31,7 +31,7 @@ use gpui::{
StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle,
View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext,
};
use language::{language_settings::SoftWrap, Buffer, LanguageRegistry, ToOffset as _};
use language::{language_settings::SoftWrap, Buffer, LanguageRegistry, Point, ToOffset as _};
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use project::Project;
@ -251,11 +251,31 @@ impl AssistantPanel {
let Some(assistant) = workspace.panel::<AssistantPanel>(cx) else {
return;
};
let active_editor = if let Some(active_editor) = workspace
let conversation_editor =
assistant
.read(cx)
.active_conversation_editor()
.and_then(|editor| {
let editor = &editor.read(cx).editor;
if editor.read(cx).is_focused(cx) {
Some(editor.clone())
} else {
None
}
});
let show_include_conversation;
let active_editor;
if let Some(conversation_editor) = conversation_editor {
active_editor = conversation_editor;
show_include_conversation = false;
} else if let Some(workspace_editor) = workspace
.active_item(cx)
.and_then(|item| item.act_as::<Editor>(cx))
{
active_editor
active_editor = workspace_editor;
show_include_conversation = true;
} else {
return;
};
@ -263,7 +283,7 @@ impl AssistantPanel {
if assistant.update(cx, |assistant, cx| assistant.is_authenticated(cx)) {
assistant.update(cx, |assistant, cx| {
assistant.new_inline_assist(&active_editor, cx, &project)
assistant.new_inline_assist(&active_editor, &project, show_include_conversation, cx)
});
} else {
let assistant = assistant.downgrade();
@ -273,7 +293,12 @@ impl AssistantPanel {
.await?;
if assistant.update(&mut cx, |assistant, cx| assistant.is_authenticated(cx))? {
assistant.update(&mut cx, |assistant, cx| {
assistant.new_inline_assist(&active_editor, cx, &project)
assistant.new_inline_assist(
&active_editor,
&project,
show_include_conversation,
cx,
)
})?;
} else {
workspace.update(&mut cx, |workspace, cx| {
@ -290,8 +315,9 @@ impl AssistantPanel {
fn new_inline_assist(
&mut self,
editor: &View<Editor>,
cx: &mut ViewContext<Self>,
project: &Model<Project>,
show_include_conversation: bool,
cx: &mut ViewContext<Self>,
) {
let selection = editor.read(cx).selections.newest_anchor().clone();
if selection.start.excerpt_id != selection.end.excerpt_id {
@ -331,7 +357,8 @@ impl AssistantPanel {
InlineAssistant::new(
inline_assist_id,
measurements.clone(),
self.include_conversation_in_next_inline_assist,
show_include_conversation,
show_include_conversation && self.include_conversation_in_next_inline_assist,
self.inline_prompt_history.clone(),
codegen.clone(),
self.workspace.clone(),
@ -345,7 +372,7 @@ impl AssistantPanel {
editor.insert_blocks(
[BlockProperties {
style: BlockStyle::Flex,
position: snapshot.anchor_before(point_selection.head()),
position: snapshot.anchor_before(Point::new(point_selection.head().row, 0)),
height: 2,
render: Box::new({
let inline_assistant = inline_assistant.clone();
@ -2577,16 +2604,6 @@ impl EventEmitter<ConversationEditorEvent> for ConversationEditor {}
impl Render for ConversationEditor {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
//
// The ConversationEditor has two main segments
//
// 1. Messages Editor
// 2. Context
// - File Context (currently only the active file)
// - Project Diagnostics (Planned)
// - Deep Code Context (Planned, for query and other tools for the model)
//
div()
.key_context("ConversationEditor")
.capture_action(cx.listener(ConversationEditor::cancel_last_assist))
@ -2660,6 +2677,7 @@ struct InlineAssistant {
prompt_editor: View<Editor>,
workspace: WeakView<Workspace>,
confirmed: bool,
show_include_conversation: bool,
include_conversation: bool,
measurements: Arc<Mutex<BlockMeasurements>>,
prompt_history: VecDeque<String>,
@ -2688,7 +2706,7 @@ impl Render for InlineAssistant {
h_flex()
.justify_center()
.w(measurements.gutter_width)
.child(
.children(self.show_include_conversation.then(|| {
IconButton::new("include_conversation", IconName::Ai)
.on_click(cx.listener(|this, _, cx| {
this.toggle_include_conversation(&ToggleIncludeConversation, cx)
@ -2700,8 +2718,8 @@ impl Render for InlineAssistant {
&ToggleIncludeConversation,
cx,
)
}),
)
})
}))
.children(if let Some(error) = self.codegen.read(cx).error() {
let error_message = SharedString::from(error.to_string());
Some(
@ -2730,9 +2748,11 @@ impl FocusableView for InlineAssistant {
}
impl InlineAssistant {
#[allow(clippy::too_many_arguments)]
fn new(
id: usize,
measurements: Arc<Mutex<BlockMeasurements>>,
show_include_conversation: bool,
include_conversation: bool,
prompt_history: VecDeque<String>,
codegen: Model<Codegen>,
@ -2760,6 +2780,7 @@ impl InlineAssistant {
prompt_editor,
workspace,
confirmed: false,
show_include_conversation,
include_conversation,
measurements,
prompt_history,