Use categories for builtin extensions groups (#202453)

* support grouping of extensions

* remove grouping

* reuse categories parsing

* cleanup

* fix tests
This commit is contained in:
Sandeep Somavarapu 2024-01-14 22:49:29 +05:30 committed by GitHub
parent 04d168ab43
commit 1e0580ec23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 198 additions and 136 deletions

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-clojure grammars/clojure.cson ./syntaxes/clojure.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-coffee-script grammars/coffeescript.cson ./syntaxes/coffeescript.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin dotnet/csharp-tmLanguage grammars/csharp.tmLanguage ./syntaxes/csharp.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"configurationDefaults": {
"[csharp]": {

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin microsoft/vscode-css grammars/css.cson ./syntaxes/css.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,9 +8,12 @@
"engines": {
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin dart-lang/dart-syntax-highlight grammars/dart.json ./syntaxes/dart.tmLanguage.json"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin dart-lang/dart-syntax-highlight grammars/dart.json ./syntaxes/dart.tmLanguage.json"
},
"categories": [
"Programming Languages"
],
"contributes": {
"languages": [
{
@ -26,9 +29,9 @@
],
"grammars": [
{
"language": "dart",
"scopeName": "source.dart",
"path": "./syntaxes/dart.tmLanguage.json"
"language": "dart",
"scopeName": "source.dart",
"path": "./syntaxes/dart.tmLanguage.json"
}
]
}

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/diff.tmbundle Syntaxes/Diff.plist ./syntaxes/diff.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin moby/moby contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage ./syntaxes/docker.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin ionide/ionide-fsgrammar grammars/fsharp.json ./syntaxes/fsharp.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin worlpaker/go-syntax syntaxes/go.tmLanguage.json ./syntaxes/go.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/groovy.tmbundle Syntaxes/Groovy.tmLanguage ./syntaxes/groovy.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin daaain/Handlebars grammars/Handlebars.json ./syntaxes/Handlebars.tmLanguage.json"
},
"categories": ["Programming Languages"],
"extensionKind": [
"ui",
"workspace"

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin tgjones/shaders-tmLanguage grammars/hlsl.json ./syntaxes/hlsl.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammar.mjs"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -12,6 +12,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/ini.tmbundle Syntaxes/Ini.plist ./syntaxes/ini.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin redhat-developer/vscode-java language-support/java/java.tmLanguage.json ./syntaxes/java.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "0.10.x"
},
"categories": ["Programming Languages"],
"contributes": {
"configurationDefaults": {
"[javascript]": {

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin JuliaEditorSupport/atom-language-julia grammars/julia_vscode.json ./syntaxes/julia.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammar.js"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin emilast/vscode-logfile-highlighter syntaxes/log.tmLanguage ./syntaxes/log.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin sumneko/lua.tmbundle Syntaxes/Lua.plist ./syntaxes/lua.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin fadeevab/make.tmbundle Syntaxes/Makefile.plist ./syntaxes/make.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "^1.20.0"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,7 +11,8 @@
"vscode": "^1.54.0"
},
"categories": [
"Other"
"Other",
"Programming Languages"
],
"capabilities": {
"virtualWorkspaces": true,

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/perl.tmbundle Syntaxes/Perl.plist ./syntaxes/perl.tmLanguage.json Syntaxes/Perl%206.tmLanguage ./syntaxes/perl6.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "0.10.x"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin davidrios/pug-tmbundle Syntaxes/Pug.JSON-tmLanguage ./syntaxes/pug.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin REditorSupport/vscode-R syntax/r.json ./syntaxes/r.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammar.mjs"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -22,9 +22,6 @@
"bugs": {
"url": "https://github.com/Microsoft/vscode-references-view/issues"
},
"categories": [
"Programming Languages"
],
"activationEvents": [
"onCommand:references-view.find",
"onCommand:editor.action.showReferences"

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin trond-snekvik/vscode-rst syntaxes/rst.tmLanguage.json ./syntaxes/rst.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/ruby.tmbundle Syntaxes/Ruby.plist ./syntaxes/ruby.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammar.mjs"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-sass grammars/scss.cson ./syntaxes/scss.tmLanguage.json grammars/sassdoc.cson ./syntaxes/sassdoc.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -9,9 +9,6 @@
"engines": {
"vscode": "^1.39.0"
},
"categories": [
"Programming Languages"
],
"main": "./out/extension.js",
"browser": "./dist/extension.js",
"activationEvents": [

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin tgjones/shaders-tmLanguage grammars/shaderlab.json ./syntaxes/shaderlab.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin jeff-hykin/better-shell-syntax autogenerated/shell.tmLanguage.json ./syntaxes/shell-unix-bash.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammar.mjs"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin jtbandes/swift-tmlanguage Swift.tmLanguage.json ./syntaxes/swift.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -13,6 +13,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"iconThemes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Themes"],
"contributes": {
"themes": [
{

View File

@ -12,6 +12,7 @@
"scripts": {
"update-grammar": "node ./build/update-grammars.mjs"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/asp.vb.net.tmbundle Syntaxes/ASP%20VB.net.plist ./syntaxes/asp-vb-net.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -8,6 +8,7 @@
"engines": {
"vscode": "*"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -11,6 +11,7 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/yaml.tmbundle Syntaxes/YAML.tmLanguage ./syntaxes/yaml.tmLanguage.json"
},
"categories": ["Programming Languages"],
"contributes": {
"languages": [
{

View File

@ -104,7 +104,6 @@ Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane).registerEditorPane
new SyncDescriptor(ExtensionsInput)
]);
Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(
{
id: VIEWLET_ID,
@ -1127,7 +1126,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
const viewlet = await this.paneCompositeService.openPaneComposite(VIEWLET_ID, ViewContainerLocation.Sidebar, true);
const extensionsViewPaneContainer = viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer;
const currentQuery = Query.parse(extensionsViewPaneContainer.searchValue || '');
extensionsViewPaneContainer.search(new Query(currentQuery.value, id, currentQuery.groupBy).toString());
extensionsViewPaneContainer.search(new Query(currentQuery.value, id).toString());
extensionsViewPaneContainer.focus();
}
});

View File

@ -21,7 +21,7 @@ import { InstallLocalExtensionsInRemoteAction, InstallRemoteExtensionsInLocalAct
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';
import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInFeatureExtensionsView, BuiltInThemesExtensionsView, BuiltInProgrammingLanguageExtensionsView, ServerInstalledExtensionsView, DefaultRecommendedExtensionsView, UntrustedWorkspaceUnsupportedExtensionsView, UntrustedWorkspacePartiallySupportedExtensionsView, VirtualWorkspaceUnsupportedExtensionsView, VirtualWorkspacePartiallySupportedExtensionsView, DefaultPopularExtensionsView, DeprecatedExtensionsView, SearchMarketplaceExtensionsView, RecentlyUpdatedExtensionsView, OutdatedExtensionsView } from 'vs/workbench/contrib/extensions/browser/extensionsViews';
import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, ServerInstalledExtensionsView, DefaultRecommendedExtensionsView, UntrustedWorkspaceUnsupportedExtensionsView, UntrustedWorkspacePartiallySupportedExtensionsView, VirtualWorkspaceUnsupportedExtensionsView, VirtualWorkspacePartiallySupportedExtensionsView, DefaultPopularExtensionsView, DeprecatedExtensionsView, SearchMarketplaceExtensionsView, RecentlyUpdatedExtensionsView, OutdatedExtensionsView, StaticQueryExtensionsView, NONE_CATEGORY } from 'vs/workbench/contrib/extensions/browser/extensionsViews';
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import Severity from 'vs/base/common/severity';
@ -42,7 +42,7 @@ import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane';
import { Query } from 'vs/workbench/contrib/extensions/common/extensionQuery';
import { SuggestEnabledInput } from 'vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { EXTENSION_CATEGORIES, ExtensionType } from 'vs/platform/extensions/common/extensions';
import { Registry } from 'vs/platform/registry/common/platform';
import { ILabelService } from 'vs/platform/label/common/label';
import { MementoObject } from 'vs/workbench/common/memento';
@ -69,6 +69,7 @@ export const DefaultViewsContext = new RawContextKey<boolean>('defaultExtensionV
export const ExtensionsSortByContext = new RawContextKey<string>('extensionsSortByValue', '');
export const SearchMarketplaceExtensionsContext = new RawContextKey<boolean>('searchMarketplaceExtensions', false);
export const SearchHasTextContext = new RawContextKey<boolean>('extensionSearchHasText', false);
const InstalledExtensionsContext = new RawContextKey<boolean>('installedExtensions', false);
const SearchInstalledExtensionsContext = new RawContextKey<boolean>('searchInstalledExtensions', false);
const SearchRecentlyUpdatedExtensionsContext = new RawContextKey<boolean>('searchRecentlyUpdatedExtensions', false);
const SearchExtensionUpdatesContext = new RawContextKey<boolean>('searchExtensionUpdates', false);
@ -301,7 +302,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
id: 'workbench.views.extensions.searchInstalled',
name: localize2('installed', "Installed"),
ctorDescriptor: new SyncDescriptor(ExtensionsListView, [{}]),
when: ContextKeyExpr.and(ContextKeyExpr.has('searchInstalledExtensions')),
when: ContextKeyExpr.or(ContextKeyExpr.has('searchInstalledExtensions'), ContextKeyExpr.has('installedExtensions')),
});
/*
@ -394,24 +395,28 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
private createBuiltinExtensionsViewDescriptors(): IViewDescriptor[] {
const viewDescriptors: IViewDescriptor[] = [];
const configuredCategories = ['themes', 'programming languages'];
const otherCategories = EXTENSION_CATEGORIES.filter(c => !configuredCategories.includes(c.toLowerCase()));
otherCategories.push(NONE_CATEGORY);
const otherCategoriesQuery = `${otherCategories.map(c => `category:"${c}"`).join(' ')} ${configuredCategories.map(c => `category:"-${c}"`).join(' ')}`;
viewDescriptors.push({
id: 'workbench.views.extensions.builtinFeatureExtensions',
name: localize2('builtinFeatureExtensions', "Features"),
ctorDescriptor: new SyncDescriptor(BuiltInFeatureExtensionsView, [{}]),
ctorDescriptor: new SyncDescriptor(StaticQueryExtensionsView, [{ query: `@builtin ${otherCategoriesQuery}` }]),
when: ContextKeyExpr.has('builtInExtensions'),
});
viewDescriptors.push({
id: 'workbench.views.extensions.builtinThemeExtensions',
name: localize2('builtInThemesExtensions', "Themes"),
ctorDescriptor: new SyncDescriptor(BuiltInThemesExtensionsView, [{}]),
ctorDescriptor: new SyncDescriptor(StaticQueryExtensionsView, [{ query: `@builtin category:themes` }]),
when: ContextKeyExpr.has('builtInExtensions'),
});
viewDescriptors.push({
id: 'workbench.views.extensions.builtinProgrammingLanguageExtensions',
name: localize2('builtinProgrammingLanguageExtensions', "Programming Languages"),
ctorDescriptor: new SyncDescriptor(BuiltInProgrammingLanguageExtensionsView, [{}]),
ctorDescriptor: new SyncDescriptor(StaticQueryExtensionsView, [{ query: `@builtin category:"programming languages"` }]),
when: ContextKeyExpr.has('builtInExtensions'),
});
@ -474,6 +479,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
private searchMarketplaceExtensionsContextKey: IContextKey<boolean>;
private searchHasTextContextKey: IContextKey<boolean>;
private sortByUpdateDateContextKey: IContextKey<boolean>;
private installedExtensionsContextKey: IContextKey<boolean>;
private searchInstalledExtensionsContextKey: IContextKey<boolean>;
private searchRecentlyUpdatedExtensionsContextKey: IContextKey<boolean>;
private searchExtensionUpdatesContextKey: IContextKey<boolean>;
@ -521,6 +527,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
this.searchMarketplaceExtensionsContextKey = SearchMarketplaceExtensionsContext.bindTo(contextKeyService);
this.searchHasTextContextKey = SearchHasTextContext.bindTo(contextKeyService);
this.sortByUpdateDateContextKey = SortByUpdateDateContext.bindTo(contextKeyService);
this.installedExtensionsContextKey = InstalledExtensionsContext.bindTo(contextKeyService);
this.searchInstalledExtensionsContextKey = SearchInstalledExtensionsContext.bindTo(contextKeyService);
this.searchRecentlyUpdatedExtensionsContextKey = SearchRecentlyUpdatedExtensionsContext.bindTo(contextKeyService);
this.searchExtensionUpdatesContextKey = SearchExtensionUpdatesContext.bindTo(contextKeyService);
@ -713,7 +720,8 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
this.contextKeyService.bufferChangeEvents(() => {
const isRecommendedExtensionsQuery = ExtensionsListView.isRecommendedExtensionsQuery(value);
this.searchHasTextContextKey.set(value.trim() !== '');
this.searchInstalledExtensionsContextKey.set(ExtensionsListView.isInstalledExtensionsQuery(value));
this.installedExtensionsContextKey.set(ExtensionsListView.isInstalledExtensionsQuery(value));
this.searchInstalledExtensionsContextKey.set(ExtensionsListView.isSearchInstalledExtensionsQuery(value));
this.searchRecentlyUpdatedExtensionsContextKey.set(ExtensionsListView.isSearchRecentlyUpdatedQuery(value) && !ExtensionsListView.isSearchExtensionUpdatesQuery(value));
this.searchOutdatedExtensionsContextKey.set(ExtensionsListView.isOutdatedExtensionsQuery(value) && !ExtensionsListView.isSearchExtensionUpdatesQuery(value));
this.searchExtensionUpdatesContextKey.set(ExtensionsListView.isSearchExtensionUpdatesQuery(value));

View File

@ -56,8 +56,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { isOfflineError } from 'vs/base/parts/request/common/request';
import { defaultCountBadgeStyles } from 'vs/platform/theme/browser/defaultStyles';
// Extensions that are automatically classified as Programming Language extensions, but should be Feature extensions
const FORCE_FEATURE_EXTENSIONS = ['vscode.git', 'vscode.git-base', 'vscode.search-result'];
export const NONE_CATEGORY = 'none';
class ExtensionsViewState extends Disposable implements IExtensionsViewState {
@ -447,74 +446,56 @@ export class ExtensionsListView extends ViewPane {
}
private filterBuiltinExtensions(local: IExtension[], query: Query, options: IQueryOptions): IExtension[] {
let value = query.value;
const showThemesOnly = /@builtin:themes/i.test(value);
if (showThemesOnly) {
value = value.replace(/@builtin:themes/g, '');
}
const showBasicsOnly = /@builtin:basics/i.test(value);
if (showBasicsOnly) {
value = value.replace(/@builtin:basics/g, '');
}
const showFeaturesOnly = /@builtin:features/i.test(value);
if (showFeaturesOnly) {
value = value.replace(/@builtin:features/g, '');
}
let { value, includedCategories, excludedCategories } = this.parseCategories(query.value);
value = value.replace(/@builtin/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
const result = local
.filter(e => e.isBuiltin && (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1));
const isThemeExtension = (e: IExtension): boolean => {
return (Array.isArray(e.local?.manifest?.contributes?.themes) && e.local!.manifest!.contributes!.themes.length > 0)
|| (Array.isArray(e.local?.manifest?.contributes?.iconThemes) && e.local!.manifest!.contributes!.iconThemes.length > 0);
};
if (showThemesOnly) {
const themesExtensions = result.filter(isThemeExtension);
return this.sortExtensions(themesExtensions, options);
}
const isLanguageBasicExtension = (e: IExtension): boolean => {
return FORCE_FEATURE_EXTENSIONS.indexOf(e.identifier.id) === -1
&& (Array.isArray(e.local?.manifest?.contributes?.grammars) && e.local!.manifest!.contributes!.grammars.length > 0);
};
if (showBasicsOnly) {
const basics = result.filter(isLanguageBasicExtension);
return this.sortExtensions(basics, options);
}
if (showFeaturesOnly) {
const others = result.filter(e => {
return e.local
&& e.local.manifest
&& !isThemeExtension(e)
&& !isLanguageBasicExtension(e);
});
return this.sortExtensions(others, options);
}
.filter(e => e.isBuiltin && (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
&& this.filterExtensionByCategory(e, includedCategories, excludedCategories));
return this.sortExtensions(result, options);
}
private parseCategories(value: string): { value: string; categories: string[] } {
const categories: string[] = [];
private filterExtensionByCategory(e: IExtension, includedCategories: string[], excludedCategories: string[]): boolean {
if (!includedCategories.length && !excludedCategories.length) {
return true;
}
if (e.categories.length) {
if (excludedCategories.length && e.categories.some(category => excludedCategories.includes(category.toLowerCase()))) {
return false;
}
return e.categories.some(category => includedCategories.includes(category.toLowerCase()));
} else {
return includedCategories.includes(NONE_CATEGORY);
}
}
private parseCategories(value: string): { value: string; includedCategories: string[]; excludedCategories: string[] } {
const includedCategories: string[] = [];
const excludedCategories: string[] = [];
value = value.replace(/\bcategory:("([^"]*)"|([^"]\S*))(\s+|\b|$)/g, (_, quotedCategory, category) => {
const entry = (category || quotedCategory || '').toLowerCase();
if (categories.indexOf(entry) === -1) {
categories.push(entry);
if (entry.startsWith('-')) {
if (excludedCategories.indexOf(entry) === -1) {
excludedCategories.push(entry);
}
} else {
if (includedCategories.indexOf(entry) === -1) {
includedCategories.push(entry);
}
}
return '';
});
return { value, categories };
return { value, includedCategories, excludedCategories };
}
private filterInstalledExtensions(local: IExtension[], runningExtensions: readonly IExtensionDescription[], query: Query, options: IQueryOptions): IExtension[] {
let { value, categories } = this.parseCategories(query.value);
let { value, includedCategories, excludedCategories } = this.parseCategories(query.value);
value = value.replace(/@installed/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
const matchingText = (e: IExtension) => (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1 || e.description.toLowerCase().indexOf(value) > -1)
&& (!categories.length || categories.some(category => (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category)));
&& this.filterExtensionByCategory(e, includedCategories, excludedCategories);
let result;
if (options.sortBy !== undefined) {
@ -570,7 +551,7 @@ export class ExtensionsListView extends ViewPane {
}
private filterOutdatedExtensions(local: IExtension[], query: Query, options: IQueryOptions): IExtension[] {
let { value, categories } = this.parseCategories(query.value);
let { value, includedCategories, excludedCategories } = this.parseCategories(query.value);
value = value.replace(/@outdated/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
@ -578,13 +559,13 @@ export class ExtensionsListView extends ViewPane {
.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName))
.filter(extension => extension.outdated
&& (extension.name.toLowerCase().indexOf(value) > -1 || extension.displayName.toLowerCase().indexOf(value) > -1)
&& (!categories.length || categories.some(category => !!extension.local && extension.local.manifest.categories!.some(c => c.toLowerCase() === category))));
&& this.filterExtensionByCategory(extension, includedCategories, excludedCategories));
return this.sortExtensions(result, options);
}
private filterDisabledExtensions(local: IExtension[], runningExtensions: readonly IExtensionDescription[], query: Query, options: IQueryOptions): IExtension[] {
let { value, categories } = this.parseCategories(query.value);
let { value, includedCategories, excludedCategories } = this.parseCategories(query.value);
value = value.replace(/@disabled/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
@ -592,13 +573,13 @@ export class ExtensionsListView extends ViewPane {
.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName))
.filter(e => runningExtensions.every(r => !areSameExtensions({ id: r.identifier.value, uuid: r.uuid }, e.identifier))
&& (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
&& (!categories.length || categories.some(category => (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category))));
&& this.filterExtensionByCategory(e, includedCategories, excludedCategories));
return this.sortExtensions(result, options);
}
private filterEnabledExtensions(local: IExtension[], runningExtensions: readonly IExtensionDescription[], query: Query, options: IQueryOptions): IExtension[] {
let { value, categories } = this.parseCategories(query.value);
let { value, includedCategories, excludedCategories } = this.parseCategories(query.value);
value = value ? value.replace(/@enabled/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase() : '';
@ -607,7 +588,7 @@ export class ExtensionsListView extends ViewPane {
.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName))
.filter(e => runningExtensions.some(r => areSameExtensions({ id: r.identifier.value, uuid: r.uuid }, e.identifier))
&& (e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
&& (!categories.length || categories.some(category => (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category))));
&& this.filterExtensionByCategory(e, includedCategories, excludedCategories));
return this.sortExtensions(result, options);
}
@ -681,15 +662,15 @@ export class ExtensionsListView extends ViewPane {
}
private filterRecentlyUpdatedExtensions(local: IExtension[], query: Query, options: IQueryOptions): IExtension[] {
let { value, categories } = this.parseCategories(query.value);
let { value, includedCategories, excludedCategories } = this.parseCategories(query.value);
const currentTime = Date.now();
local = local.filter(e => !e.isBuiltin && !e.outdated && e.local?.updated && e.local?.installedTimestamp !== undefined && currentTime - e.local.installedTimestamp < ExtensionsListView.RECENT_UPDATE_DURATION);
value = value.replace(/@recentlyUpdated/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase();
const result = local.filter(e =>
(e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1) &&
(!categories.length || categories.some(category => (e.local && e.local.manifest.categories || []).some(c => c.toLowerCase() === category))));
(e.name.toLowerCase().indexOf(value) > -1 || e.displayName.toLowerCase().indexOf(value) > -1)
&& this.filterExtensionByCategory(e, includedCategories, excludedCategories));
options.sortBy = options.sortBy ?? LocalSortBy.UpdateDate;
@ -1082,6 +1063,7 @@ export class ExtensionsListView extends ViewPane {
static isLocalExtensionsQuery(query: string, sortBy?: string): boolean {
return this.isInstalledExtensionsQuery(query)
|| this.isSearchInstalledExtensionsQuery(query)
|| this.isOutdatedExtensionsQuery(query)
|| this.isEnabledExtensionsQuery(query)
|| this.isDisabledExtensionsQuery(query)
@ -1112,7 +1094,11 @@ export class ExtensionsListView extends ViewPane {
}
static isInstalledExtensionsQuery(query: string): boolean {
return /@installed/i.test(query);
return /@installed$/i.test(query);
}
static isSearchInstalledExtensionsQuery(query: string): boolean {
return /@installed\s./i.test(query);
}
static isOutdatedExtensionsQuery(query: string): boolean {
@ -1262,21 +1248,49 @@ export class RecentlyUpdatedExtensionsView extends ExtensionsListView {
}
export class BuiltInFeatureExtensionsView extends ExtensionsListView {
override async show(query: string): Promise<IPagedModel<IExtension>> {
return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:features');
}
export interface StaticQueryExtensionsViewOptions extends ExtensionsListViewOptions {
readonly query: string;
}
export class BuiltInThemesExtensionsView extends ExtensionsListView {
override async show(query: string): Promise<IPagedModel<IExtension>> {
return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:themes');
}
}
export class StaticQueryExtensionsView extends ExtensionsListView {
export class BuiltInProgrammingLanguageExtensionsView extends ExtensionsListView {
override async show(query: string): Promise<IPagedModel<IExtension>> {
return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:basics');
constructor(
protected override readonly options: StaticQueryExtensionsViewOptions,
viewletViewOptions: IViewletViewOptions,
@INotificationService notificationService: INotificationService,
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IExtensionService extensionService: IExtensionService,
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionRecommendationsService extensionRecommendationsService: IExtensionRecommendationsService,
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
@IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService,
@IWorkbenchExtensionManagementService extensionManagementService: IWorkbenchExtensionManagementService,
@IWorkspaceContextService workspaceService: IWorkspaceContextService,
@IProductService productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IOpenerService openerService: IOpenerService,
@IPreferencesService preferencesService: IPreferencesService,
@IStorageService storageService: IStorageService,
@IWorkspaceTrustManagementService workspaceTrustManagementService: IWorkspaceTrustManagementService,
@IWorkbenchExtensionEnablementService extensionEnablementService: IWorkbenchExtensionEnablementService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@ILogService logService: ILogService
) {
super(options, viewletViewOptions, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService,
extensionsWorkbenchService, extensionRecommendationsService, telemetryService, configurationService, contextService, extensionManagementServerService,
extensionManifestPropertiesService, extensionManagementService, workspaceService, productService, contextKeyService, viewDescriptorService, openerService,
preferencesService, storageService, workspaceTrustManagementService, extensionEnablementService, layoutService, logService);
}
override show(): Promise<IPagedModel<IExtension>> {
return super.show(this.options.query);
}
}

View File

@ -8,7 +8,7 @@ import { EXTENSION_CATEGORIES } from 'vs/platform/extensions/common/extensions';
export class Query {
constructor(public value: string, public sortBy: string, public groupBy: string) {
constructor(public value: string, public sortBy: string) {
this.value = value.trim();
}
@ -48,15 +48,7 @@ export class Query {
return '';
});
let groupBy = '';
value = value.replace(/@group:(\w+)(-\w*)?/g, (match, by: string, order: string) => {
groupBy = by;
return '';
});
return new Query(value, sortBy, groupBy);
return new Query(value, sortBy);
}
toString(): string {
@ -65,10 +57,6 @@ export class Query {
if (this.sortBy) {
result = `${result}${result ? ' ' : ''}@sort:${this.sortBy}`;
}
if (this.groupBy) {
result = `${result}${result ? ' ' : ''}@group:${this.groupBy}`;
}
return result;
}

View File

@ -70,72 +70,72 @@ suite('Extension query', () => {
});
test('toString', () => {
let query = new Query('hello', '', '');
let query = new Query('hello', '');
assert.strictEqual(query.toString(), 'hello');
query = new Query('hello world', '', '');
query = new Query('hello world', '');
assert.strictEqual(query.toString(), 'hello world');
query = new Query(' hello ', '', '');
query = new Query(' hello ', '');
assert.strictEqual(query.toString(), 'hello');
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert.strictEqual(query.toString(), '@sort:installs');
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert.strictEqual(query.toString(), '@sort:installs');
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert.strictEqual(query.toString(), '@sort:installs');
query = new Query('hello', 'installs', '');
query = new Query('hello', 'installs');
assert.strictEqual(query.toString(), 'hello @sort:installs');
query = new Query(' hello ', 'installs', '');
query = new Query(' hello ', 'installs');
assert.strictEqual(query.toString(), 'hello @sort:installs');
});
test('isValid', () => {
let query = new Query('hello', '', '');
let query = new Query('hello', '');
assert(query.isValid());
query = new Query('hello world', '', '');
query = new Query('hello world', '');
assert(query.isValid());
query = new Query(' hello ', '', '');
query = new Query(' hello ', '');
assert(query.isValid());
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert(query.isValid());
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert(query.isValid());
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert(query.isValid());
query = new Query('', 'installs', '');
query = new Query('', 'installs');
assert(query.isValid());
query = new Query('hello', 'installs', '');
query = new Query('hello', 'installs');
assert(query.isValid());
query = new Query(' hello ', 'installs', '');
query = new Query(' hello ', 'installs');
assert(query.isValid());
});
test('equals', () => {
const query1 = new Query('hello', '', '');
let query2 = new Query('hello', '', '');
const query1 = new Query('hello', '');
let query2 = new Query('hello', '');
assert(query1.equals(query2));
query2 = new Query('hello world', '', '');
query2 = new Query('hello world', '');
assert(!query1.equals(query2));
query2 = new Query('hello', 'installs', '');
query2 = new Query('hello', 'installs');
assert(!query1.equals(query2));
query2 = new Query('hello', 'installs', '');
query2 = new Query('hello', 'installs');
assert(!query1.equals(query2));
});

View File

@ -61,8 +61,8 @@ suite('ExtensionsViews Tests', () => {
const localDisabledTheme = aLocalExtension('first-disabled-extension', { categories: ['themes'] }, { installedTimestamp: 234567 });
const localDisabledLanguage = aLocalExtension('second-disabled-extension', { categories: ['programming languages'] }, { installedTimestamp: Date.now() - 50000, updated: true });
const localRandom = aLocalExtension('random-enabled-extension', { categories: ['random'] }, { installedTimestamp: 345678 });
const builtInTheme = aLocalExtension('my-theme', { contributes: { themes: ['my-theme'] } }, { type: ExtensionType.System, installedTimestamp: 222 });
const builtInBasic = aLocalExtension('my-lang', { contributes: { grammars: [{ language: 'my-language' }] } }, { type: ExtensionType.System, installedTimestamp: 666666 });
const builtInTheme = aLocalExtension('my-theme', { categories: ['Themes'], contributes: { themes: ['my-theme'] } }, { type: ExtensionType.System, installedTimestamp: 222 });
const builtInBasic = aLocalExtension('my-lang', { categories: ['Programming Languages'], contributes: { grammars: [{ language: 'my-language' }] } }, { type: ExtensionType.System, installedTimestamp: 666666 });
const galleryEnabledLanguage = aGalleryExtension(localEnabledLanguage.manifest.name, { ...localEnabledLanguage.manifest, version: '1.0.1', identifier: localDisabledLanguage.identifier });
@ -286,12 +286,12 @@ suite('ExtensionsViews Tests', () => {
assert.strictEqual(result.get(2).name, localEnabledLanguage.manifest.name, 'Unexpected extension for @enabled query.');
});
await testableView.show('@builtin:themes').then(result => {
assert.strictEqual(result.length, 1, 'Unexpected number of results for @builtin:themes query');
await testableView.show('@builtin category:themes').then(result => {
assert.strictEqual(result.length, 1, 'Unexpected number of results for @builtin category:themes query');
assert.strictEqual(result.get(0).name, builtInTheme.manifest.name, 'Unexpected extension for @builtin:themes query.');
});
await testableView.show('@builtin:basics').then(result => {
await testableView.show('@builtin category:"programming languages"').then(result => {
assert.strictEqual(result.length, 1, 'Unexpected number of results for @builtin:basics query');
assert.strictEqual(result.get(0).name, builtInBasic.manifest.name, 'Unexpected extension for @builtin:basics query.');
});