From 2ed45d72d8aa8f6e9e64ea41982b01dbc2d4c1a1 Mon Sep 17 00:00:00 2001 From: Andrew Lygin Date: Mon, 5 Feb 2024 21:12:47 +0300 Subject: [PATCH] File finder UI enhancement (#7364) File finder looks and feels a little bulky now. It duplicates file names and consumes too much space for each file. This PR makes it more compact: - File name is trimmed from the path, removing duplication - Path is placed to the right of the file name, improving space usage - Path is muted and printed in small size to not distract attention from the main information (file names) It makes search results easier to look through, consistent with the editor tabs, and closer in terms of usage to mature editors. Release Notes: - File finder UI enhancement --- crates/file_finder/src/file_finder.rs | 19 ++++++++++++++++--- crates/file_finder/src/file_finder_tests.rs | 4 ++-- .../src/components/label/highlighted_label.rs | 4 +++- crates/ui/src/components/label/label_like.rs | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index be3d2feb83..d222682e80 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -566,7 +566,7 @@ impl FileFinderDelegate { let path = &path_match.path; let path_string = path.to_string_lossy(); let full_path = [path_match.path_prefix.as_ref(), path_string.as_ref()].join(""); - let path_positions = path_match.positions.clone(); + let mut path_positions = path_match.positions.clone(); let file_name = path.file_name().map_or_else( || path_match.path_prefix.to_string(), @@ -584,6 +584,14 @@ impl FileFinderDelegate { }) .collect(); + // Trim file name from the full path + let full_path = if full_path.len() > file_name.len() { + full_path[..full_path.len() - file_name.len() - 1].to_string() + } else { + "".to_string() + }; + path_positions.retain(|idx| *idx < full_path.len()); + (file_name, file_name_positions, full_path, path_positions) } @@ -868,9 +876,14 @@ impl PickerDelegate for FileFinderDelegate { .inset(true) .selected(selected) .child( - v_flex() + h_flex() + .gap_2() .child(HighlightedLabel::new(file_name, file_name_positions)) - .child(HighlightedLabel::new(full_path, full_path_positions)), + .child( + HighlightedLabel::new(full_path, full_path_positions) + .size(LabelSize::Small) + .color(Color::Muted), + ), ), ) } diff --git a/crates/file_finder/src/file_finder_tests.rs b/crates/file_finder/src/file_finder_tests.rs index 450d034614..f0e1626bd4 100644 --- a/crates/file_finder/src/file_finder_tests.rs +++ b/crates/file_finder/src/file_finder_tests.rs @@ -490,8 +490,8 @@ async fn test_single_file_worktrees(cx: &mut TestAppContext) { delegate.labels_for_path_match(&matches[0].0); assert_eq!(file_name, "the-file"); assert_eq!(file_name_positions, &[0, 1, 4]); - assert_eq!(full_path, "the-file"); - assert_eq!(full_path_positions, &[0, 1, 4]); + assert_eq!(full_path, ""); + assert_eq!(full_path_positions, &[0; 0]); }); // Since the worktree root is a file, searching for its name followed by a slash does diff --git a/crates/ui/src/components/label/highlighted_label.rs b/crates/ui/src/components/label/highlighted_label.rs index d70c2d1b51..41866bd10a 100644 --- a/crates/ui/src/components/label/highlighted_label.rs +++ b/crates/ui/src/components/label/highlighted_label.rs @@ -79,6 +79,8 @@ impl RenderOnce for HighlightedLabel { let mut text_style = cx.text_style().clone(); text_style.color = self.base.color.color(cx); - LabelLike::new().child(StyledText::new(self.label).with_highlights(&text_style, highlights)) + LabelLike::new() + .size(self.base.size) + .child(StyledText::new(self.label).with_highlights(&text_style, highlights)) } } diff --git a/crates/ui/src/components/label/label_like.rs b/crates/ui/src/components/label/label_like.rs index cddd849b89..f08ff1bf83 100644 --- a/crates/ui/src/components/label/label_like.rs +++ b/crates/ui/src/components/label/label_like.rs @@ -36,7 +36,7 @@ pub trait LabelCommon { #[derive(IntoElement)] pub struct LabelLike { - size: LabelSize, + pub(crate) size: LabelSize, line_height_style: LineHeightStyle, pub(crate) color: Color, strikethrough: bool,