More zed2 fixes (#3814)

Kirill Bulatov created

Change summary

crates/breadcrumbs2/src/breadcrumbs.rs        |  58 +++-------
crates/file_finder2/src/file_finder.rs        |   2 
crates/project2/src/terminals.rs              |   1 
crates/project2/src/worktree.rs               |   1 
crates/terminal2/src/terminal2.rs             | 113 +++++++++++++++++++-
crates/terminal_view2/src/terminal_element.rs | 111 +-------------------
6 files changed, 129 insertions(+), 157 deletions(-)

Detailed changes

crates/breadcrumbs2/src/breadcrumbs.rs 🔗

@@ -11,10 +11,6 @@ use workspace::{
     ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
 };
 
-pub enum Event {
-    UpdateLocation,
-}
-
 pub struct Breadcrumbs {
     pane_focused: bool,
     active_item: Option<Box<dyn ItemHandle>>,
@@ -31,7 +27,6 @@ impl Breadcrumbs {
     }
 }
 
-impl EventEmitter<Event> for Breadcrumbs {}
 impl EventEmitter<ToolbarItemEvent> for Breadcrumbs {}
 
 impl Render for Breadcrumbs {
@@ -39,15 +34,9 @@ impl Render for Breadcrumbs {
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
         let element = h_stack().text_ui();
-
-        let Some(active_item) = &self
-            .active_item
-            .as_ref()
-            .filter(|item| item.downcast::<editor::Editor>().is_some())
-        else {
+        let Some(active_item) = self.active_item.as_ref() else {
             return element;
         };
-
         let Some(segments) = active_item.breadcrumbs(cx.theme(), cx) else {
             return element;
         };
@@ -64,21 +53,24 @@ impl Render for Breadcrumbs {
             Label::new("›").color(Color::Muted).into_any_element()
         });
 
-        let editor = active_item
+        let breadcrumbs_stack = h_stack().gap_1().children(breadcrumbs);
+        match active_item
             .downcast::<Editor>()
-            .map(|editor| editor.downgrade());
-
-        element.child(
-            ButtonLike::new("toggle outline view")
-                .style(ButtonStyle::Subtle)
-                .child(h_stack().gap_1().children(breadcrumbs))
-                .on_click(move |_, cx| {
-                    if let Some(editor) = editor.as_ref().and_then(|editor| editor.upgrade()) {
-                        outline::toggle(editor, &outline::Toggle, cx)
-                    }
-                })
-                .tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)),
-        )
+            .map(|editor| editor.downgrade())
+        {
+            Some(editor) => element.child(
+                ButtonLike::new("toggle outline view")
+                    .child(breadcrumbs_stack)
+                    .style(ButtonStyle::Subtle)
+                    .on_click(move |_, cx| {
+                        if let Some(editor) = editor.upgrade() {
+                            outline::toggle(editor, &outline::Toggle, cx)
+                        }
+                    })
+                    .tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)),
+            ),
+            None => element.child(breadcrumbs_stack),
+        }
     }
 }
 
@@ -97,7 +89,6 @@ impl ToolbarItemView for Breadcrumbs {
                 Box::new(move |event, cx| {
                     if let ItemEvent::UpdateBreadcrumbs = event {
                         this.update(cx, |_, cx| {
-                            cx.emit(Event::UpdateLocation);
                             cx.notify();
                         })
                         .ok();
@@ -111,19 +102,6 @@ impl ToolbarItemView for Breadcrumbs {
         }
     }
 
-    // fn location_for_event(
-    //     &self,
-    //     _: &Event,
-    //     current_location: ToolbarItemLocation,
-    //     cx: &AppContext,
-    // ) -> ToolbarItemLocation {
-    //     if let Some(active_item) = self.active_item.as_ref() {
-    //         active_item.breadcrumb_location(cx)
-    //     } else {
-    //         current_location
-    //     }
-    // }
-
     fn pane_focus_update(&mut self, pane_focused: bool, _: &mut ViewContext<Self>) {
         self.pane_focused = pane_focused;
     }

crates/file_finder2/src/file_finder.rs 🔗

@@ -546,7 +546,7 @@ impl PickerDelegate for FileFinderDelegate {
 
     fn separators_after_indices(&self) -> Vec<usize> {
         let history_items = self.matches.history.len();
-        if history_items == 0 {
+        if history_items == 0 || self.matches.search.is_empty() {
             Vec::new()
         } else {
             vec![history_items - 1]

crates/project2/src/terminals.rs 🔗

@@ -37,7 +37,6 @@ impl Project {
                 Some(settings.blinking.clone()),
                 settings.alternate_scroll,
                 window,
-                |_, _| todo!("color_for_index"),
             )
             .map(|builder| {
                 let terminal_handle = cx.build_model(|cx| builder.subscribe(cx));

crates/project2/src/worktree.rs 🔗

@@ -2184,7 +2184,6 @@ impl LocalSnapshot {
         ignore_stack
     }
 
-    #[allow(dead_code)] // todo!("remove this when we use it")
     #[cfg(test)]
     pub(crate) fn expanded_entries(&self) -> impl Iterator<Item = &Entry> {
         self.entries_by_path

crates/terminal2/src/terminal2.rs 🔗

@@ -35,6 +35,7 @@ use procinfo::LocalProcessInfo;
 use serde::{Deserialize, Serialize};
 use settings::Settings;
 use terminal_settings::{AlternateScroll, Shell, TerminalBlink, TerminalSettings};
+use theme::{ActiveTheme, Theme};
 use util::truncate_and_trailoff;
 
 use std::{
@@ -50,9 +51,9 @@ use std::{
 use thiserror::Error;
 
 use gpui::{
-    actions, px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
-    ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
-    Point, ScrollWheelEvent, Size, Task, TouchPhase,
+    actions, black, px, red, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter,
+    Hsla, Keystroke, ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent,
+    MouseUpEvent, Pixels, Point, Rgba, ScrollWheelEvent, Size, Task, TouchPhase,
 };
 
 use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
@@ -299,7 +300,6 @@ impl TerminalBuilder {
         blink_settings: Option<TerminalBlink>,
         alternate_scroll: AlternateScroll,
         window: AnyWindowHandle,
-        color_for_index: impl Fn(usize, &mut AppContext) -> Hsla + Send + Sync + 'static,
     ) -> Result<TerminalBuilder> {
         let pty_config = {
             let alac_shell = match shell.clone() {
@@ -405,7 +405,6 @@ impl TerminalBuilder {
             selection_phase: SelectionPhase::Ended,
             cmd_pressed: false,
             hovered_word: false,
-            color_for_index: Box::new(color_for_index),
         };
 
         Ok(TerminalBuilder {
@@ -562,8 +561,6 @@ pub struct Terminal {
     selection_phase: SelectionPhase,
     cmd_pressed: bool,
     hovered_word: bool,
-    // An implementation of the 8 bit ANSI color palette
-    color_for_index: Box<dyn Fn(usize, &mut AppContext) -> Hsla + Send + Sync + 'static>,
 }
 
 impl Terminal {
@@ -646,8 +643,9 @@ impl Terminal {
     ) {
         match event {
             InternalEvent::ColorRequest(index, format) => {
-                let color = term.colors()[*index]
-                    .unwrap_or_else(|| to_alac_rgb((self.color_for_index)(*index, cx)));
+                let color = term.colors()[*index].unwrap_or_else(|| {
+                    to_alac_rgb(get_color_at_index(*index, cx.theme().as_ref()))
+                });
                 self.write_to_pty(format(color))
             }
             InternalEvent::Resize(mut new_size) => {
@@ -1418,6 +1416,90 @@ fn content_index_for_mouse(pos: Point<Pixels>, size: &TerminalSize) -> usize {
     clamped_row * size.columns() + clamped_col
 }
 
+///Converts an 8 bit ANSI color to it's GPUI equivalent.
+///Accepts usize for compatibility with the alacritty::Colors interface,
+///Other than that use case, should only be called with values in the [0,255] range
+pub fn get_color_at_index(index: usize, theme: &Theme) -> Hsla {
+    let colors = theme.colors();
+
+    match index {
+        //0-15 are the same as the named colors above
+        0 => colors.terminal_ansi_black,
+        1 => colors.terminal_ansi_red,
+        2 => colors.terminal_ansi_green,
+        3 => colors.terminal_ansi_yellow,
+        4 => colors.terminal_ansi_blue,
+        5 => colors.terminal_ansi_magenta,
+        6 => colors.terminal_ansi_cyan,
+        7 => colors.terminal_ansi_white,
+        8 => colors.terminal_ansi_bright_black,
+        9 => colors.terminal_ansi_bright_red,
+        10 => colors.terminal_ansi_bright_green,
+        11 => colors.terminal_ansi_bright_yellow,
+        12 => colors.terminal_ansi_bright_blue,
+        13 => colors.terminal_ansi_bright_magenta,
+        14 => colors.terminal_ansi_bright_cyan,
+        15 => colors.terminal_ansi_bright_white,
+        //16-231 are mapped to their RGB colors on a 0-5 range per channel
+        16..=231 => {
+            let (r, g, b) = rgb_for_index(&(index as u8)); //Split the index into it's ANSI-RGB components
+            let step = (u8::MAX as f32 / 5.).floor() as u8; //Split the RGB range into 5 chunks, with floor so no overflow
+            rgba_color(r * step, g * step, b * step) //Map the ANSI-RGB components to an RGB color
+        }
+        //232-255 are a 24 step grayscale from black to white
+        232..=255 => {
+            let i = index as u8 - 232; //Align index to 0..24
+            let step = (u8::MAX as f32 / 24.).floor() as u8; //Split the RGB grayscale values into 24 chunks
+            rgba_color(i * step, i * step, i * step) //Map the ANSI-grayscale components to the RGB-grayscale
+        }
+        //For compatibility with the alacritty::Colors interface
+        256 => colors.text,
+        257 => colors.background,
+        258 => theme.players().local().cursor,
+
+        // todo!(more colors)
+        259 => red(),                      //style.dim_black,
+        260 => red(),                      //style.dim_red,
+        261 => red(),                      //style.dim_green,
+        262 => red(),                      //style.dim_yellow,
+        263 => red(),                      //style.dim_blue,
+        264 => red(),                      //style.dim_magenta,
+        265 => red(),                      //style.dim_cyan,
+        266 => red(),                      //style.dim_white,
+        267 => red(),                      //style.bright_foreground,
+        268 => colors.terminal_ansi_black, //'Dim Background', non-standard color
+
+        _ => black(),
+    }
+}
+
+///Generates the rgb channels in [0, 5] for a given index into the 6x6x6 ANSI color cube
+///See: [8 bit ansi color](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit).
+///
+///Wikipedia gives a formula for calculating the index for a given color:
+///
+///index = 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
+///
+///This function does the reverse, calculating the r, g, and b components from a given index.
+fn rgb_for_index(i: &u8) -> (u8, u8, u8) {
+    debug_assert!((&16..=&231).contains(&i));
+    let i = i - 16;
+    let r = (i - (i % 36)) / 36;
+    let g = ((i % 36) - (i % 6)) / 6;
+    let b = (i % 36) % 6;
+    (r, g, b)
+}
+
+pub fn rgba_color(r: u8, g: u8, b: u8) -> Hsla {
+    Rgba {
+        r: (r as f32 / 255.) as f32,
+        g: (g as f32 / 255.) as f32,
+        b: (b as f32 / 255.) as f32,
+        a: 1.,
+    }
+    .into()
+}
+
 #[cfg(test)]
 mod tests {
     use alacritty_terminal::{
@@ -1427,7 +1509,18 @@ mod tests {
     use gpui::{point, size, Pixels};
     use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng, Rng};
 
-    use crate::{content_index_for_mouse, IndexedCell, TerminalContent, TerminalSize};
+    use crate::{
+        content_index_for_mouse, rgb_for_index, IndexedCell, TerminalContent, TerminalSize,
+    };
+
+    #[test]
+    fn test_rgb_for_index() {
+        //Test every possible value in the color cube
+        for i in 16..=231 {
+            let (r, g, b) = rgb_for_index(&(i as u8));
+            assert_eq!(i, 16 + 36 * r + 6 * g + b);
+        }
+    }
 
     #[test]
     fn test_mouse_to_cell_test() {

crates/terminal_view2/src/terminal_element.rs 🔗

@@ -1,12 +1,11 @@
 use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
 use gpui::{
-    black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace,
+    div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace,
     BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font,
     FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
     Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton,
-    Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement,
-    StyleRefinement, Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace,
-    WindowContext,
+    Pixels, PlatformInputHandler, Point, ShapedLine, StatefulInteractiveElement, StyleRefinement,
+    Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext,
 };
 use itertools::Itertools;
 use language::CursorShape;
@@ -1048,108 +1047,12 @@ fn convert_color(fg: &terminal::alacritty_terminal::ansi::Color, theme: &Theme)
             NamedColor::DimForeground => red(),
         },
         //'True' colors
-        terminal::alacritty_terminal::ansi::Color::Spec(rgb) => rgba_color(rgb.r, rgb.g, rgb.b),
+        terminal::alacritty_terminal::ansi::Color::Spec(rgb) => {
+            terminal::rgba_color(rgb.r, rgb.g, rgb.b)
+        }
         //8 bit, indexed colors
         terminal::alacritty_terminal::ansi::Color::Indexed(i) => {
-            get_color_at_index(&(*i as usize), theme)
-        }
-    }
-}
-
-///Converts an 8 bit ANSI color to it's GPUI equivalent.
-///Accepts usize for compatibility with the alacritty::Colors interface,
-///Other than that use case, should only be called with values in the [0,255] range
-pub fn get_color_at_index(index: &usize, theme: &Theme) -> Hsla {
-    let colors = theme.colors();
-
-    match index {
-        //0-15 are the same as the named colors above
-        0 => colors.terminal_ansi_black,
-        1 => colors.terminal_ansi_red,
-        2 => colors.terminal_ansi_green,
-        3 => colors.terminal_ansi_yellow,
-        4 => colors.terminal_ansi_blue,
-        5 => colors.terminal_ansi_magenta,
-        6 => colors.terminal_ansi_cyan,
-        7 => colors.terminal_ansi_white,
-        8 => colors.terminal_ansi_bright_black,
-        9 => colors.terminal_ansi_bright_red,
-        10 => colors.terminal_ansi_bright_green,
-        11 => colors.terminal_ansi_bright_yellow,
-        12 => colors.terminal_ansi_bright_blue,
-        13 => colors.terminal_ansi_bright_magenta,
-        14 => colors.terminal_ansi_bright_cyan,
-        15 => colors.terminal_ansi_bright_white,
-        //16-231 are mapped to their RGB colors on a 0-5 range per channel
-        16..=231 => {
-            let (r, g, b) = rgb_for_index(&(*index as u8)); //Split the index into it's ANSI-RGB components
-            let step = (u8::MAX as f32 / 5.).floor() as u8; //Split the RGB range into 5 chunks, with floor so no overflow
-            rgba_color(r * step, g * step, b * step) //Map the ANSI-RGB components to an RGB color
-        }
-        //232-255 are a 24 step grayscale from black to white
-        232..=255 => {
-            let i = *index as u8 - 232; //Align index to 0..24
-            let step = (u8::MAX as f32 / 24.).floor() as u8; //Split the RGB grayscale values into 24 chunks
-            rgba_color(i * step, i * step, i * step) //Map the ANSI-grayscale components to the RGB-grayscale
-        }
-        //For compatibility with the alacritty::Colors interface
-        256 => colors.text,
-        257 => colors.background,
-        258 => theme.players().local().cursor,
-
-        // todo!(more colors)
-        259 => red(),                      //style.dim_black,
-        260 => red(),                      //style.dim_red,
-        261 => red(),                      //style.dim_green,
-        262 => red(),                      //style.dim_yellow,
-        263 => red(),                      //style.dim_blue,
-        264 => red(),                      //style.dim_magenta,
-        265 => red(),                      //style.dim_cyan,
-        266 => red(),                      //style.dim_white,
-        267 => red(),                      //style.bright_foreground,
-        268 => colors.terminal_ansi_black, //'Dim Background', non-standard color
-
-        _ => black(),
-    }
-}
-
-///Generates the rgb channels in [0, 5] for a given index into the 6x6x6 ANSI color cube
-///See: [8 bit ansi color](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit).
-///
-///Wikipedia gives a formula for calculating the index for a given color:
-///
-///index = 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
-///
-///This function does the reverse, calculating the r, g, and b components from a given index.
-fn rgb_for_index(i: &u8) -> (u8, u8, u8) {
-    debug_assert!((&16..=&231).contains(&i));
-    let i = i - 16;
-    let r = (i - (i % 36)) / 36;
-    let g = ((i % 36) - (i % 6)) / 6;
-    let b = (i % 36) % 6;
-    (r, g, b)
-}
-
-fn rgba_color(r: u8, g: u8, b: u8) -> Hsla {
-    Rgba {
-        r: (r as f32 / 255.) as f32,
-        g: (g as f32 / 255.) as f32,
-        b: (b as f32 / 255.) as f32,
-        a: 1.,
-    }
-    .into()
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::terminal_element::rgb_for_index;
-
-    #[test]
-    fn test_rgb_for_index() {
-        //Test every possible value in the color cube
-        for i in 16..=231 {
-            let (r, g, b) = rgb_for_index(&(i as u8));
-            assert_eq!(i, 16 + 36 * r + 6 * g + b);
+            terminal::get_color_at_index(*i as usize, theme)
         }
     }
 }