From 0f6956d214e848ffd102eb223c07816abd6c2319 Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Thu, 9 Jan 2025 19:25:50 -0300 Subject: [PATCH 1/5] Show file extension icon in file context picker Co-Authored-By: Nathan --- Cargo.lock | 1 + crates/assistant2/Cargo.toml | 1 + crates/assistant2/src/context_picker/file_context_picker.rs | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f90c71a6721ee..487a0e67a0152 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -469,6 +469,7 @@ dependencies = [ "db", "editor", "feature_flags", + "file_icons", "fs", "futures 0.3.31", "fuzzy", diff --git a/crates/assistant2/Cargo.toml b/crates/assistant2/Cargo.toml index 8b52a946a7d31..2a2010ec7b60b 100644 --- a/crates/assistant2/Cargo.toml +++ b/crates/assistant2/Cargo.toml @@ -73,6 +73,7 @@ util.workspace = true uuid.workspace = true workspace.workspace = true zed_actions.workspace = true +file_icons.workspace = true [dev-dependencies] rand.workspace = true diff --git a/crates/assistant2/src/context_picker/file_context_picker.rs b/crates/assistant2/src/context_picker/file_context_picker.rs index 288483bf2f1c6..6c43fff84d017 100644 --- a/crates/assistant2/src/context_picker/file_context_picker.rs +++ b/crates/assistant2/src/context_picker/file_context_picker.rs @@ -2,6 +2,7 @@ use std::path::Path; use std::sync::atomic::AtomicBool; use std::sync::Arc; +use file_icons::FileIcons; use fuzzy::PathMatch; use gpui::{AppContext, DismissEvent, FocusHandle, FocusableView, Task, View, WeakModel, WeakView}; use picker::{Picker, PickerDelegate}; @@ -281,6 +282,10 @@ impl PickerDelegate for FileContextPickerDelegate { .will_include_file_path(&path_match.path, cx) }); + let file_icon = FileIcons::get_icon(&path_match.path.clone(), cx) + .map(|icon_path| Icon::from_path(icon_path)) + .unwrap_or_else(|| Icon::new(IconName::File)); + Some( ListItem::new(ix) .inset(true) @@ -288,6 +293,7 @@ impl PickerDelegate for FileContextPickerDelegate { .child( h_flex() .gap_2() + .child(file_icon.size(IconSize::Small)) .child(Label::new(file_name)) .children(directory.map(|directory| { Label::new(directory) From 09422f87f63fea57a428f238df3d3dc766195377 Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Thu, 9 Jan 2025 19:52:33 -0300 Subject: [PATCH 2/5] Show extension icon in context pill Co-Authored-By: Nathan Co-Authored-By: Michael --- crates/assistant2/src/context.rs | 19 +++++++++++++++++++ crates/assistant2/src/context_store.rs | 1 + crates/assistant2/src/ui/context_pill.rs | 18 +++++++----------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/crates/assistant2/src/context.rs b/crates/assistant2/src/context.rs index ab0def6bc4876..a34f945ccf6a2 100644 --- a/crates/assistant2/src/context.rs +++ b/crates/assistant2/src/context.rs @@ -3,11 +3,13 @@ use std::rc::Rc; use std::sync::Arc; use collections::BTreeMap; +use file_icons::FileIcons; use gpui::{AppContext, Model, SharedString}; use language::Buffer; use language_model::{LanguageModelRequestMessage, MessageContent}; use serde::{Deserialize, Serialize}; use text::BufferId; +use ui::IconName; use util::post_inc; use crate::thread::Thread; @@ -28,6 +30,7 @@ pub struct ContextSnapshot { pub name: SharedString, pub parent: Option, pub tooltip: Option, + pub icon_path: Option, pub kind: ContextKind, /// Text to send to the model. This is not refreshed by `snapshot`. pub text: SharedString, @@ -41,6 +44,17 @@ pub enum ContextKind { Thread, } +impl ContextKind { + pub fn icon(&self) -> IconName { + match self { + ContextKind::File => IconName::File, + ContextKind::Directory => IconName::Folder, + ContextKind::FetchedUrl => IconName::Globe, + ContextKind::Thread => IconName::MessageCircle, + } + } +} + #[derive(Debug)] pub enum Context { File(FileContext), @@ -135,11 +149,14 @@ impl FileContext { .and_then(|p| p.file_name()) .map(|p| p.to_string_lossy().into_owned().into()); + let icon_path = FileIcons::get_icon(&path, cx); + Some(ContextSnapshot { id: self.id, name, parent, tooltip: Some(full_path), + icon_path, kind: ContextKind::File, text: self.text.clone(), }) @@ -159,6 +176,7 @@ impl FetchedUrlContext { name: self.url.clone(), parent: None, tooltip: None, + icon_path: None, kind: ContextKind::FetchedUrl, text: self.text.clone(), } @@ -173,6 +191,7 @@ impl ThreadContext { name: thread.summary().unwrap_or("New thread".into()), parent: None, tooltip: None, + icon_path: None, kind: ContextKind::Thread, text: self.text.clone(), } diff --git a/crates/assistant2/src/context_store.rs b/crates/assistant2/src/context_store.rs index 84b4d0b97bf0b..3929db49b6a00 100644 --- a/crates/assistant2/src/context_store.rs +++ b/crates/assistant2/src/context_store.rs @@ -234,6 +234,7 @@ impl ContextStore { name, parent, tooltip: Some(full_path), + icon_path: None, kind: ContextKind::Directory, text: text.into(), }, diff --git a/crates/assistant2/src/ui/context_pill.rs b/crates/assistant2/src/ui/context_pill.rs index e70169ed5f7aa..54861521d8d57 100644 --- a/crates/assistant2/src/ui/context_pill.rs +++ b/crates/assistant2/src/ui/context_pill.rs @@ -49,23 +49,19 @@ impl ContextPill { } } - pub fn kind(&self) -> ContextKind { + pub fn icon(&self) -> Icon { match self { - Self::Added { context, .. } => context.kind, - Self::Suggested { kind, .. } => *kind, + Self::Added { context, .. } => match &context.icon_path { + Some(icon_path) => Icon::from_path(icon_path), + None => Icon::new(context.kind.icon()), + }, + Self::Suggested { kind, .. } => Icon::new(kind.icon()), } } } impl RenderOnce for ContextPill { fn render(self, cx: &mut WindowContext) -> impl IntoElement { - let icon = match &self.kind() { - ContextKind::File => IconName::File, - ContextKind::Directory => IconName::Folder, - ContextKind::FetchedUrl => IconName::Globe, - ContextKind::Thread => IconName::MessageCircle, - }; - let color = cx.theme().colors(); let base_pill = h_flex() @@ -75,7 +71,7 @@ impl RenderOnce for ContextPill { .border_1() .rounded_md() .gap_1() - .child(Icon::new(icon).size(IconSize::XSmall).color(Color::Muted)); + .child(self.icon().size(IconSize::XSmall).color(Color::Muted)); match &self { ContextPill::Added { From c86080b585dbe1586a5b248e115c30b033bad49f Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Thu, 9 Jan 2025 20:01:03 -0300 Subject: [PATCH 3/5] Show extension icon for suggested context Co-Authored-By: Nathan Co-Authored-By: Michael --- crates/assistant2/src/context_strip.rs | 19 ++++++++++++++++- crates/assistant2/src/ui/context_pill.rs | 26 +++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/crates/assistant2/src/context_strip.rs b/crates/assistant2/src/context_strip.rs index f62d7991697da..7bc395b7bb3c3 100644 --- a/crates/assistant2/src/context_strip.rs +++ b/crates/assistant2/src/context_strip.rs @@ -2,6 +2,7 @@ use std::rc::Rc; use collections::HashSet; use editor::Editor; +use file_icons::FileIcons; use gpui::{ AppContext, DismissEvent, EventEmitter, FocusHandle, Model, Subscription, View, WeakModel, WeakView, @@ -94,9 +95,12 @@ impl ContextStrip { None => path.to_string_lossy().into_owned().into(), }; + let icon_path = FileIcons::get_icon(path, cx); + Some(SuggestedContext::File { name, buffer: active_buffer_model.downgrade(), + icon_path, }) } @@ -227,6 +231,7 @@ impl Render for ContextStrip { .when_some(suggested_context, |el, suggested| { el.child(ContextPill::new_suggested( suggested.name().clone(), + suggested.icon_path(), suggested.kind(), { let context_store = self.context_store.clone(); @@ -283,6 +288,7 @@ pub enum SuggestContextKind { pub enum SuggestedContext { File { name: SharedString, + icon_path: Option, buffer: WeakModel, }, Thread { @@ -299,9 +305,20 @@ impl SuggestedContext { } } + pub fn icon_path(&self) -> Option { + match self { + Self::File { icon_path, .. } => icon_path.clone(), + Self::Thread { .. } => None, + } + } + pub fn accept(&self, context_store: &mut ContextStore, cx: &mut AppContext) { match self { - Self::File { buffer, name: _ } => { + Self::File { + buffer, + icon_path: _, + name: _, + } => { if let Some(buffer) = buffer.upgrade() { context_store.insert_file(buffer, cx); }; diff --git a/crates/assistant2/src/ui/context_pill.rs b/crates/assistant2/src/ui/context_pill.rs index 54861521d8d57..6e5de11728809 100644 --- a/crates/assistant2/src/ui/context_pill.rs +++ b/crates/assistant2/src/ui/context_pill.rs @@ -14,6 +14,7 @@ pub enum ContextPill { }, Suggested { name: SharedString, + icon_path: Option, kind: ContextKind, on_add: Rc, }, @@ -34,10 +35,16 @@ impl ContextPill { pub fn new_suggested( name: SharedString, + icon_path: Option, kind: ContextKind, on_add: Rc, ) -> Self { - Self::Suggested { name, kind, on_add } + Self::Suggested { + name, + icon_path, + kind, + on_add, + } } pub fn id(&self) -> ElementId { @@ -55,7 +62,15 @@ impl ContextPill { Some(icon_path) => Icon::from_path(icon_path), None => Icon::new(context.kind.icon()), }, - Self::Suggested { kind, .. } => Icon::new(kind.icon()), + Self::Suggested { + icon_path: Some(icon_path), + .. + } => Icon::from_path(icon_path), + Self::Suggested { + kind, + icon_path: None, + .. + } => Icon::new(kind.icon()), } } } @@ -114,7 +129,12 @@ impl RenderOnce for ContextPill { }), ) }), - ContextPill::Suggested { name, kind, on_add } => base_pill + ContextPill::Suggested { + name, + icon_path: _, + kind, + on_add, + } => base_pill .cursor_pointer() .pr_1() .border_color(color.border_variant.opacity(0.5)) From eebb114097d9959a54ee58652abaa7e49db48754 Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Thu, 9 Jan 2025 20:07:52 -0300 Subject: [PATCH 4/5] Sort assistant2 deps --- crates/assistant2/Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/assistant2/Cargo.toml b/crates/assistant2/Cargo.toml index 2a2010ec7b60b..85220bc56f79e 100644 --- a/crates/assistant2/Cargo.toml +++ b/crates/assistant2/Cargo.toml @@ -18,15 +18,16 @@ anyhow.workspace = true assets.workspace = true assistant_tool.workspace = true async-watch.workspace = true +chrono.workspace = true client.workspace = true clock.workspace = true -chrono.workspace = true collections.workspace = true command_palette_hooks.workspace = true context_server.workspace = true db.workspace = true editor.workspace = true feature_flags.workspace = true +file_icons.workspace = true fs.workspace = true futures.workspace = true fuzzy.workspace = true @@ -47,8 +48,8 @@ multi_buffer.workspace = true ollama = { workspace = true, features = ["schemars"] } open_ai = { workspace = true, features = ["schemars"] } ordered-float.workspace = true -paths.workspace = true parking_lot.workspace = true +paths.workspace = true picker.workspace = true project.workspace = true proto.workspace = true @@ -61,9 +62,9 @@ settings.workspace = true similar.workspace = true smol.workspace = true telemetry_events.workspace = true +terminal.workspace = true terminal_view.workspace = true text.workspace = true -terminal.workspace = true theme.workspace = true time.workspace = true time_format.workspace = true @@ -73,7 +74,6 @@ util.workspace = true uuid.workspace = true workspace.workspace = true zed_actions.workspace = true -file_icons.workspace = true [dev-dependencies] rand.workspace = true From 55c2838dbd181ee7ba84b31c6f47ac17227d47e1 Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Thu, 9 Jan 2025 20:12:16 -0300 Subject: [PATCH 5/5] Fix cargo clippy --- crates/assistant2/src/context_picker/file_context_picker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/assistant2/src/context_picker/file_context_picker.rs b/crates/assistant2/src/context_picker/file_context_picker.rs index 6c43fff84d017..7fb467b7da893 100644 --- a/crates/assistant2/src/context_picker/file_context_picker.rs +++ b/crates/assistant2/src/context_picker/file_context_picker.rs @@ -283,7 +283,7 @@ impl PickerDelegate for FileContextPickerDelegate { }); let file_icon = FileIcons::get_icon(&path_match.path.clone(), cx) - .map(|icon_path| Icon::from_path(icon_path)) + .map(Icon::from_path) .unwrap_or_else(|| Icon::new(IconName::File)); Some(