Add zed://extension/{id} links (#34492)
Release Notes: - Add zed://extension/{id} links to open the extensions UI with a specific extension
This commit is contained in:
parent
ec52e9281a
commit
3751737621
9 changed files with 72 additions and 10 deletions
|
@ -6,6 +6,7 @@ use std::sync::OnceLock;
|
|||
use std::time::Duration;
|
||||
use std::{ops::Range, sync::Arc};
|
||||
|
||||
use anyhow::Context as _;
|
||||
use client::{ExtensionMetadata, ExtensionProvides};
|
||||
use collections::{BTreeMap, BTreeSet};
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
|
@ -80,16 +81,24 @@ pub fn init(cx: &mut App) {
|
|||
.find_map(|item| item.downcast::<ExtensionsPage>());
|
||||
|
||||
if let Some(existing) = existing {
|
||||
if provides_filter.is_some() {
|
||||
existing.update(cx, |extensions_page, cx| {
|
||||
existing.update(cx, |extensions_page, cx| {
|
||||
if provides_filter.is_some() {
|
||||
extensions_page.change_provides_filter(provides_filter, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
if let Some(id) = action.id.as_ref() {
|
||||
extensions_page.focus_extension(id, window, cx);
|
||||
}
|
||||
});
|
||||
|
||||
workspace.activate_item(&existing, true, true, window, cx);
|
||||
} else {
|
||||
let extensions_page =
|
||||
ExtensionsPage::new(workspace, provides_filter, window, cx);
|
||||
let extensions_page = ExtensionsPage::new(
|
||||
workspace,
|
||||
provides_filter,
|
||||
action.id.as_deref(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
workspace.add_item_to_active_pane(
|
||||
Box::new(extensions_page),
|
||||
None,
|
||||
|
@ -287,6 +296,7 @@ impl ExtensionsPage {
|
|||
pub fn new(
|
||||
workspace: &Workspace,
|
||||
provides_filter: Option<ExtensionProvides>,
|
||||
focus_extension_id: Option<&str>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) -> Entity<Self> {
|
||||
|
@ -317,6 +327,9 @@ impl ExtensionsPage {
|
|||
let query_editor = cx.new(|cx| {
|
||||
let mut input = Editor::single_line(window, cx);
|
||||
input.set_placeholder_text("Search extensions...", cx);
|
||||
if let Some(id) = focus_extension_id {
|
||||
input.set_text(format!("id:{id}"), window, cx);
|
||||
}
|
||||
input
|
||||
});
|
||||
cx.subscribe(&query_editor, Self::on_query_change).detach();
|
||||
|
@ -340,7 +353,7 @@ impl ExtensionsPage {
|
|||
scrollbar_state: ScrollbarState::new(scroll_handle),
|
||||
};
|
||||
this.fetch_extensions(
|
||||
None,
|
||||
this.search_query(cx),
|
||||
Some(BTreeSet::from_iter(this.provides_filter)),
|
||||
None,
|
||||
cx,
|
||||
|
@ -464,9 +477,23 @@ impl ExtensionsPage {
|
|||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let remote_extensions = extension_store.update(cx, |store, cx| {
|
||||
store.fetch_extensions(search.as_deref(), provides_filter.as_ref(), cx)
|
||||
});
|
||||
let remote_extensions =
|
||||
if let Some(id) = search.as_ref().and_then(|s| s.strip_prefix("id:")) {
|
||||
let versions =
|
||||
extension_store.update(cx, |store, cx| store.fetch_extension_versions(id, cx));
|
||||
cx.foreground_executor().spawn(async move {
|
||||
let versions = versions.await?;
|
||||
let latest = versions
|
||||
.into_iter()
|
||||
.max_by_key(|v| v.published_at)
|
||||
.context("no extension found")?;
|
||||
Ok(vec![latest])
|
||||
})
|
||||
} else {
|
||||
extension_store.update(cx, |store, cx| {
|
||||
store.fetch_extensions(search.as_deref(), provides_filter.as_ref(), cx)
|
||||
})
|
||||
};
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
let dev_extensions = if let Some(search) = search {
|
||||
|
@ -1165,6 +1192,13 @@ impl ExtensionsPage {
|
|||
self.refresh_feature_upsells(cx);
|
||||
}
|
||||
|
||||
pub fn focus_extension(&mut self, id: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.query_editor.update(cx, |editor, cx| {
|
||||
editor.set_text(format!("id:{id}"), window, cx)
|
||||
});
|
||||
self.refresh_search(cx);
|
||||
}
|
||||
|
||||
pub fn change_provides_filter(
|
||||
&mut self,
|
||||
provides_filter: Option<ExtensionProvides>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue