All of the important changes are in [`db.rs`](https://github.com/zed-industries/zed/pull/51809/changes#diff-2f644eab943bfa58feec29256281a3d9e8d4d7784cd34783e845af8beb15b16d). Consider reading the commit log in order to review this work. The DB crate's macro and API was changed to fix flakiness observed in the MultiWorkspace tests when run locally. This flakiness was caused by a shared `static LazyLock`, that caused concurrent test runs to interact with the same underlying in-memory database. This flakiness wasn't possible on CI due to it's usage of `cargo nextest`, whose process-per-test approach masked this problem. Essentially, I've changed the `static_connection` macro to remove the static database variable and redone the internal model. Now, all database types are thin wrappers around a generic `AppDatabase`. The `AppDatabase` collects all of the individual table's migrations via the `inventory` crate, and so only runs the migrations once on startup, rather than a dozen times on startup. The new API requires a `cx` so that we can replace the database returned at runtime, rather than relying exclusively on a process-global thread-local. However, we are still using a `static LazyLock` so that we only need to take an `&App`, instead of an `&mut App`. These databases types are `Clone + Send + Sync`, so you can easily capture-and-move the database into background tasks and other places that don't have a `cx`. For tests that require database isolation, it is now possible to set their own database in init. See [`workspace::init_test`](https://github.com/zed-industries/zed/pull/51809/changes#diff-041673bbd1947a35d45945636c0055429dfc8b5985faf93f8a8a960c9ad31e28R13610), for the flakiness fix. Best part, this change should be entirely compiler driven, so the Zed agent was able to make the app-wide refactor easily. Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - N/A --------- Co-authored-by: Anthony Eid <hello@anthonyeid.me> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
101 lines
3.9 KiB
Rust
101 lines
3.9 KiB
Rust
use db::kvp::Dismissable;
|
|
use editor::Editor;
|
|
use gpui::{Context, EventEmitter, Subscription};
|
|
use ui::{Banner, FluentBuilder as _, prelude::*};
|
|
use workspace::{ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace};
|
|
|
|
pub struct BasedPyrightBanner {
|
|
dismissed: bool,
|
|
have_basedpyright: bool,
|
|
_subscriptions: [Subscription; 1],
|
|
}
|
|
|
|
impl Dismissable for BasedPyrightBanner {
|
|
const KEY: &str = "basedpyright-banner";
|
|
}
|
|
|
|
impl BasedPyrightBanner {
|
|
pub fn new(workspace: &Workspace, cx: &mut Context<Self>) -> Self {
|
|
let subscription = cx.subscribe(workspace.project(), |this, _, event, _| {
|
|
if let project::Event::LanguageServerAdded(_, name, _) = event
|
|
&& name == "basedpyright"
|
|
{
|
|
this.have_basedpyright = true;
|
|
}
|
|
});
|
|
let dismissed = Self::dismissed(cx);
|
|
Self {
|
|
dismissed,
|
|
have_basedpyright: false,
|
|
_subscriptions: [subscription],
|
|
}
|
|
}
|
|
|
|
fn onboarding_banner_enabled(&self) -> bool {
|
|
!self.dismissed && self.have_basedpyright
|
|
}
|
|
}
|
|
|
|
impl EventEmitter<ToolbarItemEvent> for BasedPyrightBanner {}
|
|
|
|
impl Render for BasedPyrightBanner {
|
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
|
div()
|
|
.id("basedpyright-banner")
|
|
.when(self.onboarding_banner_enabled(), |el| {
|
|
el.child(
|
|
Banner::new()
|
|
.child(
|
|
v_flex()
|
|
.gap_0p5()
|
|
.child(Label::new("Basedpyright is now the only default language server for Python").mt_0p5())
|
|
.child(Label::new("We have disabled PyRight and pylsp by default. They can be re-enabled in your settings.").size(LabelSize::Small).color(Color::Muted))
|
|
)
|
|
.action_slot(
|
|
h_flex()
|
|
.gap_0p5()
|
|
.child(
|
|
Button::new("learn-more", "Learn More")
|
|
.label_size(LabelSize::Small)
|
|
.end_icon(Icon::new(IconName::ArrowUpRight).size(IconSize::XSmall).color(Color::Muted))
|
|
.on_click(|_, _, cx| {
|
|
cx.open_url("https://zed.dev/docs/languages/python")
|
|
}),
|
|
)
|
|
.child(IconButton::new("dismiss", IconName::Close).icon_size(IconSize::Small).on_click(
|
|
cx.listener(|this, _, _, cx| {
|
|
this.dismissed = true;
|
|
Self::set_dismissed(true, cx);
|
|
cx.notify();
|
|
}),
|
|
))
|
|
)
|
|
.into_any_element(),
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
impl ToolbarItemView for BasedPyrightBanner {
|
|
fn set_active_pane_item(
|
|
&mut self,
|
|
active_pane_item: Option<&dyn workspace::ItemHandle>,
|
|
_window: &mut ui::Window,
|
|
cx: &mut Context<Self>,
|
|
) -> ToolbarItemLocation {
|
|
if !self.onboarding_banner_enabled() {
|
|
return ToolbarItemLocation::Hidden;
|
|
}
|
|
if let Some(item) = active_pane_item
|
|
&& let Some(editor) = item.act_as::<Editor>(cx)
|
|
&& let Some(path) = editor.update(cx, |editor, cx| editor.target_file_abs_path(cx))
|
|
&& let Some(file_name) = path.file_name()
|
|
&& file_name.as_encoded_bytes().ends_with(".py".as_bytes())
|
|
{
|
|
return ToolbarItemLocation::Secondary;
|
|
}
|
|
|
|
ToolbarItemLocation::Hidden
|
|
}
|
|
}
|