diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 14d3ec12623..d00a0e2365b 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -598,6 +598,11 @@ const editorConfiguration: IConfigurationNode = { 'default': EDITOR_DEFAULTS.contribInfo.colorDecorators, 'description': nls.localize('colorDecorators', "Controls whether the editor should render the inline color decorators and color picker.") }, + 'editor.lightbulb.enabled': { + 'type': 'boolean', + 'default': EDITOR_DEFAULTS.contribInfo.lightbulbEnabled, + 'description': nls.localize('codeActions', "Enables the code action lightbulb") + }, 'diffEditor.renderSideBySide': { 'type': 'boolean', 'default': true, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index d3a94dcc623..e1c77e1f78a 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -114,6 +114,17 @@ export interface IEditorMinimapOptions { maxColumn?: number; } +/** + * Configuration options for editor minimap + */ +export interface IEditorLightbulbOptions { + /** + * Enable the lightbulb code action. + * Defaults to true. + */ + enabled?: boolean; +} + /** * Configuration options for the editor. */ @@ -462,6 +473,10 @@ export interface IEditorOptions { * @internal */ referenceInfos?: boolean; + /** + * Control the behavior and rendering of the code action lightbulb. + */ + lightbulb?: IEditorLightbulbOptions; /** * Enable code folding * Defaults to true in vscode and to false in monaco-editor. @@ -795,6 +810,7 @@ export interface EditorContribOptions { readonly matchBrackets: boolean; readonly find: InternalEditorFindOptions; readonly colorDecorators: boolean; + readonly lightbulbEnabled: boolean; } /** @@ -1140,6 +1156,7 @@ export class InternalEditorOptions { && a.matchBrackets === b.matchBrackets && this._equalFindOptions(a.find, b.find) && a.colorDecorators === b.colorDecorators + && a.lightbulbEnabled === b.lightbulbEnabled ); } @@ -1669,6 +1686,7 @@ export class EditorOptionsValidator { matchBrackets: _boolean(opts.matchBrackets, defaults.matchBrackets), find: find, colorDecorators: _boolean(opts.colorDecorators, defaults.colorDecorators), + lightbulbEnabled: _boolean(opts.lightbulb.enabled, defaults.lightbulbEnabled) }; } } @@ -1766,7 +1784,8 @@ export class InternalEditorOptionsFactory { showFoldingControls: opts.contribInfo.showFoldingControls, matchBrackets: (accessibilityIsOn ? false : opts.contribInfo.matchBrackets), // DISABLED WHEN SCREEN READER IS ATTACHED find: opts.contribInfo.find, - colorDecorators: opts.contribInfo.colorDecorators + colorDecorators: opts.contribInfo.colorDecorators, + lightbulbEnabled: opts.contribInfo.lightbulbEnabled } }; } @@ -2205,6 +2224,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { seedSearchStringFromSelection: true, autoFindInSelection: false }, - colorDecorators: true + colorDecorators: true, + lightbulbEnabled: true }, }; diff --git a/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts b/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts index 8bb2b4c2f02..c25c621b809 100644 --- a/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts @@ -29,12 +29,12 @@ export class LightBulbWidget implements IDisposable, IContentWidget { private _futureFixes = new CancellationTokenSource(); constructor(editor: ICodeEditor) { - this._editor = editor; - this._editor.addContentWidget(this); - this._domNode = document.createElement('div'); this._domNode.className = 'lightbulb-glyph'; + this._editor = editor; + this._editor.addContentWidget(this); + this._disposables.push(dom.addStandardDisposableListener(this._domNode, 'click', e => { // a bit of extra work to make sure the menu // doesn't cover the line-text diff --git a/src/vs/editor/contrib/quickFix/browser/quickFixCommands.ts b/src/vs/editor/contrib/quickFix/browser/quickFixCommands.ts index 605591babeb..e6a1ef98e96 100644 --- a/src/vs/editor/contrib/quickFix/browser/quickFixCommands.ts +++ b/src/vs/editor/contrib/quickFix/browser/quickFixCommands.ts @@ -9,7 +9,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IMarkerService } from 'vs/platform/markers/common/markers'; import { ICommonCodeEditor, IEditorContribution } from 'vs/editor/common/editorCommon'; @@ -32,30 +32,28 @@ export class QuickFixController implements IEditorContribution { private _editor: ICodeEditor; private _model: QuickFixModel; - private _quickFixContextMenu: QuickFixContextMenu; - private _lightBulbWidget: LightBulbWidget; + private _quickFixContextMenu: QuickFixContextMenu | undefined; + private _lightBulbWidget: LightBulbWidget | undefined; private _disposables: IDisposable[] = []; + private enabled: boolean = false; - constructor(editor: ICodeEditor, + + constructor( + editor: ICodeEditor, @IMarkerService markerService: IMarkerService, - @IContextKeyService contextKeyService: IContextKeyService, - @ICommandService commandService: ICommandService, - @IContextMenuService contextMenuService: IContextMenuService, - @IKeybindingService private _keybindingService: IKeybindingService + @ICommandService private readonly _commandService: ICommandService, + @IContextMenuService private readonly _contextMenuService: IContextMenuService, + @IKeybindingService private readonly _keybindingService: IKeybindingService ) { this._editor = editor; this._model = new QuickFixModel(this._editor, markerService); - this._quickFixContextMenu = new QuickFixContextMenu(editor, contextMenuService, commandService); - this._lightBulbWidget = new LightBulbWidget(editor); - - this._updateLightBulbTitle(); this._disposables.push( - this._quickFixContextMenu.onDidExecuteCodeAction(_ => this._model.trigger('auto')), - this._lightBulbWidget.onClick(this._handleLightBulbSelect, this), - this._model.onDidChangeFixes(e => this._onQuickFixEvent(e)), - this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitle, this) + this._editor.onDidChangeConfiguration(() => this.onEditorConfigurationChange()), + this._model.onDidChangeFixes(e => this._onQuickFixEvent(e)) ); + + this.onEditorConfigurationChange(); } public dispose(): void { @@ -63,21 +61,46 @@ export class QuickFixController implements IEditorContribution { dispose(this._disposables); } + private get lightBulbWidget(): LightBulbWidget { + if (!this._lightBulbWidget) { + this._lightBulbWidget = new LightBulbWidget(this._editor); + this._disposables.push( + this._lightBulbWidget.onClick(this._handleLightBulbSelect, this), + this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitle, this) + ); + this._updateLightBulbTitle(); + } + return this._lightBulbWidget; + } + + private get quickFixContextMenu(): QuickFixContextMenu { + if (!this._quickFixContextMenu) { + this._quickFixContextMenu = new QuickFixContextMenu(this._editor, this._contextMenuService, this._commandService); + this._disposables.push(this._quickFixContextMenu.onDidExecuteCodeAction(_ => { + this._model.trigger('auto'); + })); + } + return this._quickFixContextMenu; + } + private _onQuickFixEvent(e: QuickFixComputeEvent): void { if (e && e.type === 'manual') { - this._quickFixContextMenu.show(e.fixes, e.position); - + this.quickFixContextMenu.show(e.fixes, e.position); } else if (e && e.fixes) { // auto magically triggered // * update an existing list of code actions // * manage light bulb - if (this._quickFixContextMenu.isVisible) { - this._quickFixContextMenu.show(e.fixes, e.position); + if (this.quickFixContextMenu.isVisible) { + this.quickFixContextMenu.show(e.fixes, e.position); } else { - this._lightBulbWidget.model = e; + if (this.enabled) { + this.lightBulbWidget.model = e; + } } } else { - this._lightBulbWidget.hide(); + if (this._lightBulbWidget) { + this._lightBulbWidget.hide(); + } } } @@ -86,7 +109,7 @@ export class QuickFixController implements IEditorContribution { } private _handleLightBulbSelect(coords: { x: number, y: number }): void { - this._quickFixContextMenu.show(this._lightBulbWidget.model.fixes, coords); + this.quickFixContextMenu.show(this.lightBulbWidget.model.fixes, coords); } public triggerFromEditorSelection(): void { @@ -94,6 +117,10 @@ export class QuickFixController implements IEditorContribution { } private _updateLightBulbTitle(): void { + if (!this._lightBulbWidget) { + return; + } + const kb = this._keybindingService.lookupKeybinding(QuickFixAction.Id); let title: string; if (kb) { @@ -101,7 +128,18 @@ export class QuickFixController implements IEditorContribution { } else { title = nls.localize('quickFix', "Show Fixes"); } - this._lightBulbWidget.title = title; + this.lightBulbWidget.title = title; + } + + private onEditorConfigurationChange(): void { + this.enabled = this._editor.getConfiguration().contribInfo.lightbulbEnabled; + + if (!this.enabled) { + if (this._lightBulbWidget) { + this._lightBulbWidget.dispose(); + this._lightBulbWidget = undefined; + } + } } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 467ac20a374..194484f2618 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2683,6 +2683,17 @@ declare module monaco.editor { maxColumn?: number; } + /** + * Configuration options for editor minimap + */ + export interface IEditorLightbulbOptions { + /** + * Enable the lightbulb code action. + * Defaults to true. + */ + enabled?: boolean; + } + /** * Configuration options for the editor. */ @@ -3018,6 +3029,10 @@ declare module monaco.editor { * Defaults to true. */ codeLens?: boolean; + /** + * Control the behavior and rendering of the code action lightbulb. + */ + lightbulb?: IEditorLightbulbOptions; /** * Enable code folding * Defaults to true in vscode and to false in monaco-editor. @@ -3296,6 +3311,7 @@ declare module monaco.editor { readonly matchBrackets: boolean; readonly find: InternalEditorFindOptions; readonly colorDecorators: boolean; + readonly lightbulbEnabled: boolean; } /**