Cargo.lock 🔗
@@ -9496,6 +9496,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"editor",
+ "file_icons",
"fuzzy",
"gpui",
"itertools 0.11.0",
Piotr Osiewicz created
Before:

After:

Release Notes:
- N/A
Cargo.lock | 1
crates/file_icons/src/file_icons.rs | 24 +++++-------
crates/tasks_ui/Cargo.toml | 2 +
crates/tasks_ui/src/modal.rs | 57 +++++++++++++++---------------
4 files changed, 42 insertions(+), 42 deletions(-)
@@ -9496,6 +9496,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"editor",
+ "file_icons",
"fuzzy",
"gpui",
"itertools 0.11.0",
@@ -54,18 +54,20 @@ impl FileIcons {
let suffix = path.icon_stem_or_suffix()?;
if let Some(type_str) = this.stems.get(suffix) {
- return this
- .types
- .get(type_str)
- .map(|type_config| type_config.icon.clone());
+ return this.get_type_icon(type_str);
}
this.suffixes
.get(suffix)
- .and_then(|type_str| this.types.get(type_str))
- .map(|type_config| type_config.icon.clone())
+ .and_then(|type_str| this.get_type_icon(type_str))
})
- .or_else(|| this.types.get("default").map(|config| config.icon.clone()))
+ .or_else(|| this.get_type_icon("default"))
+ }
+
+ pub fn get_type_icon(&self, typ: &str) -> Option<Arc<str>> {
+ self.types
+ .get(typ)
+ .map(|type_config| type_config.icon.clone())
}
pub fn get_folder_icon(expanded: bool, cx: &AppContext) -> Option<Arc<str>> {
@@ -77,9 +79,7 @@ impl FileIcons {
COLLAPSED_DIRECTORY_TYPE
};
- this.types
- .get(key)
- .map(|type_config| type_config.icon.clone())
+ this.get_type_icon(key)
}
pub fn get_chevron_icon(expanded: bool, cx: &AppContext) -> Option<Arc<str>> {
@@ -91,8 +91,6 @@ impl FileIcons {
COLLAPSED_CHEVRON_TYPE
};
- this.types
- .get(key)
- .map(|type_config| type_config.icon.clone())
+ this.get_type_icon(key)
}
}
@@ -11,6 +11,7 @@ workspace = true
[dependencies]
anyhow.workspace = true
editor.workspace = true
+file_icons.workspace = true
fuzzy.workspace = true
gpui.workspace = true
picker.workspace = true
@@ -23,6 +24,7 @@ workspace.workspace = true
language.workspace = true
itertools.workspace = true
+
[dev-dependencies]
editor = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
@@ -3,22 +3,19 @@ use std::sync::Arc;
use crate::{active_item_selection_properties, schedule_task};
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
- impl_actions, rems, AppContext, DismissEvent, EventEmitter, FocusableView, InteractiveElement,
- Model, ParentElement, Render, SharedString, Styled, Subscription, View, ViewContext,
- VisualContext, WeakView,
-};
-use picker::{
- highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
- Picker, PickerDelegate,
+ impl_actions, rems, AppContext, DismissEvent, EventEmitter, FocusableView, Global,
+ InteractiveElement, Model, ParentElement, Render, SharedString, Styled, Subscription, View,
+ ViewContext, VisualContext, WeakView,
};
+use picker::{highlighted_match_with_paths::HighlightedText, Picker, PickerDelegate};
use project::{Inventory, TaskSourceKind};
use task::{oneshot_source::OneshotSource, Task, TaskContext};
use ui::{
- div, v_flex, ButtonCommon, ButtonSize, Clickable, Color, FluentBuilder as _, IconButton,
+ div, v_flex, ButtonCommon, ButtonSize, Clickable, Color, FluentBuilder as _, Icon, IconButton,
IconButtonShape, IconName, IconSize, ListItem, ListItemSpacing, RenderOnce, Selectable,
Tooltip, WindowContext,
};
-use util::{paths::PathExt, ResultExt};
+use util::ResultExt;
use workspace::{ModalView, Workspace};
use serde::Deserialize;
@@ -285,34 +282,31 @@ impl PickerDelegate for TasksModalDelegate {
cx: &mut ViewContext<picker::Picker<Self>>,
) -> Option<Self::ListItem> {
let candidates = self.candidates.as_ref()?;
- let hit = &self.matches.get(ix)?;
- let (source_kind, _) = &candidates.get(hit.candidate_id)?;
- let details = match source_kind {
- TaskSourceKind::UserInput => "user input".to_string(),
- TaskSourceKind::Language { name } => format!("{name} language"),
- TaskSourceKind::Worktree { abs_path, .. } | TaskSourceKind::AbsPath(abs_path) => {
- abs_path.compact().to_string_lossy().to_string()
- }
+ let hit = &self.matches[ix];
+ let (source_kind, _) = &candidates[hit.candidate_id];
+ let language_name = if let TaskSourceKind::Language { name } = source_kind {
+ Some(name)
+ } else {
+ None
};
- let highlighted_location = HighlightedMatchWithPaths {
- match_label: HighlightedText {
- text: hit.string.clone(),
- highlight_positions: hit.positions.clone(),
- char_count: hit.string.chars().count(),
- },
- paths: vec![HighlightedText {
- char_count: details.chars().count(),
- highlight_positions: Vec::new(),
- text: details,
- }],
+ let highlighted_location = HighlightedText {
+ text: hit.string.clone(),
+ highlight_positions: hit.positions.clone(),
+ char_count: hit.string.chars().count(),
};
+ let language_icon = language_name
+ .and_then(|language| {
+ let language = language.to_lowercase();
+ file_icons::FileIcons::get(cx).get_type_icon(&language)
+ })
+ .map(|icon_path| Icon::from_path(icon_path));
Some(
ListItem::new(SharedString::from(format!("tasks-modal-{ix}")))
.inset(true)
.spacing(ListItemSpacing::Sparse)
.map(|this| {
- if matches!(source_kind, TaskSourceKind::UserInput) {
+ let this = if matches!(source_kind, TaskSourceKind::UserInput) {
let task_index = hit.candidate_id;
let delete_button = div().child(
IconButton::new("delete", IconName::Close)
@@ -332,6 +326,11 @@ impl PickerDelegate for TasksModalDelegate {
this.end_hover_slot(delete_button)
} else {
this
+ };
+ if let Some(icon) = language_icon {
+ this.end_slot(icon)
+ } else {
+ this
}
})
.selected(selected)