Merge branch 'main' into nate/extend-syntax

Nate Butler created

Change summary

assets/keymaps/vim.json                      |  3 
crates/feedback/src/feedback.rs              | 14 ++++++
crates/feedback/src/feedback_info_text.rs    | 47 +++++++++++++++++++--
crates/fuzzy/src/paths.rs                    | 19 ++++++++
crates/theme/src/theme.rs                    |  4 +
crates/zed/resources/app-icon-preview.png    |  0 
crates/zed/resources/app-icon-preview@2x.png |  0 
crates/zed/resources/app-icon.png            |  0 
crates/zed/resources/app-icon@2x.png         |  0 
styles/src/styleTree/feedback.ts             |  4 +
10 files changed, 81 insertions(+), 10 deletions(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -234,7 +234,8 @@
             "escape": [
                 "vim::SwitchMode",
                 "Normal"
-            ]
+            ],
+            "d": "editor::GoToDefinition"
         }
     },
     {

crates/feedback/src/feedback.rs 🔗

@@ -20,7 +20,12 @@ impl_actions!(zed, [OpenBrowser]);
 
 actions!(
     zed,
-    [CopySystemSpecsIntoClipboard, FileBugReport, RequestFeature]
+    [
+        CopySystemSpecsIntoClipboard,
+        FileBugReport,
+        RequestFeature,
+        OpenZedCommunityRepo
+    ]
 );
 
 pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
@@ -66,4 +71,11 @@ pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
             });
         },
     );
+
+    cx.add_action(
+        |_: &mut Workspace, _: &OpenZedCommunityRepo, cx: &mut ViewContext<Workspace>| {
+            let url = "https://github.com/zed-industries/community";
+            cx.dispatch_action(OpenBrowser { url: url.into() });
+        },
+    );
 }

crates/feedback/src/feedback_info_text.rs 🔗

@@ -1,10 +1,12 @@
 use gpui::{
-    elements::Label, Element, ElementBox, Entity, RenderContext, View, ViewContext, ViewHandle,
+    elements::{Flex, Label, MouseEventHandler, ParentElement, Text},
+    CursorStyle, Element, ElementBox, Entity, MouseButton, RenderContext, View, ViewContext,
+    ViewHandle,
 };
 use settings::Settings;
 use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
 
-use crate::feedback_editor::FeedbackEditor;
+use crate::{feedback_editor::FeedbackEditor, OpenZedCommunityRepo};
 
 pub struct FeedbackInfoText {
     active_item: Option<ViewHandle<FeedbackEditor>>,
@@ -29,9 +31,44 @@ impl View for FeedbackInfoText {
 
     fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
         let theme = cx.global::<Settings>().theme.clone();
-        let text = "We read whatever you submit here. For issues and discussions, visit the community repo on GitHub.";
-        Label::new(text, theme.feedback.info_text.text.clone())
-            .contained()
+
+        Flex::row()
+            .with_child(
+                Text::new(
+                    "We read whatever you submit here. For issues and discussions, visit the ",
+                    theme.feedback.info_text_default.text.clone(),
+                )
+                .with_soft_wrap(false)
+                .aligned()
+                .boxed(),
+            )
+            .with_child(
+                MouseEventHandler::<OpenZedCommunityRepo>::new(0, cx, |state, _| {
+                    let contained_text = if state.hovered() {
+                        &theme.feedback.link_text_hover
+                    } else {
+                        &theme.feedback.link_text_default
+                    };
+
+                    Label::new("community repo", contained_text.text.clone())
+                        .contained()
+                        .aligned()
+                        .left()
+                        .clipped()
+                        .boxed()
+                })
+                .with_cursor_style(CursorStyle::PointingHand)
+                .on_click(MouseButton::Left, |_, cx| {
+                    cx.dispatch_action(OpenZedCommunityRepo)
+                })
+                .boxed(),
+            )
+            .with_child(
+                Text::new(" on GitHub.", theme.feedback.info_text_default.text.clone())
+                    .with_soft_wrap(false)
+                    .aligned()
+                    .boxed(),
+            )
             .aligned()
             .left()
             .clipped()

crates/fuzzy/src/paths.rs 🔗

@@ -198,6 +198,23 @@ fn distance_between_paths(path: &Path, relative_to: &Path) -> usize {
     let mut path_components = path.components();
     let mut relative_components = relative_to.components();
 
-    while path_components.next() == relative_components.next() {}
+    while path_components
+        .next()
+        .zip(relative_components.next())
+        .map(|(path_component, relative_component)| path_component == relative_component)
+        .unwrap_or_default()
+    {}
     path_components.count() + relative_components.count() + 1
 }
+
+#[cfg(test)]
+mod tests {
+    use std::path::Path;
+
+    use super::distance_between_paths;
+
+    #[test]
+    fn test_distance_between_paths_empty() {
+        distance_between_paths(Path::new(""), Path::new(""));
+    }
+}

crates/theme/src/theme.rs 🔗

@@ -821,7 +821,9 @@ pub struct TerminalStyle {
 pub struct FeedbackStyle {
     pub submit_button: Interactive<ContainedText>,
     pub button_margin: f32,
-    pub info_text: ContainedText,
+    pub info_text_default: ContainedText,
+    pub link_text_default: ContainedText,
+    pub link_text_hover: ContainedText,
 }
 
 #[derive(Clone, Deserialize, Default)]

styles/src/styleTree/feedback.ts 🔗

@@ -31,6 +31,8 @@ export default function feedback(colorScheme: ColorScheme) {
             },
         },
         button_margin: 8,
-        info_text: text(layer, "sans", "default", { size: "xs" }),
+        info_text_default: text(layer, "sans", "default", { size: "xs" }),
+        link_text_default: text(layer, "sans", "default", { size: "xs", underline: true }),
+        link_text_hover: text(layer, "sans", "hovered", { size: "xs", underline: true })
     }
 }