Handle drag and drop in new agent threads (#35879)

This is a bit simpler than for the original agent thread view, since we
don't have to deal with opening buffers or a context store.

Release Notes:

- N/A
This commit is contained in:
Cole Miller 2025-08-08 15:03:50 -04:00 committed by GitHub
parent 2cde6da5ff
commit f3a58b50c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 61 additions and 4 deletions

View file

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

View file

@ -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<project::ProjectPath>,
_added_worktrees: Vec<Entity<project::Worktree>>,
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 {

View file

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