diff --git a/Cargo.lock b/Cargo.lock index 8eb98330d7..4ee96c3319 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18593,6 +18593,7 @@ dependencies = [ "languages", "libc", "log", + "markdown", "markdown_preview", "menu", "migrator", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 9d7f6e7a22..062c4173b6 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -78,6 +78,7 @@ languages = { workspace = true, features = ["load-grammars"] } libc.workspace = true log.workspace = true markdown_preview.workspace = true +markdown.workspace = true menu.workspace = true migrator.workspace = true mimalloc = { version = "0.1", optional = true } diff --git a/crates/zed/src/zed/migrate.rs b/crates/zed/src/zed/migrate.rs index 50c94fcc43..118b71c89f 100644 --- a/crates/zed/src/zed/migrate.rs +++ b/crates/zed/src/zed/migrate.rs @@ -2,12 +2,14 @@ use anyhow::{Context as _, Result}; use editor::Editor; use fs::Fs; use migrator::{migrate_keymap, migrate_settings}; -use settings::{KeymapFile, SettingsStore}; +use settings::{KeymapFile, Settings, SettingsStore}; use util::ResultExt; use std::sync::Arc; -use gpui::{Entity, EventEmitter, Global, Task}; +use gpui::{Entity, EventEmitter, Global, Task, TextStyle, TextStyleRefinement}; +use markdown::{Markdown, MarkdownElement, MarkdownStyle}; +use theme::ThemeSettings; use ui::prelude::*; use workspace::item::ItemHandle; use workspace::{ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace}; @@ -21,6 +23,7 @@ pub enum MigrationType { pub struct MigrationBanner { migration_type: Option, should_migrate_task: Option>, + markdown: Option>, } pub enum MigrationEvent { @@ -63,22 +66,7 @@ impl MigrationBanner { Self { migration_type: None, should_migrate_task: None, - } - } - - fn backup_file_name(&self) -> String { - match self.migration_type { - Some(MigrationType::Keymap) => paths::keymap_backup_file() - .file_name() - .unwrap_or_default() - .to_string_lossy() - .into_owned(), - Some(MigrationType::Settings) => paths::settings_backup_file() - .file_name() - .unwrap_or_default() - .to_string_lossy() - .into_owned(), - None => String::new(), + markdown: None, } } @@ -100,6 +88,48 @@ impl MigrationBanner { } } } + + fn show(&mut self, cx: &mut Context) { + let (file_type, backup_file_name) = match self.migration_type { + Some(MigrationType::Keymap) => ( + "keymap", + paths::keymap_backup_file() + .file_name() + .unwrap_or_default() + .to_string_lossy() + .into_owned(), + ), + Some(MigrationType::Settings) => ( + "settings", + paths::settings_backup_file() + .file_name() + .unwrap_or_default() + .to_string_lossy() + .into_owned(), + ), + None => return, + }; + + let migration_text = format!( + "Your {} file uses deprecated settings which can be \ + automatically updated. A backup will be saved to `{}`", + file_type, backup_file_name + ); + + self.markdown = Some(cx.new(|cx| Markdown::new(migration_text.into(), None, None, cx))); + + cx.emit(ToolbarItemEvent::ChangeLocation( + ToolbarItemLocation::Secondary, + )); + cx.notify(); + } + + fn reset(&mut self, cx: &mut Context) { + self.should_migrate_task.take(); + self.migration_type.take(); + self.markdown.take(); + cx.notify(); + } } impl EventEmitter for MigrationBanner {} @@ -111,8 +141,8 @@ impl ToolbarItemView for MigrationBanner { window: &mut Window, cx: &mut Context, ) -> ToolbarItemLocation { - cx.notify(); - self.should_migrate_task.take(); + self.reset(cx); + let Some(target) = active_pane_item .and_then(|item| item.act_as::(cx)) .and_then(|editor| editor.update(cx, |editor, cx| editor.target_file_abs_path(cx))) @@ -126,11 +156,8 @@ impl ToolbarItemView for MigrationBanner { let should_migrate = should_migrate_keymap(fs); self.should_migrate_task = Some(cx.spawn_in(window, async move |this, cx| { if let Ok(true) = should_migrate.await { - this.update(cx, |_, cx| { - cx.emit(ToolbarItemEvent::ChangeLocation( - ToolbarItemLocation::Secondary, - )); - cx.notify(); + this.update(cx, |this, cx| { + this.show(cx); }) .log_err(); } @@ -141,11 +168,8 @@ impl ToolbarItemView for MigrationBanner { let should_migrate = should_migrate_settings(fs); self.should_migrate_task = Some(cx.spawn_in(window, async move |this, cx| { if let Ok(true) = should_migrate.await { - this.update(cx, |_, cx| { - cx.emit(ToolbarItemEvent::ChangeLocation( - ToolbarItemLocation::Secondary, - )); - cx.notify(); + this.update(cx, |this, cx| { + this.show(cx); }) .log_err(); } @@ -159,54 +183,54 @@ impl ToolbarItemView for MigrationBanner { impl Render for MigrationBanner { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let migration_type = self.migration_type; - let file_type = match migration_type { - Some(MigrationType::Keymap) => "keymap", - Some(MigrationType::Settings) => "settings", - None => "", - }; - let backup_file_name = self.backup_file_name(); - + let settings = ThemeSettings::get_global(cx); + let ui_font_family = settings.ui_font.family.clone(); + let line_height = settings.ui_font_size(cx) * 1.3; h_flex() .py_1() .pl_2() .pr_1() - .flex_wrap() .justify_between() .bg(cx.theme().status().info_background.opacity(0.6)) .border_1() .border_color(cx.theme().colors().border_variant) .rounded_sm() - .overflow_hidden() .child( h_flex() .gap_2() + .overflow_hidden() .child( Icon::new(IconName::Warning) .size(IconSize::XSmall) .color(Color::Warning), ) .child( - h_flex() - .gap_0p5() - .child( - Label::new(format!( - "Your {} file uses deprecated settings which can be \ - automatically updated. A backup will be saved to", - file_type - )) - .color(Color::Default), - ) - .child( - div() - .px_1() - .bg(cx.theme().colors().background) - .rounded_xs() - .child( - Label::new(backup_file_name) - .buffer_font(cx) - .size(LabelSize::Small), - ), - ), + div() + .overflow_hidden() + .text_size(TextSize::Default.rems(cx)) + .max_h(2 * line_height) + .when_some(self.markdown.as_ref(), |this, markdown| { + this.child( + MarkdownElement::new( + markdown.clone(), + MarkdownStyle { + base_text_style: TextStyle { + color: cx.theme().colors().text, + font_family: ui_font_family, + ..Default::default() + }, + inline_code: TextStyleRefinement { + background_color: Some( + cx.theme().colors().background, + ), + ..Default::default() + }, + ..Default::default() + }, + ) + .into_any_element(), + ) + }), ), ) .child(