diff --git a/crates/agent_ui/src/acp/completion_provider.rs b/crates/agent_ui/src/acp/completion_provider.rs index fca4ae0300..d8f452afa5 100644 --- a/crates/agent_ui/src/acp/completion_provider.rs +++ b/crates/agent_ui/src/acp/completion_provider.rs @@ -59,7 +59,7 @@ impl ContextPickerCompletionProvider { } } - fn completion_for_path( + pub(crate) fn completion_for_path( project_path: ProjectPath, path_prefix: &str, is_recent: bool, diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 74bbac2b1c..6411abb84f 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -30,7 +30,7 @@ use language::language_settings::SoftWrap; use language::{Buffer, Language}; use markdown::{HeadingLevelStyles, Markdown, MarkdownElement, MarkdownStyle}; use parking_lot::Mutex; -use project::Project; +use project::{CompletionIntent, Project}; use settings::{Settings as _, SettingsStore}; use text::{Anchor, BufferSnapshot}; use theme::ThemeSettings; @@ -2611,6 +2611,61 @@ impl AcpThreadView { }) } } + + pub(crate) fn insert_dragged_files( + &self, + paths: Vec, + _added_worktrees: Vec>, + window: &mut Window, + cx: &mut Context<'_, Self>, + ) { + let buffer = self.message_editor.read(cx).buffer().clone(); + let Some((&excerpt_id, _, _)) = buffer.read(cx).snapshot(cx).as_singleton() else { + return; + }; + let Some(buffer) = buffer.read(cx).as_singleton() else { + return; + }; + for path in paths { + let Some(entry) = self.project.read(cx).entry_for_path(&path, cx) else { + continue; + }; + let Some(abs_path) = self.project.read(cx).absolute_path(&path, cx) else { + continue; + }; + + let anchor = buffer.update(cx, |buffer, _cx| buffer.anchor_before(buffer.len())); + let path_prefix = abs_path + .file_name() + .unwrap_or(path.path.as_os_str()) + .display() + .to_string(); + let completion = ContextPickerCompletionProvider::completion_for_path( + path, + &path_prefix, + false, + entry.is_dir(), + excerpt_id, + anchor..anchor, + self.message_editor.clone(), + self.mention_set.clone(), + cx, + ); + + self.message_editor.update(cx, |message_editor, cx| { + message_editor.edit( + [( + multi_buffer::Anchor::max()..multi_buffer::Anchor::max(), + completion.new_text, + )], + cx, + ); + }); + if let Some(confirm) = completion.confirm.clone() { + confirm(CompletionIntent::Complete, window, cx); + } + } + } } impl Focusable for AcpThreadView { diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 6b8e36066b..87e4dd822c 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -3187,8 +3187,10 @@ impl AgentPanel { .detach(); }); } - ActiveView::ExternalAgentThread { .. } => { - unimplemented!() + ActiveView::ExternalAgentThread { thread_view } => { + thread_view.update(cx, |thread_view, cx| { + thread_view.insert_dragged_files(paths, added_worktrees, window, cx); + }); } ActiveView::TextThread { context_editor, .. } => { context_editor.update(cx, |context_editor, cx| {