@@ -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,