@@ -1,5 +1,5 @@
use crate::acp::completion_provider::ContextPickerCompletionProvider;
-use crate::acp::{MessageHistory, completion_provider::MentionSet};
+use crate::acp::completion_provider::MentionSet;
use acp_thread::MentionUri;
use agent_client_protocol as acp;
use anyhow::Result;
@@ -10,8 +10,7 @@ use editor::{
};
use file_icons::FileIcons;
use gpui::{
- AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, Subscription, Task,
- TextStyle, WeakEntity,
+ AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, Task, TextStyle, WeakEntity,
};
use language::Language;
use language::{Buffer, BufferSnapshot};
@@ -20,7 +19,7 @@ use project::{CompletionIntent, Project};
use settings::Settings;
use std::path::Path;
use std::rc::Rc;
-use std::{cell::RefCell, sync::Arc};
+use std::sync::Arc;
use theme::ThemeSettings;
use ui::{
ActiveTheme, App, IconName, InteractiveElement, IntoElement, ParentElement, Render,
@@ -28,7 +27,7 @@ use ui::{
};
use util::ResultExt;
use workspace::Workspace;
-use zed_actions::agent::{Chat, NextHistoryMessage, PreviousHistoryMessage};
+use zed_actions::agent::Chat;
pub const MIN_EDITOR_LINES: usize = 4;
pub const MAX_EDITOR_LINES: usize = 8;
@@ -37,9 +36,6 @@ pub struct MessageEditor {
editor: Entity<Editor>,
project: Entity<Project>,
mention_set: Arc<Mutex<MentionSet>>,
- history: Rc<RefCell<MessageHistory<Vec<acp::ContentBlock>>>>,
- message_set_from_history: Option<BufferSnapshot>,
- _subscription: Subscription,
}
pub enum MessageEditorEvent {
@@ -52,7 +48,6 @@ impl MessageEditor {
pub fn new(
workspace: WeakEntity<Workspace>,
project: Entity<Project>,
- history: Rc<RefCell<MessageHistory<Vec<acp::ContentBlock>>>>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
@@ -95,35 +90,11 @@ impl MessageEditor {
});
editor
});
- let message_editor_subscription = cx.subscribe(&editor, |this, editor, event, cx| {
- if let editor::EditorEvent::BufferEdited = &event {
- let buffer = editor
- .read(cx)
- .buffer()
- .read(cx)
- .as_singleton()
- .unwrap()
- .read(cx)
- .snapshot();
- if let Some(message) = this.message_set_from_history.clone()
- && message.version() != buffer.version()
- {
- this.message_set_from_history = None;
- }
-
- if this.message_set_from_history.is_none() {
- this.history.borrow_mut().reset_position();
- }
- }
- });
Self {
editor,
project,
mention_set,
- history,
- message_set_from_history: None,
- _subscription: message_editor_subscription,
}
}
@@ -266,69 +237,7 @@ impl MessageEditor {
});
}
- fn previous_history_message(
- &mut self,
- _: &PreviousHistoryMessage,
- window: &mut Window,
- cx: &mut Context<Self>,
- ) {
- if self.message_set_from_history.is_none() && !self.editor.read(cx).is_empty(cx) {
- self.editor.update(cx, |editor, cx| {
- editor.move_up(&Default::default(), window, cx);
- });
- return;
- }
-
- self.message_set_from_history = Self::set_draft_message(
- self.editor.clone(),
- self.mention_set.clone(),
- self.project.clone(),
- self.history
- .borrow_mut()
- .prev()
- .map(|blocks| blocks.as_slice()),
- window,
- cx,
- );
- }
-
- fn next_history_message(
- &mut self,
- _: &NextHistoryMessage,
- window: &mut Window,
- cx: &mut Context<Self>,
- ) {
- if self.message_set_from_history.is_none() {
- self.editor.update(cx, |editor, cx| {
- editor.move_down(&Default::default(), window, cx);
- });
- return;
- }
-
- let mut history = self.history.borrow_mut();
- let next_history = history.next();
-
- let set_draft_message = Self::set_draft_message(
- self.editor.clone(),
- self.mention_set.clone(),
- self.project.clone(),
- Some(
- next_history
- .map(|blocks| blocks.as_slice())
- .unwrap_or_else(|| &[]),
- ),
- window,
- cx,
- );
- // If we reset the text to an empty string because we ran out of history,
- // we don't want to mark it as coming from the history
- self.message_set_from_history = if next_history.is_some() {
- set_draft_message
- } else {
- None
- };
- }
-
+ #[allow(unused)]
fn set_draft_message(
message_editor: Entity<Editor>,
mention_set: Arc<Mutex<MentionSet>>,
@@ -437,8 +346,6 @@ impl Render for MessageEditor {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
div()
.key_context("MessageEditor")
- .on_action(cx.listener(Self::previous_history_message))
- .on_action(cx.listener(Self::next_history_message))
.on_action(cx.listener(Self::chat))
.flex_1()
.child({
@@ -474,125 +381,23 @@ impl Render for MessageEditor {
#[cfg(test)]
mod tests {
- use std::{cell::RefCell, path::Path, rc::Rc};
+ use std::path::Path;
use agent_client_protocol as acp;
use fs::FakeFs;
use gpui::{AppContext, TestAppContext};
use lsp::{CompletionContext, CompletionTriggerKind};
- use pretty_assertions::assert_matches;
use project::{CompletionIntent, Project};
use serde_json::json;
use util::path;
use workspace::Workspace;
- use crate::acp::{
- MessageHistory, message_editor::MessageEditor, thread_view::tests::init_test,
- };
-
- #[gpui::test]
- async fn test_at_mention_history(cx: &mut TestAppContext) {
- init_test(cx);
-
- let history = Rc::new(RefCell::new(MessageHistory::default()));
- let fs = FakeFs::new(cx.executor());
- fs.insert_tree("/project", json!({"file": ""})).await;
- let project = Project::test(fs, [Path::new(path!("/project"))], cx).await;
-
- let (workspace, cx) =
- cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
-
- let message_editor = cx.update(|window, cx| {
- cx.new(|cx| {
- MessageEditor::new(
- workspace.downgrade(),
- project.clone(),
- history.clone(),
- window,
- cx,
- )
- })
- });
- let editor = message_editor.update(cx, |message_editor, _| message_editor.editor.clone());
-
- cx.run_until_parked();
-
- let excerpt_id = editor.update(cx, |editor, cx| {
- editor
- .buffer()
- .read(cx)
- .excerpt_ids()
- .into_iter()
- .next()
- .unwrap()
- });
- let completions = editor.update_in(cx, |editor, window, cx| {
- editor.set_text("Hello @", window, cx);
- let buffer = editor.buffer().read(cx).as_singleton().unwrap();
- let completion_provider = editor.completion_provider().unwrap();
- completion_provider.completions(
- excerpt_id,
- &buffer,
- text::Anchor::MAX,
- CompletionContext {
- trigger_kind: CompletionTriggerKind::TRIGGER_CHARACTER,
- trigger_character: Some("@".into()),
- },
- window,
- cx,
- )
- });
- let [_, completion]: [_; 2] = completions
- .await
- .unwrap()
- .into_iter()
- .flat_map(|response| response.completions)
- .collect::<Vec<_>>()
- .try_into()
- .unwrap();
-
- editor.update_in(cx, |editor, window, cx| {
- let snapshot = editor.buffer().read(cx).snapshot(cx);
- let start = snapshot
- .anchor_in_excerpt(excerpt_id, completion.replace_range.start)
- .unwrap();
- let end = snapshot
- .anchor_in_excerpt(excerpt_id, completion.replace_range.end)
- .unwrap();
- editor.edit([(start..end, completion.new_text)], cx);
- (completion.confirm.unwrap())(CompletionIntent::Complete, window, cx);
- });
-
- cx.run_until_parked();
-
- let content = message_editor
- .update(cx, |message_editor, cx| message_editor.contents(cx))
- .await
- .unwrap();
- assert_eq!(content.len(), 2);
- assert_matches!(&content[0], &acp::ContentBlock::Text(_));
- assert_matches!(&content[1], &acp::ContentBlock::Resource(_));
-
- history.borrow_mut().push(content);
- message_editor.update_in(cx, |message_editor, window, cx| {
- message_editor.clear(window, cx);
- message_editor.previous_history_message(&Default::default(), window, cx);
- });
-
- let content = message_editor
- .update(cx, |message_editor, cx| message_editor.contents(cx))
- .await
- .unwrap();
- assert_eq!(content.len(), 2);
- assert_matches!(&content[0], &acp::ContentBlock::Text(_));
- assert_matches!(&content[1], &acp::ContentBlock::Resource(_));
- }
+ use crate::acp::{message_editor::MessageEditor, thread_view::tests::init_test};
#[gpui::test]
async fn test_at_mention_removal(cx: &mut TestAppContext) {
init_test(cx);
- let history = Rc::new(RefCell::new(MessageHistory::default()));
let fs = FakeFs::new(cx.executor());
fs.insert_tree("/project", json!({"file": ""})).await;
let project = Project::test(fs, [Path::new(path!("/project"))], cx).await;
@@ -601,15 +406,7 @@ mod tests {
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let message_editor = cx.update(|window, cx| {
- cx.new(|cx| {
- MessageEditor::new(
- workspace.downgrade(),
- project.clone(),
- history.clone(),
- window,
- cx,
- )
- })
+ cx.new(|cx| MessageEditor::new(workspace.downgrade(), project.clone(), window, cx))
});
let editor = message_editor.update(cx, |message_editor, _| message_editor.editor.clone());
@@ -25,7 +25,7 @@ use markdown::{HeadingLevelStyles, Markdown, MarkdownElement, MarkdownStyle};
use project::Project;
use rope::Point;
use settings::{Settings as _, SettingsStore};
-use std::{cell::RefCell, collections::BTreeMap, process::ExitStatus, rc::Rc, time::Duration};
+use std::{collections::BTreeMap, process::ExitStatus, rc::Rc, time::Duration};
use terminal_view::TerminalView;
use text::Anchor;
use theme::ThemeSettings;
@@ -39,7 +39,6 @@ use zed_actions::agent::{Chat, ToggleModelSelector};
use crate::acp::AcpModelSelectorPopover;
use crate::acp::message_editor::{MessageEditor, MessageEditorEvent};
-use crate::acp::message_history::MessageHistory;
use crate::agent_diff::AgentDiff;
use crate::ui::{AgentNotification, AgentNotificationEvent};
use crate::{
@@ -69,7 +68,6 @@ pub struct AcpThreadView {
plan_expanded: bool,
editor_expanded: bool,
terminal_expanded: bool,
- message_history: Rc<RefCell<MessageHistory<Vec<acp::ContentBlock>>>>,
_cancel_task: Option<Task<()>>,
_subscriptions: [Subscription; 2],
}
@@ -96,19 +94,11 @@ impl AcpThreadView {
agent: Rc<dyn AgentServer>,
workspace: WeakEntity<Workspace>,
project: Entity<Project>,
- message_history: Rc<RefCell<MessageHistory<Vec<acp::ContentBlock>>>>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
- let message_editor = cx.new(|cx| {
- MessageEditor::new(
- workspace.clone(),
- project.clone(),
- message_history.clone(),
- window,
- cx,
- )
- });
+ let message_editor =
+ cx.new(|cx| MessageEditor::new(workspace.clone(), project.clone(), window, cx));
let list_state = ListState::new(0, gpui::ListAlignment::Bottom, px(2048.0));
@@ -138,7 +128,6 @@ impl AcpThreadView {
plan_expanded: false,
editor_expanded: false,
terminal_expanded: true,
- message_history,
_subscriptions: subscriptions,
_cancel_task: None,
}
@@ -348,7 +337,6 @@ impl AcpThreadView {
this.message_editor.update(cx, |message_editor, cx| {
message_editor.clear(window, cx);
});
- this.message_history.borrow_mut().push(contents.clone());
})?;
let send = thread.update(cx, |thread, cx| thread.send(contents, cx))?;
send.await
@@ -3212,14 +3200,7 @@ pub(crate) mod tests {
let thread_view = cx.update(|window, cx| {
cx.new(|cx| {
- AcpThreadView::new(
- Rc::new(agent),
- workspace.downgrade(),
- project,
- Rc::new(RefCell::new(MessageHistory::default())),
- window,
- cx,
- )
+ AcpThreadView::new(Rc::new(agent), workspace.downgrade(), project, window, cx)
})
});
cx.run_until_parked();
@@ -1,4 +1,3 @@
-use std::cell::RefCell;
use std::ops::{Not, Range};
use std::path::Path;
use std::rc::Rc;
@@ -476,8 +475,6 @@ pub struct AgentPanel {
configuration_subscription: Option<Subscription>,
local_timezone: UtcOffset,
active_view: ActiveView,
- acp_message_history:
- Rc<RefCell<crate::acp::MessageHistory<Vec<agent_client_protocol::ContentBlock>>>>,
previous_view: Option<ActiveView>,
history_store: Entity<HistoryStore>,
history: Entity<ThreadHistory>,
@@ -765,7 +762,6 @@ impl AgentPanel {
.unwrap(),
inline_assist_context_store,
previous_view: None,
- acp_message_history: Default::default(),
history_store: history_store.clone(),
history: cx.new(|cx| ThreadHistory::new(weak_self, history_store, window, cx)),
hovered_recent_history_item: None,
@@ -962,7 +958,6 @@ impl AgentPanel {
) {
let workspace = self.workspace.clone();
let project = self.project.clone();
- let message_history = self.acp_message_history.clone();
let fs = self.fs.clone();
const LAST_USED_EXTERNAL_AGENT_KEY: &str = "agent_panel__last_used_external_agent";
@@ -1006,14 +1001,7 @@ impl AgentPanel {
this.update_in(cx, |this, window, cx| {
let thread_view = cx.new(|cx| {
- crate::acp::AcpThreadView::new(
- server,
- workspace.clone(),
- project,
- message_history,
- window,
- cx,
- )
+ crate::acp::AcpThreadView::new(server, workspace.clone(), project, window, cx)
});
this.set_active_view(ActiveView::ExternalAgentThread { thread_view }, window, cx);
@@ -1567,8 +1555,6 @@ impl AgentPanel {
self.active_view = new_view;
}
- self.acp_message_history.borrow_mut().reset_position();
-
self.focus_handle(cx).focus(window);
}