Detailed changes
@@ -24,6 +24,7 @@ pub struct Context {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ContextKind {
File,
+ Directory,
FetchedUrl,
Thread,
}
@@ -33,6 +34,7 @@ pub fn attach_context_to_message(
context: impl IntoIterator<Item = Context>,
) {
let mut file_context = String::new();
+ let mut directory_context = String::new();
let mut fetch_context = String::new();
let mut thread_context = String::new();
@@ -42,6 +44,10 @@ pub fn attach_context_to_message(
file_context.push_str(&context.text);
file_context.push('\n');
}
+ ContextKind::Directory => {
+ directory_context.push_str(&context.text);
+ directory_context.push('\n');
+ }
ContextKind::FetchedUrl => {
fetch_context.push_str(&context.name);
fetch_context.push('\n');
@@ -63,6 +69,11 @@ pub fn attach_context_to_message(
context_text.push_str(&file_context);
}
+ if !directory_context.is_empty() {
+ context_text.push_str("The following directories are available:\n");
+ context_text.push_str(&directory_context);
+ }
+
if !fetch_context.is_empty() {
context_text.push_str("The following fetched results are available\n");
context_text.push_str(&fetch_context);
@@ -1,3 +1,4 @@
+mod directory_context_picker;
mod fetch_context_picker;
mod file_context_picker;
mod thread_context_picker;
@@ -14,6 +15,7 @@ use util::ResultExt;
use workspace::Workspace;
use crate::context::ContextKind;
+use crate::context_picker::directory_context_picker::DirectoryContextPicker;
use crate::context_picker::fetch_context_picker::FetchContextPicker;
use crate::context_picker::file_context_picker::FileContextPicker;
use crate::context_picker::thread_context_picker::ThreadContextPicker;
@@ -24,6 +26,7 @@ use crate::thread_store::ThreadStore;
enum ContextPickerMode {
Default,
File(View<FileContextPicker>),
+ Directory(View<DirectoryContextPicker>),
Fetch(View<FetchContextPicker>),
Thread(View<ThreadContextPicker>),
}
@@ -46,6 +49,11 @@ impl ContextPicker {
kind: ContextKind::File,
icon: IconName::File,
},
+ ContextPickerEntry {
+ name: "Folder".into(),
+ kind: ContextKind::Directory,
+ icon: IconName::Folder,
+ },
ContextPickerEntry {
name: "Fetch".into(),
kind: ContextKind::FetchedUrl,
@@ -92,6 +100,7 @@ impl FocusableView for ContextPicker {
match &self.mode {
ContextPickerMode::Default => self.picker.focus_handle(cx),
ContextPickerMode::File(file_picker) => file_picker.focus_handle(cx),
+ ContextPickerMode::Directory(directory_picker) => directory_picker.focus_handle(cx),
ContextPickerMode::Fetch(fetch_picker) => fetch_picker.focus_handle(cx),
ContextPickerMode::Thread(thread_picker) => thread_picker.focus_handle(cx),
}
@@ -106,6 +115,9 @@ impl Render for ContextPicker {
.map(|parent| match &self.mode {
ContextPickerMode::Default => parent.child(self.picker.clone()),
ContextPickerMode::File(file_picker) => parent.child(file_picker.clone()),
+ ContextPickerMode::Directory(directory_picker) => {
+ parent.child(directory_picker.clone())
+ }
ContextPickerMode::Fetch(fetch_picker) => parent.child(fetch_picker.clone()),
ContextPickerMode::Thread(thread_picker) => parent.child(thread_picker.clone()),
})
@@ -167,6 +179,16 @@ impl PickerDelegate for ContextPickerDelegate {
)
}));
}
+ ContextKind::Directory => {
+ this.mode = ContextPickerMode::Directory(cx.new_view(|cx| {
+ DirectoryContextPicker::new(
+ self.context_picker.clone(),
+ self.workspace.clone(),
+ self.context_store.clone(),
+ cx,
+ )
+ }));
+ }
ContextKind::FetchedUrl => {
this.mode = ContextPickerMode::Fetch(cx.new_view(|cx| {
FetchContextPicker::new(
@@ -202,6 +224,7 @@ impl PickerDelegate for ContextPickerDelegate {
.update(cx, |this, cx| match this.mode {
ContextPickerMode::Default => cx.emit(DismissEvent),
ContextPickerMode::File(_)
+ | ContextPickerMode::Directory(_)
| ContextPickerMode::Fetch(_)
| ContextPickerMode::Thread(_) => {}
})
@@ -0,0 +1,117 @@
+// TODO: Remove this once we've implemented the functionality.
+#![allow(unused)]
+
+use std::sync::Arc;
+
+use fuzzy::PathMatch;
+use gpui::{AppContext, DismissEvent, FocusHandle, FocusableView, Task, View, WeakModel, WeakView};
+use picker::{Picker, PickerDelegate};
+use project::{PathMatchCandidateSet, WorktreeId};
+use ui::{prelude::*, ListItem};
+use util::ResultExt as _;
+use workspace::Workspace;
+
+use crate::context_picker::ContextPicker;
+use crate::context_store::ContextStore;
+
+pub struct DirectoryContextPicker {
+ picker: View<Picker<DirectoryContextPickerDelegate>>,
+}
+
+impl DirectoryContextPicker {
+ pub fn new(
+ context_picker: WeakView<ContextPicker>,
+ workspace: WeakView<Workspace>,
+ context_store: WeakModel<ContextStore>,
+ cx: &mut ViewContext<Self>,
+ ) -> Self {
+ let delegate =
+ DirectoryContextPickerDelegate::new(context_picker, workspace, context_store);
+ let picker = cx.new_view(|cx| Picker::uniform_list(delegate, cx));
+
+ Self { picker }
+ }
+}
+
+impl FocusableView for DirectoryContextPicker {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
+ self.picker.focus_handle(cx)
+ }
+}
+
+impl Render for DirectoryContextPicker {
+ fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
+ self.picker.clone()
+ }
+}
+
+pub struct DirectoryContextPickerDelegate {
+ context_picker: WeakView<ContextPicker>,
+ workspace: WeakView<Workspace>,
+ context_store: WeakModel<ContextStore>,
+ matches: Vec<PathMatch>,
+ selected_index: usize,
+}
+
+impl DirectoryContextPickerDelegate {
+ pub fn new(
+ context_picker: WeakView<ContextPicker>,
+ workspace: WeakView<Workspace>,
+ context_store: WeakModel<ContextStore>,
+ ) -> Self {
+ Self {
+ context_picker,
+ workspace,
+ context_store,
+ matches: Vec::new(),
+ selected_index: 0,
+ }
+ }
+}
+
+impl PickerDelegate for DirectoryContextPickerDelegate {
+ type ListItem = ListItem;
+
+ fn match_count(&self) -> usize {
+ self.matches.len()
+ }
+
+ fn selected_index(&self) -> usize {
+ self.selected_index
+ }
+
+ fn set_selected_index(&mut self, ix: usize, cx: &mut ViewContext<Picker<Self>>) {
+ self.selected_index = ix;
+ }
+
+ fn placeholder_text(&self, _cx: &mut WindowContext) -> Arc<str> {
+ "Search foldersβ¦".into()
+ }
+
+ fn update_matches(&mut self, _query: String, _cx: &mut ViewContext<Picker<Self>>) -> Task<()> {
+ // TODO: Implement this once we fix the issues with the file context picker.
+ Task::ready(())
+ }
+
+ fn confirm(&mut self, _secondary: bool, _cx: &mut ViewContext<Picker<Self>>) {
+ // TODO: Implement this once we fix the issues with the file context picker.
+ }
+
+ fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
+ self.context_picker
+ .update(cx, |this, cx| {
+ this.reset_mode();
+ cx.emit(DismissEvent);
+ })
+ .ok();
+ }
+
+ fn render_match(
+ &self,
+ _ix: usize,
+ _selected: bool,
+ _cx: &mut ViewContext<Picker<Self>>,
+ ) -> Option<Self::ListItem> {
+ None
+ }
+}