From e88156645dcb34b88932220c70dfcbe2c90271d8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Apr 2022 16:48:33 -0700 Subject: [PATCH] Update the styling of the lsp status indicator --- assets/icons/download-solid-14.svg | 3 + assets/themes/cave-dark.json | 39 +++++++-- assets/themes/cave-light.json | 39 +++++++-- assets/themes/dark.json | 39 +++++++-- assets/themes/light.json | 39 +++++++-- assets/themes/solarized-dark.json | 39 +++++++-- assets/themes/solarized-light.json | 39 +++++++-- assets/themes/sulphurpool-dark.json | 39 +++++++-- assets/themes/sulphurpool-light.json | 39 +++++++-- crates/theme/src/theme.rs | 17 +++- crates/workspace/src/lsp_status.rs | 114 ++++++++++++++++++--------- styles/src/styleTree/workspace.ts | 22 +++++- 12 files changed, 369 insertions(+), 99 deletions(-) create mode 100644 assets/icons/download-solid-14.svg diff --git a/assets/icons/download-solid-14.svg b/assets/icons/download-solid-14.svg new file mode 100644 index 0000000000..e2e1cf5d02 --- /dev/null +++ b/assets/icons/download-solid-14.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json index c64adb53d8..428768f8bf 100644 --- a/assets/themes/cave-dark.json +++ b/assets/themes/cave-dark.json @@ -194,11 +194,6 @@ "color": "#8b8792", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#8b8792", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#8b8792", @@ -209,6 +204,36 @@ "color": "#8b8792", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14 + }, + "icon_color": "#8b8792", + "icon_color_hover": "#e2dfe7", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#58526052" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#a06e3b", "icon_color_error": "#be4678", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/cave-light.json b/assets/themes/cave-light.json index 8d7a8b4d17..1b956493e6 100644 --- a/assets/themes/cave-light.json +++ b/assets/themes/cave-light.json @@ -194,11 +194,6 @@ "color": "#585260", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#585260", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#585260", @@ -209,6 +204,36 @@ "color": "#585260", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14 + }, + "icon_color": "#585260", + "icon_color_hover": "#26232a", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#8b87921f" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#a06e3b", "icon_color_error": "#be4678", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/dark.json b/assets/themes/dark.json index aac1da9a3a..0fee98d5bb 100644 --- a/assets/themes/dark.json +++ b/assets/themes/dark.json @@ -194,11 +194,6 @@ "color": "#808080", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#808080", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#808080", @@ -209,6 +204,36 @@ "color": "#808080", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#808080", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#f1f1f1", + "size": 14 + }, + "icon_color": "#555555", + "icon_color_hover": "#c6c6c6", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#232323" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#f6a724", "icon_color_error": "#eb2d2d", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/light.json b/assets/themes/light.json index 858ad25400..70710b0303 100644 --- a/assets/themes/light.json +++ b/assets/themes/light.json @@ -194,11 +194,6 @@ "color": "#636363", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#636363", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#636363", @@ -209,6 +204,36 @@ "color": "#636363", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#636363", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#2b2b2b", + "size": 14 + }, + "icon_color": "#9c9c9c", + "icon_color_hover": "#393939", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#eaeaea" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#f7bf17", "icon_color_error": "#c91818", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/solarized-dark.json b/assets/themes/solarized-dark.json index a6320433df..5cdc89efb7 100644 --- a/assets/themes/solarized-dark.json +++ b/assets/themes/solarized-dark.json @@ -194,11 +194,6 @@ "color": "#93a1a1", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#93a1a1", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#93a1a1", @@ -209,6 +204,36 @@ "color": "#93a1a1", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14 + }, + "icon_color": "#93a1a1", + "icon_color_hover": "#eee8d5", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#586e7552" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#b58900", "icon_color_error": "#dc322f", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/solarized-light.json b/assets/themes/solarized-light.json index 14a465d253..4e4e32aaf0 100644 --- a/assets/themes/solarized-light.json +++ b/assets/themes/solarized-light.json @@ -194,11 +194,6 @@ "color": "#586e75", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#586e75", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#586e75", @@ -209,6 +204,36 @@ "color": "#586e75", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#073642", + "size": 14 + }, + "icon_color": "#586e75", + "icon_color_hover": "#073642", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#93a1a11f" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#b58900", "icon_color_error": "#dc322f", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/sulphurpool-dark.json b/assets/themes/sulphurpool-dark.json index 421c5bbe29..18d1a73293 100644 --- a/assets/themes/sulphurpool-dark.json +++ b/assets/themes/sulphurpool-dark.json @@ -194,11 +194,6 @@ "color": "#979db4", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#979db4", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#979db4", @@ -209,6 +204,36 @@ "color": "#979db4", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14 + }, + "icon_color": "#979db4", + "icon_color_hover": "#dfe2f1", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#5e668752" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#c08b30", "icon_color_error": "#c94922", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/assets/themes/sulphurpool-light.json b/assets/themes/sulphurpool-light.json index 0529f1787d..08df8d7af6 100644 --- a/assets/themes/sulphurpool-light.json +++ b/assets/themes/sulphurpool-light.json @@ -194,11 +194,6 @@ "color": "#5e6687", "size": 14 }, - "lsp_message": { - "family": "Zed Sans", - "color": "#5e6687", - "size": 14 - }, "auto_update_progress_message": { "family": "Zed Sans", "color": "#5e6687", @@ -209,6 +204,36 @@ "color": "#5e6687", "size": 14 }, + "lsp_status": { + "icon_spacing": 4, + "icon_width": 14, + "height": 18, + "message": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "message_hover": { + "family": "Zed Sans", + "color": "#293256", + "size": 14 + }, + "icon_color": "#5e6687", + "icon_color_hover": "#293256", + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "container_hover": { + "corner_radius": 6, + "padding": { + "left": 6, + "right": 6 + }, + "background": "#979db41f" + } + }, "diagnostics": { "height": 16, "summary_ok": { @@ -300,8 +325,8 @@ "icon_color_warning": "#c08b30", "icon_color_error": "#c94922", "icon_width": 14, - "icon_spacing": 4, - "summary_spacing": 8 + "icon_spacing": 2, + "summary_spacing": 6 }, "sidebar_buttons": { "group_left": {}, diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 63774824e4..059e6eb51b 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -143,10 +143,9 @@ pub struct StatusBar { pub height: f32, pub item_spacing: f32, pub cursor_position: TextStyle, - pub diagnostic_message: TextStyle, - pub lsp_message: TextStyle, pub auto_update_progress_message: TextStyle, pub auto_update_done_message: TextStyle, + pub lsp_status: StatusBarLspStatus, pub sidebar_buttons: StatusBarSidebarButtons, pub diagnostics: StatusBarDiagnostics, } @@ -178,6 +177,20 @@ pub struct StatusBarDiagnostics { pub summary_spacing: f32, } +#[derive(Deserialize, Default)] +pub struct StatusBarLspStatus { + #[serde(flatten)] + pub container: ContainerStyle, + pub height: f32, + pub container_hover: ContainerStyle, + pub icon_spacing: f32, + pub icon_color: Color, + pub icon_color_hover: Color, + pub icon_width: f32, + pub message: TextStyle, + pub message_hover: TextStyle, +} + #[derive(Deserialize, Default)] pub struct Sidebar { pub resize_handle: ContainerStyle, diff --git a/crates/workspace/src/lsp_status.rs b/crates/workspace/src/lsp_status.rs index 1accbcad3c..7a6b8f070d 100644 --- a/crates/workspace/src/lsp_status.rs +++ b/crates/workspace/src/lsp_status.rs @@ -1,6 +1,6 @@ use crate::{ItemHandle, StatusItemView}; use futures::StreamExt; -use gpui::{actions, AppContext}; +use gpui::{actions, AppContext, EventContext}; use gpui::{ elements::*, platform::CursorStyle, Entity, ModelHandle, MutableAppContext, RenderContext, View, ViewContext, @@ -117,11 +117,13 @@ impl View for LspStatus { } fn render(&mut self, cx: &mut RenderContext) -> ElementBox { - let theme = &cx.global::().theme; + let mut message; + let mut icon = None; + let mut handler = None; let mut pending_work = self.pending_language_server_work(cx); if let Some((lang_server_name, progress_token, progress)) = pending_work.next() { - let mut message = lang_server_name.to_string(); + message = lang_server_name.to_string(); message.push_str(": "); if let Some(progress_message) = progress.message.as_ref() { @@ -138,21 +140,19 @@ impl View for LspStatus { if additional_work_count > 0 { write!(&mut message, " + {} more", additional_work_count).unwrap(); } + } else { + drop(pending_work); - Label::new(message, theme.workspace.status_bar.lsp_message.clone()).boxed() - } else if !self.downloading.is_empty() { - Label::new( - format!( + if !self.downloading.is_empty() { + icon = Some("icons/download-solid-14.svg"); + message = format!( "Downloading {} language server{}...", self.downloading.join(", "), if self.downloading.len() > 1 { "s" } else { "" } - ), - theme.workspace.status_bar.lsp_message.clone(), - ) - .boxed() - } else if !self.checking_for_update.is_empty() { - Label::new( - format!( + ); + } else if !self.checking_for_update.is_empty() { + icon = Some("icons/download-solid-14.svg"); + message = format!( "Checking for updates to {} language server{}...", self.checking_for_update.join(", "), if self.checking_for_update.len() > 1 { @@ -160,30 +160,70 @@ impl View for LspStatus { } else { "" } - ), - theme.workspace.status_bar.lsp_message.clone(), - ) - .boxed() - } else if !self.failed.is_empty() { - drop(pending_work); - MouseEventHandler::new::(0, cx, |_, cx| { - let theme = &cx.global::().theme; - Label::new( - format!( - "Failed to download {} language server{}. Click to dismiss.", - self.failed.join(", "), - if self.failed.len() > 1 { "s" } else { "" } - ), - theme.workspace.status_bar.lsp_message.clone(), - ) - .boxed() - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(|cx| cx.dispatch_action(DismissErrorMessage)) - .boxed() - } else { - Empty::new().boxed() + ); + } else if !self.failed.is_empty() { + icon = Some("icons/warning-solid-14.svg"); + message = format!( + "Failed to download {} language server{}. Click to dismiss.", + self.failed.join(", "), + if self.failed.len() > 1 { "s" } else { "" } + ); + handler = Some(|cx: &mut EventContext| cx.dispatch_action(DismissErrorMessage)); + } else { + return Empty::new().boxed(); + } } + + let mut element = MouseEventHandler::new::(0, cx, |state, cx| { + let hovered = state.hovered && handler.is_some(); + let theme = &cx.global::().theme; + let style = &theme.workspace.status_bar.lsp_status; + Flex::row() + .with_children(icon.map(|path| { + Svg::new(path) + .with_color(if hovered { + style.icon_color_hover + } else { + style.icon_color + }) + .constrained() + .with_width(style.icon_width) + .contained() + .with_margin_right(style.icon_spacing) + .aligned() + .named("warning-icon") + })) + .with_child( + Label::new( + message, + if hovered { + style.message_hover.clone() + } else { + style.message.clone() + }, + ) + .aligned() + .boxed(), + ) + .constrained() + .with_height(style.height) + .contained() + .with_style(if hovered { + style.container_hover + } else { + style.container + }) + .aligned() + .boxed() + }); + + if let Some(handler) = handler { + element = element + .with_cursor_style(CursorStyle::PointingHand) + .on_click(handler); + } + + element.boxed() } } diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts index b82e140e35..1d80f32349 100644 --- a/styles/src/styleTree/workspace.ts +++ b/styles/src/styleTree/workspace.ts @@ -1,5 +1,4 @@ import Theme from "../themes/theme"; -import { color } from "../tokens"; import { backgroundColor, border, iconColor, text } from "./components"; export default function workspace(theme: Theme) { @@ -97,9 +96,24 @@ export default function workspace(theme: Theme) { border: border(theme, "primary", { top: true, overlay: true }), cursorPosition: text(theme, "sans", "muted"), diagnosticMessage: text(theme, "sans", "muted"), - lspMessage: text(theme, "sans", "muted"), autoUpdateProgressMessage: text(theme, "sans", "muted"), autoUpdateDoneMessage: text(theme, "sans", "muted"), + lspStatus: { + iconSpacing: 4, + iconWidth: 14, + height: 18, + message: text(theme, "sans", "muted"), + messageHover: text(theme, "sans", "primary"), + iconColor: iconColor(theme, "muted"), + iconColorHover: iconColor(theme, "primary"), + cornerRadius: 6, + padding: { left: 6, right: 6 }, + containerHover: { + cornerRadius: 6, + padding: { left: 6, right: 6 }, + background: backgroundColor(theme, 300, "hovered"), + } + }, diagnostics: { height: 16, summaryOk: { @@ -133,8 +147,8 @@ export default function workspace(theme: Theme) { iconColorWarning: iconColor(theme, "warning"), iconColorError: iconColor(theme, "error"), iconWidth: 14, - iconSpacing: 4, - summarySpacing: 8, + iconSpacing: 2, + summarySpacing: 6, }, sidebarButtons: { groupLeft: {},