diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 0767fa5d8f6e6..6a3d5c45fafab 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -18,7 +18,7 @@ import { VIEWLET_ID, IExtensionsWorkbenchService, IExtensionsViewPaneContainer, import { OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowRecommendedKeymapExtensionsAction, ShowPopularExtensionsAction, ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, ShowBuiltInExtensionsAction, UpdateAllAction, - EnableAllAction, EnableAllWorkspaceAction, DisableAllAction, DisableAllWorkspaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, InstallVSIXAction, ReinstallAction, InstallSpecificVersionOfExtensionAction, ClearExtensionsSearchResultsAction, ConfigureWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction + EnableAllAction, EnableAllWorkspaceAction, DisableAllAction, DisableAllWorkspaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, InstallVSIXAction, ReinstallAction, InstallSpecificVersionOfExtensionAction, ClearExtensionsSearchResultsAction, ConfigureWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, RefreshExtensionsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor'; @@ -773,6 +773,22 @@ class ExtensionsContributions implements IWorkbenchContribution { } }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: RefreshExtensionsAction.ID, + title: { value: RefreshExtensionsAction.LABEL, original: 'Refresh' }, + category: ExtensionsLocalizedLabel, + menu: { + id: MenuId.CommandPalette, + } + }); + } + run(accessor: ServicesAccessor) { + return runAction(accessor.get(IInstantiationService).createInstance(RefreshExtensionsAction, RefreshExtensionsAction.ID, RefreshExtensionsAction.LABEL)); + } + }); + registerAction2(class extends Action2 { constructor() { super({ diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 7d334c9b880b8..da0dcd1413cda 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -1717,11 +1717,11 @@ export class ShowInstalledExtensionsAction extends Action { super(id, label, undefined, true); } - run(refresh?: boolean): Promise { + run(): Promise { return this.viewletService.openViewlet(VIEWLET_ID, true) .then(viewlet => viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer) .then(viewlet => { - viewlet.search('@installed ', refresh); + viewlet.search('@installed '); viewlet.focus(); }); } @@ -1793,6 +1793,28 @@ export class ClearExtensionsInputAction extends ClearExtensionsSearchResultsActi } +export class RefreshExtensionsAction extends Action { + + static readonly ID = 'workbench.extensions.action.refreshExtension'; + static readonly LABEL = localize('refreshExtension', "Refresh"); + + constructor( + id: string, + label: string, + @IViewsService private readonly viewsService: IViewsService + ) { + super(id, label, 'codicon-refresh', true); + } + + async run(): Promise { + const viewPaneContainer = this.viewsService.getActiveViewPaneContainerWithId(VIEWLET_ID); + if (viewPaneContainer) { + const extensionsViewPaneContainer = viewPaneContainer as IExtensionsViewPaneContainer; + extensionsViewPaneContainer.refresh(); + } + } +} + export class ShowBuiltInExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.listBuiltInExtensions'; @@ -1923,7 +1945,7 @@ export class ShowRecommendedExtensionsAction extends Action { return this.viewletService.openViewlet(VIEWLET_ID, true) .then(viewlet => viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer) .then(viewlet => { - viewlet.search('@recommended ', true); + viewlet.search('@recommended '); viewlet.focus(); }); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 8cb16fae74ef9..85eb5baec5911 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -22,7 +22,7 @@ import { ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, SearchCategoryAction, RecentlyPublishedExtensionsAction, ShowInstalledExtensionsAction, ShowOutdatedExtensionsAction, ShowDisabledExtensionsAction, - ShowEnabledExtensionsAction, PredefinedExtensionFilterAction + ShowEnabledExtensionsAction, PredefinedExtensionFilterAction, RefreshExtensionsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; @@ -541,6 +541,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE return [ new SubmenuAction('workbench.extensions.action.filterExtensions', localize('filterExtensions', "Filter Extensions..."), filterActions, 'codicon-filter'), + this.instantiationService.createInstance(RefreshExtensionsAction, RefreshExtensionsAction.ID, RefreshExtensionsAction.LABEL), this.instantiationService.createInstance(ClearExtensionsInputAction, ClearExtensionsInputAction.ID, ClearExtensionsInputAction.LABEL, this.onSearchChange, this.searchBox ? this.searchBox.getValue() : ''), ]; } @@ -565,16 +566,16 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE return actions; } - search(value: string, refresh: boolean = false): void { - if (this.searchBox) { - if (this.searchBox.getValue() !== value) { - this.searchBox.setValue(value); - } else if (refresh) { - this.doSearch(); - } + search(value: string): void { + if (this.searchBox && this.searchBox.getValue() !== value) { + this.searchBox.setValue(value); } } + refresh(): void { + this.doSearch(true); + } + private triggerSearch(): void { this.searchDelayer.trigger(() => this.doSearch(), this.searchBox && this.searchBox.getValue() ? 500 : 0).then(undefined, err => this.onError(err)); } @@ -601,7 +602,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE super.saveState(); } - private doSearch(): Promise { + private doSearch(refresh?: boolean): Promise { const value = this.normalizedQuery(); const isRecommendedExtensionsQuery = ExtensionsListView.isRecommendedExtensionsQuery(value); this.searchInstalledExtensionsContextKey.set(ExtensionsListView.isInstalledExtensionsQuery(value)); @@ -615,7 +616,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE this.defaultViewsContextKey.set(!value); return this.progress(Promise.all(this.panes.map(view => - (view).show(this.normalizedQuery()) + (view).show(this.normalizedQuery(), refresh) .then(model => this.alertSearchResult(model.length, view.id)) ))).then(() => undefined); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index c5fc5e44a5c67..2353bb4a0219b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -180,9 +180,9 @@ export class ExtensionsListView extends ViewPane { } } - async show(query: string): Promise> { + async show(query: string, refresh?: boolean): Promise> { if (this.queryRequest) { - if (this.queryRequest.query === query) { + if (!refresh && this.queryRequest.query === query) { return this.queryRequest.request; } this.queryRequest.request.cancel(); diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index 2bc9d75a77cbf..7df228a2d4829 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -18,7 +18,8 @@ import { IViewPaneContainer } from 'vs/workbench/common/views'; export const VIEWLET_ID = 'workbench.view.extensions'; export interface IExtensionsViewPaneContainer extends IViewPaneContainer { - search(text: string, refresh?: boolean): void; + search(text: string): void; + refresh(): void; } export const enum ExtensionState {