Skip to content

Commit 4f2d170

Browse files
Fix extension search not respecting category filter
When searching extensions with a category filter (e.g., "Themes") selected, results could include extensions that don't belong to that category. This happened because `filter_extension_entries()` only filtered by install status but not by the `provides_filter` (category). The Cloud API may also bypass category filtering for exact-match extensions. Add client-side `provides_filter` checks for both remote and dev extensions in `filter_extension_entries()`. Closes #48628 Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4ed2b3d commit 4f2d170

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

crates/extensions_ui/src/extensions_ui.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ pub struct ExtensionsPage {
320320
remote_extension_entries: Vec<ExtensionMetadata>,
321321
dev_extension_entries: Vec<Arc<ExtensionManifest>>,
322322
filtered_remote_extension_indices: Vec<usize>,
323+
filtered_dev_extension_indices: Vec<usize>,
323324
query_editor: Entity<Editor>,
324325
query_contains_error: bool,
325326
provides_filter: Option<ExtensionProvides>,
@@ -381,6 +382,7 @@ impl ExtensionsPage {
381382
filter: ExtensionFilter::All,
382383
dev_extension_entries: Vec::new(),
383384
filtered_remote_extension_indices: Vec::new(),
385+
filtered_dev_extension_indices: Vec::new(),
384386
remote_extension_entries: Vec::new(),
385387
query_contains_error: false,
386388
provides_filter,
@@ -487,8 +489,25 @@ impl ExtensionsPage {
487489
matches!(status, ExtensionStatus::NotInstalled)
488490
}
489491
})
492+
.filter(|(_, extension)| match self.provides_filter {
493+
Some(provides) => extension.manifest.provides.contains(&provides),
494+
None => true,
495+
})
496+
.map(|(ix, _)| ix),
497+
);
498+
499+
self.filtered_dev_extension_indices.clear();
500+
self.filtered_dev_extension_indices.extend(
501+
self.dev_extension_entries
502+
.iter()
503+
.enumerate()
504+
.filter(|(_, manifest)| match self.provides_filter {
505+
Some(provides) => dev_extension_matches_provides(manifest, provides),
506+
None => true,
507+
})
490508
.map(|(ix, _)| ix),
491509
);
510+
492511
cx.notify();
493512
}
494513

@@ -597,14 +616,15 @@ impl ExtensionsPage {
597616
cx: &mut Context<Self>,
598617
) -> Vec<ExtensionCard> {
599618
let dev_extension_entries_len = if self.filter.include_dev_extensions() {
600-
self.dev_extension_entries.len()
619+
self.filtered_dev_extension_indices.len()
601620
} else {
602621
0
603622
};
604623
range
605624
.map(|ix| {
606625
if ix < dev_extension_entries_len {
607-
let extension = &self.dev_extension_entries[ix];
626+
let dev_ix = self.filtered_dev_extension_indices[ix];
627+
let extension = &self.dev_extension_entries[dev_ix];
608628
self.render_dev_extension(extension, cx)
609629
} else {
610630
let extension_ix =
@@ -1817,7 +1837,7 @@ impl Render for ExtensionsPage {
18171837
.child(v_flex().px_4().size_full().overflow_y_hidden().map(|this| {
18181838
let mut count = self.filtered_remote_extension_indices.len();
18191839
if self.filter.include_dev_extensions() {
1820-
count += self.dev_extension_entries.len();
1840+
count += self.filtered_dev_extension_indices.len();
18211841
}
18221842

18231843
if count == 0 {
@@ -1864,3 +1884,22 @@ impl Item for ExtensionsPage {
18641884
f(*event)
18651885
}
18661886
}
1887+
1888+
fn dev_extension_matches_provides(
1889+
manifest: &ExtensionManifest,
1890+
provides: ExtensionProvides,
1891+
) -> bool {
1892+
match provides {
1893+
ExtensionProvides::Themes => !manifest.themes.is_empty(),
1894+
ExtensionProvides::IconThemes => !manifest.icon_themes.is_empty(),
1895+
ExtensionProvides::Languages => !manifest.languages.is_empty(),
1896+
ExtensionProvides::Grammars => !manifest.grammars.is_empty(),
1897+
ExtensionProvides::LanguageServers => !manifest.language_servers.is_empty(),
1898+
ExtensionProvides::ContextServers => !manifest.context_servers.is_empty(),
1899+
ExtensionProvides::AgentServers => !manifest.agent_servers.is_empty(),
1900+
ExtensionProvides::SlashCommands => !manifest.slash_commands.is_empty(),
1901+
ExtensionProvides::IndexedDocsProviders => false,
1902+
ExtensionProvides::Snippets => manifest.snippets.is_some(),
1903+
ExtensionProvides::DebugAdapters => !manifest.debug_adapters.is_empty(),
1904+
}
1905+
}

0 commit comments

Comments
 (0)