Change:
Today I noticed that VSCode updates and installs extensions even if they are disabled. In fact, I was reminded of a couple of extensions I no longer use by the hundreds of megabytes downloaded in the background. Could you consider adding this as a toggle in settings or disabling this behavior altogether?
I see your point. But what is the reason behind having such extension installed and disabled, instead of uninstalling it?
So that they don't update in the background and waste traffic on my metered connection ;) I switch between a lot of languages and runtimes regularly. I use VSCode for C++, C#, F#, PHP, Python, JS/Flow, Processing, GLSL/HLSL, Arduino and others, but I like to keep a "working set" of supporting extensions, depending on the project I'm working on. This comes down to the question "what does disabling extensions actually do", besides declutter the list? Initially I thought this would help with memory usage and startup time, but I don't believe that's really the case. If there's no practical use for disabling, maybe that option should be deprecated in favor of just uninstalling them.
Yes, Disabling helps you in creating a working set. But I see your point and agreed that not auto updating a disabled extension makes sense.
Know that disabled extension can also still popup a notification as well. I'm sure the C++ extension (ms-vscode.cpptools) occasionally (not sure when exactly) asks you to enter a survey even when the extension is disabled.
This should not happen. Please file a separate issue with steps to repro.
I will take a look at this one and follow up with a pull request.
I was wondering about the current status of this issue? If this issue still persists, I would love to contribute and try to resolve it. If this is the case, I would highly appreciate a code pointer to the update procedure, as I am fairly new to this project.
I have not had the chance to look into this. is this something that we still want to pursue?
It looks to me like you have already implemented the desired changes a few days ago?
This is not yet supported and contribution is very much appreciated. Code pointer: Auto update of extensions happen here
Thank you I will look into it. I would say, we just out the disabled extensions and do not return them. Do you have something different / more elaborate in mind? And do you happen to know an easy way to test this function (i.e. forcing an auto-update)?
I was able to implement this feature and also a configuration to let users decide on whether disabled extensions should be updated. The PR can be found at .

Discussion:
import { IViewContainersRegistry, ViewContainerLocation, Extensions as ViewContainerExtensions, IViewsService } from 'vs/workbench/common/views'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; <del> import { ContextKeyAndExpr, ContextKeyDefinedExpr, ContextKeyEqualsExpr, ContextKeyExpr, ContextKeyOrExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; </del> <ins> import { ContextKeyAndExpr, ContextKeyDefinedExpr, ContextKeyEqualsExpr, ContextKeyExpr, ContextKeyNotEqualsExpr, ContextKeyOrExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; </ins> import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { InstallExtensionQuickAccessProvider, ManageExtensionsQuickAccessProvider } from 'vs/workbench/contrib/extensions/browser/extensionsQuickAccess';

type: 'object', properties: { 'extensions.autoUpdate': { <del> type: 'boolean', description: localize('extensionsAutoUpdate', "When enabled, automatically installs updates for extensions. The updates are fetched from a Microsoft online service."), </del> <ins> enum: [true, 'onlyEnabledExtensions', false,], enumItemLabels: [ localize('all', "All Extensions"), localize('enabled', "Only Enabled Extensions"), localize('none', "None"), ], enumDescriptions: [ localize('extensions.autoUpdate.true', 'Download and install updates automatically for all extensions.'), localize('extensions.autoUpdate.enabled', 'Download and install updates automatically only for enabled extensions. Disabled extensions will not be updated automatically.'), localize('extensions.autoUpdate.false', 'Extensions are not automatically updated.'), ], description: localize('extensions.autoUpdate', "Controls the automatic update behavior of extensions. The updates are fetched from a Microsoft online service."), </ins> default: true, scope: ConfigurationScope.APPLICATION, tags: ['usesOnlineServices']

} }); <ins> const autoUpdateExtensionsSubMenu = new MenuId('autoUpdateExtensionsSubMenu'); MenuRegistry.appendMenuItem(MenuId.ViewContainerTitle, <ISubmenuItem>{ submenu: autoUpdateExtensionsSubMenu, title: localize('configure auto updating extensions', "Configure Auto Updating Extensions"), when: ContextKeyEqualsExpr.create('viewContainer', VIEWLET_ID), group: '1_updates', order: 5, }); </ins> this.registerExtensionAction({ <del> id: 'workbench.extensions.action.disableAutoUpdate', title: { value: localize('disableAutoUpdate', "Disable Auto Updating Extensions"), original: 'Disable Auto Updating Extensions' }, category: ExtensionsLocalizedLabel, </del> <ins> id: 'configureExtensionsAutoUpdate.all', title: localize('configureExtensionsAutoUpdate.all', "All Extensions"), toggled: ContextKeyAndExpr.create([ContextKeyDefinedExpr.create(`config.${AutoUpdateConfigurationKey}`), ContextKeyNotEqualsExpr.create(`config.${AutoUpdateConfigurationKey}`, 'onlyEnabledExtensions')]), </ins> menu: [{ <del> id: MenuId.CommandPalette, }, { id: MenuId.ViewContainerTitle, when: ContextKeyAndExpr.create([ContextKeyEqualsExpr.create('viewContainer', VIEWLET_ID), ContextKeyDefinedExpr.create(`config.${AutoUpdateConfigurationKey}`)]), group: '1_updates', order: 2 </del> <ins> id: autoUpdateExtensionsSubMenu, order: 1, }], run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, true) }); this.registerExtensionAction({ id: 'configureExtensionsAutoUpdate.enabled', title: localize('configureExtensionsAutoUpdate.enabled', "Only Enabled Extensions"), toggled: ContextKeyEqualsExpr.create(`config.${AutoUpdateConfigurationKey}`, 'onlyEnabledExtensions'), menu: [{ id: autoUpdateExtensionsSubMenu, order: 2, }], run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, 'onlyEnabledExtensions') }); this.registerExtensionAction({ id: 'configureExtensionsAutoUpdate.none', title: localize('configureExtensionsAutoUpdate.none', "None"), toggled: ContextKeyEqualsExpr.create(`config.${AutoUpdateConfigurationKey}`, false), menu: [{ id: autoUpdateExtensionsSubMenu, order: 3, </ins> }], run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, false) });

when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) }, { id: MenuId.ViewContainerTitle, <del> when: ContextKeyAndExpr.create([ContextKeyEqualsExpr.create('viewContainer', VIEWLET_ID), ContextKeyDefinedExpr.create(`config.${AutoUpdateConfigurationKey}`).negate()]), </del> <ins> when: ContextKeyAndExpr.create([ContextKeyEqualsExpr.create('viewContainer', VIEWLET_ID), ContextKeyOrExpr.create([ContextKeyDefinedExpr.create(`config.${AutoUpdateConfigurationKey}`).negate(), ContextKeyEqualsExpr.create(`config.${AutoUpdateConfigurationKey}`, 'onlyEnabledExtensions')])]), </ins> group: '1_updates', order: 2 }],

}); this.registerExtensionAction({ <ins> id: 'workbench.extensions.action.disableAutoUpdate', title: { value: localize('disableAutoUpdate', "Disable Auto Updating Extensions"), original: 'Disable Auto Updating Extensions' }, category: ExtensionsLocalizedLabel, f1: true, run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, false) }); this.registerExtensionAction({ </ins> id: 'workbench.extensions.action.enableAutoUpdate', <del> title: { value: localize('enableAutoUpdate', "Enable Auto Updating Extensions"), original: 'Enable Auto Updating Extensions' }, </del> <ins> title: { value: localize('enableAutoUpdate', "Enable Auto Updating All Extensions"), original: 'Enable Auto Updating All Extensions' }, </ins> category: ExtensionsLocalizedLabel, <del> menu: [{ id: MenuId.CommandPalette, }, { id: MenuId.ViewContainerTitle, when: ContextKeyAndExpr.create([ContextKeyEqualsExpr.create('viewContainer', VIEWLET_ID), ContextKeyDefinedExpr.create(`config.${AutoUpdateConfigurationKey}`).negate()]), group: '1_updates', order: 3 }], </del> <ins> f1: true, </ins> run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, true) });

import { IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions'; import { IUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataSync'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; <ins> import { isBoolean } from 'vs/base/common/types'; </ins> interface IExtensionStateProvider<T> { (extension: Extension): T;

} }, this)); <ins> this._register(extensionEnablementService.onEnablementChanged(platformExtensions => { if (this.getAutoUpdateValue() === 'onlyEnabledExtensions' && platformExtensions.some(e => this.extensionEnablementService.isEnabled(e))) { this.checkForUpdates(); } }, this)); </ins> this.queryLocal().then(() => { this.resetIgnoreAutoUpdateExtensions(); this.eventuallySyncWithGallery(true);

return Promise.resolve(this.syncDelayer.trigger(() => this.syncWithGallery(), 0)); } <ins> private getAutoUpdateValue(): boolean | 'onlyEnabledExtensions' { const autoUpdate = this.configurationService.getValue<boolean | 'onlyEnabledExtensions'>(AutoUpdateConfigurationKey); return isBoolean(autoUpdate) || autoUpdate === 'onlyEnabledExtensions' ? autoUpdate : true; } </ins> private isAutoUpdateEnabled(): boolean { <del> return this.configurationService.getValue(AutoUpdateConfigurationKey); </del> <ins> return this.getAutoUpdateValue() !== false; </ins> } private isAutoCheckUpdatesEnabled(): boolean {

return Promise.resolve(); } <del> const toUpdate = this.outdated.filter(e => !this.isAutoUpdateIgnored(new ExtensionIdentifierWithVersion(e.identifier, e.version))); </del> <ins> const toUpdate = this.outdated.filter(e => !this.isAutoUpdateIgnored(new ExtensionIdentifierWithVersion(e.identifier, e.version)) && (this.getAutoUpdateValue() === true || (e.local && this.extensionEnablementService.isEnabled(e.local))) ); </ins> return Promises.settled(toUpdate.map(e => this.install(e))); }