assistant2: Wire up the directory context picker (#22582)
This PR wires up the functionality of the directory context picker. Release Notes: - N/A --------- Co-authored-by: Agus <agus@zed.dev>
This commit is contained in:
parent
3cf5ab16a9
commit
2c2ca9e370
5 changed files with 75 additions and 20 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -494,7 +494,6 @@ dependencies = [
|
||||||
"project",
|
"project",
|
||||||
"proto",
|
"proto",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"release_channel",
|
|
||||||
"rope",
|
"rope",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -50,7 +50,6 @@ parking_lot.workspace = true
|
||||||
picker.workspace = true
|
picker.workspace = true
|
||||||
project.workspace = true
|
project.workspace = true
|
||||||
proto.workspace = true
|
proto.workspace = true
|
||||||
release_channel.workspace = true
|
|
||||||
rope.workspace = true
|
rope.workspace = true
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|
|
@ -10,7 +10,6 @@ use gpui::{
|
||||||
WeakModel, WeakView,
|
WeakModel, WeakView,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use release_channel::ReleaseChannel;
|
|
||||||
use ui::{prelude::*, ListItem, ListItemSpacing};
|
use ui::{prelude::*, ListItem, ListItemSpacing};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
@ -56,16 +55,11 @@ impl ContextPicker {
|
||||||
kind: ContextPickerEntryKind::File,
|
kind: ContextPickerEntryKind::File,
|
||||||
icon: IconName::File,
|
icon: IconName::File,
|
||||||
});
|
});
|
||||||
let release_channel = ReleaseChannel::global(cx);
|
entries.push(ContextPickerEntry {
|
||||||
// The directory context picker isn't fully implemented yet, so limit it
|
name: "Folder".into(),
|
||||||
// to development builds.
|
kind: ContextPickerEntryKind::Directory,
|
||||||
if release_channel == ReleaseChannel::Dev {
|
icon: IconName::Folder,
|
||||||
entries.push(ContextPickerEntry {
|
});
|
||||||
name: "Folder".into(),
|
|
||||||
kind: ContextPickerEntryKind::Directory,
|
|
||||||
icon: IconName::Folder,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
entries.push(ContextPickerEntry {
|
entries.push(ContextPickerEntry {
|
||||||
name: "Fetch".into(),
|
name: "Fetch".into(),
|
||||||
kind: ContextPickerEntryKind::FetchedUrl,
|
kind: ContextPickerEntryKind::FetchedUrl,
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
// TODO: Remove this when we finish the implementation.
|
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
use fuzzy::PathMatch;
|
use fuzzy::PathMatch;
|
||||||
use gpui::{AppContext, DismissEvent, FocusHandle, FocusableView, Task, View, WeakModel, WeakView};
|
use gpui::{AppContext, DismissEvent, FocusHandle, FocusableView, Task, View, WeakModel, WeakView};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use project::{PathMatchCandidateSet, WorktreeId};
|
use project::{PathMatchCandidateSet, ProjectPath, Worktree, WorktreeId};
|
||||||
use ui::{prelude::*, ListItem};
|
use ui::{prelude::*, ListItem};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::context::ContextKind;
|
use crate::context::ContextKind;
|
||||||
|
use crate::context_picker::file_context_picker::codeblock_fence_for_path;
|
||||||
use crate::context_picker::{ConfirmBehavior, ContextPicker};
|
use crate::context_picker::{ConfirmBehavior, ContextPicker};
|
||||||
use crate::context_store::ContextStore;
|
use crate::context_store::ContextStore;
|
||||||
|
|
||||||
|
@ -193,14 +192,61 @@ impl PickerDelegate for DirectoryContextPickerDelegate {
|
||||||
let worktree_id = WorktreeId::from_usize(mat.worktree_id);
|
let worktree_id = WorktreeId::from_usize(mat.worktree_id);
|
||||||
let confirm_behavior = self.confirm_behavior;
|
let confirm_behavior = self.confirm_behavior;
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
|
let worktree = project.update(&mut cx, |project, cx| {
|
||||||
|
project
|
||||||
|
.worktree_for_id(worktree_id, cx)
|
||||||
|
.ok_or_else(|| anyhow!("no worktree found for {worktree_id:?}"))
|
||||||
|
})??;
|
||||||
|
|
||||||
|
let files = worktree.update(&mut cx, |worktree, _cx| {
|
||||||
|
collect_files_in_path(worktree, &path)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let open_buffer_tasks = project.update(&mut cx, |project, cx| {
|
||||||
|
files
|
||||||
|
.into_iter()
|
||||||
|
.map(|file_path| {
|
||||||
|
project.open_buffer(
|
||||||
|
ProjectPath {
|
||||||
|
worktree_id,
|
||||||
|
path: file_path.clone(),
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let open_all_buffers_tasks = cx.background_executor().spawn(async move {
|
||||||
|
let mut buffers = Vec::with_capacity(open_buffer_tasks.len());
|
||||||
|
|
||||||
|
for open_buffer_task in open_buffer_tasks {
|
||||||
|
let buffer = open_buffer_task.await?;
|
||||||
|
|
||||||
|
buffers.push(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
anyhow::Ok(buffers)
|
||||||
|
});
|
||||||
|
|
||||||
|
let buffers = open_all_buffers_tasks.await?;
|
||||||
|
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
|
|
||||||
// TODO: Add the files from the selected directory.
|
for buffer in buffers {
|
||||||
|
text.push_str(&codeblock_fence_for_path(Some(&path), None));
|
||||||
|
text.push_str(&buffer.read(cx).text());
|
||||||
|
if !text.ends_with('\n') {
|
||||||
|
text.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
text.push_str("```\n");
|
||||||
|
}
|
||||||
|
|
||||||
this.delegate
|
this.delegate
|
||||||
.context_store
|
.context_store
|
||||||
.update(cx, |context_store, cx| {
|
.update(cx, |context_store, _cx| {
|
||||||
context_store.insert_context(
|
context_store.insert_context(
|
||||||
ContextKind::Directory,
|
ContextKind::Directory,
|
||||||
path.to_string_lossy().to_string(),
|
path.to_string_lossy().to_string(),
|
||||||
|
@ -247,3 +293,17 @@ impl PickerDelegate for DirectoryContextPickerDelegate {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_files_in_path(worktree: &Worktree, path: &Path) -> Vec<Arc<Path>> {
|
||||||
|
let mut files = Vec::new();
|
||||||
|
|
||||||
|
for entry in worktree.child_entries(path) {
|
||||||
|
if entry.is_dir() {
|
||||||
|
files.extend(collect_files_in_path(worktree, &entry.path));
|
||||||
|
} else if entry.is_file() {
|
||||||
|
files.push(entry.path.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
files
|
||||||
|
}
|
||||||
|
|
|
@ -316,7 +316,10 @@ impl PickerDelegate for FileContextPickerDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn codeblock_fence_for_path(path: Option<&Path>, row_range: Option<RangeInclusive<u32>>) -> String {
|
pub(crate) fn codeblock_fence_for_path(
|
||||||
|
path: Option<&Path>,
|
||||||
|
row_range: Option<RangeInclusive<u32>>,
|
||||||
|
) -> String {
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
write!(text, "```").unwrap();
|
write!(text, "```").unwrap();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue