Skip to content

Commit

Permalink
Merge pull request microsoft#199786 from microsoft/aiday/changingTheS…
Browse files Browse the repository at this point in the history
…ettingsForTheLightbulb

Changing the settings for the lightbulb code action menu
  • Loading branch information
aiday-mar authored and yiliang114 committed Jan 3, 2024
2 parents 25366b3 + c061b52 commit 6d747bb
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 87 deletions.
8 changes: 8 additions & 0 deletions src/vs/editor/browser/config/migrateOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,11 @@ registerEditorSettingMigration('codeActionWidget.includeNearbyQuickfixes', (valu
}
}
});

// Migrate the lightbulb settings
registerEditorSettingMigration('lightbulb.enabled', (value, read, write) => {
if (typeof value === 'boolean') {
write('lightbulb.enabled', value ? undefined : 'off');
}
});

42 changes: 15 additions & 27 deletions src/vs/editor/common/config/editorOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2720,7 +2720,7 @@ class WrappingStrategy extends BaseEditorOption<EditorOption.wrappingStrategy, '

//#region lightbulb

export enum ShowAiIconMode {
export enum ShowLightbulbIconMode {
Off = 'off',
OnCode = 'onCode',
On = 'on'
Expand All @@ -2732,16 +2732,12 @@ export enum ShowAiIconMode {
export interface IEditorLightbulbOptions {
/**
* Enable the lightbulb code action.
* Defaults to true.
* The three possible values are `off`, `on` and `onCode` and the default is `onCode`.
* `off` disables the code action menu.
* `on` shows the code action menu on code and on empty lines.
* `onCode` shows the code action menu on code only.
*/
enabled?: boolean;

experimental?: {
/**
* Highlight AI code actions with AI icon
*/
showAiIcon?: ShowAiIconMode;
};
enabled?: ShowLightbulbIconMode;
}

/**
Expand All @@ -2752,26 +2748,21 @@ export type EditorLightbulbOptions = Readonly<Required<IEditorLightbulbOptions>>
class EditorLightbulb extends BaseEditorOption<EditorOption.lightbulb, IEditorLightbulbOptions, EditorLightbulbOptions> {

constructor() {
const defaults: EditorLightbulbOptions = { enabled: true, experimental: { showAiIcon: ShowAiIconMode.Off } };
const defaults: EditorLightbulbOptions = { enabled: ShowLightbulbIconMode.OnCode };
super(
EditorOption.lightbulb, 'lightbulb', defaults,
{
'editor.lightbulb.enabled': {
type: 'boolean',
default: defaults.enabled,
description: nls.localize('codeActions', "Enables the Code Action lightbulb in the editor.")
},
'editor.lightbulb.experimental.showAiIcon': {
type: 'string',
enum: [ShowAiIconMode.Off, ShowAiIconMode.OnCode, ShowAiIconMode.On],
default: defaults.experimental.showAiIcon,
enum: [ShowLightbulbIconMode.Off, ShowLightbulbIconMode.OnCode, ShowLightbulbIconMode.On],
default: defaults.enabled,
enumDescriptions: [
nls.localize('editor.lightbulb.showAiIcon.off', 'Don not show the AI icon.'),
nls.localize('editor.lightbulb.showAiIcon.onCode', 'Show an AI icon when the code action menu contains an AI action, but only on code.'),
nls.localize('editor.lightbulb.showAiIcon.on', 'Show an AI icon when the code action menu contains an AI action, on code and empty lines.'),
nls.localize('editor.lightbulb.enabled.off', 'Disable the code action menu.'),
nls.localize('editor.lightbulb.enabled.onCode', 'Show the code action menu when the cursor is on lines with code.'),
nls.localize('editor.lightbulb.enabled.on', 'Show the code action menu when the cursor is on lines with code or on empty lines.'),
],
description: nls.localize('showAiIcons', "Show an AI icon along with the lightbulb when the code action menu contains an AI action.")
},
description: nls.localize('enabled', "Enables the Code Action lightbulb in the editor.")
}
}
);
}
Expand All @@ -2782,10 +2773,7 @@ class EditorLightbulb extends BaseEditorOption<EditorOption.lightbulb, IEditorLi
}
const input = _input as IEditorLightbulbOptions;
return {
enabled: boolean(input.enabled, this.defaultValue.enabled),
experimental: {
showAiIcon: stringSet(input.experimental?.showAiIcon, this.defaultValue.experimental?.showAiIcon, [ShowAiIconMode.Off, ShowAiIconMode.OnCode, ShowAiIconMode.On])
}
enabled: stringSet(input.enabled, this.defaultValue.enabled, [ShowLightbulbIconMode.Off, ShowLightbulbIconMode.OnCode, ShowLightbulbIconMode.On])
};
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/common/standalone/standaloneEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ export enum SelectionDirection {
RTL = 1
}

export enum ShowAiIconMode {
export enum ShowLightbulbIconMode {
Off = 'off',
OnCode = 'onCode',
On = 'on'
Expand Down
30 changes: 21 additions & 9 deletions src/vs/editor/contrib/codeAction/browser/codeActionModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { isEqual } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorOption, ShowAiIconMode } from 'vs/editor/common/config/editorOptions';
import { EditorOption, ShowLightbulbIconMode } from 'vs/editor/common/config/editorOptions';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry';
Expand Down Expand Up @@ -66,18 +66,26 @@ class CodeActionOracle extends Disposable {
if (!this._editor.hasModel()) {
return undefined;
}

const model = this._editor.getModel();
const selection = this._editor.getSelection();
if (selection.isEmpty() && trigger.type === CodeActionTriggerType.Auto) {
if (trigger.type === CodeActionTriggerType.Invoke) {
return selection;
}
const enabled = this._editor.getOption(EditorOption.lightbulb).enabled;
if (enabled === ShowLightbulbIconMode.Off) {
return undefined;
} else if (enabled === ShowLightbulbIconMode.On) {
return selection;
} else if (enabled === ShowLightbulbIconMode.OnCode) {
const isSelectionEmpty = selection.isEmpty();
if (!isSelectionEmpty) {
return selection;
}
const model = this._editor.getModel();
const { lineNumber, column } = selection.getPosition();
const line = model.getLineContent(lineNumber);
if (line.length === 0) {
// empty line
const showAiIconOnEmptyLines = this._editor.getOption(EditorOption.lightbulb).experimental?.showAiIcon === ShowAiIconMode.On;
if (!showAiIconOnEmptyLines) {
return undefined;
}
return undefined;
} else if (column === 1) {
// look only right
if (/\s/.test(line[0])) {
Expand Down Expand Up @@ -168,7 +176,11 @@ export class CodeActionModel extends Disposable {
this._register(this._editor.onDidChangeModel(() => this._update()));
this._register(this._editor.onDidChangeModelLanguage(() => this._update()));
this._register(this._registry.onDidChange(() => this._update()));

this._register(this._editor.onDidChangeConfiguration((e) => {
if (e.hasChanged(EditorOption.lightbulb)) {
this._update();
}
}));
this._update();
}

Expand Down
55 changes: 15 additions & 40 deletions src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { ThemeIcon } from 'vs/base/common/themables';
import 'vs/css!./lightBulbWidget';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { EditorOption, ShowAiIconMode } from 'vs/editor/common/config/editorOptions';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { IPosition } from 'vs/editor/common/core/position';
import { computeIndentLevel } from 'vs/editor/common/model/utils';
import { autoFixCommandId, quickFixCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction';
Expand Down Expand Up @@ -86,10 +86,8 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
return;
}

const option = this._editor.getOption(EditorOption.lightbulb).experimental.showAiIcon;
if (
(option === ShowAiIconMode.On || option === ShowAiIconMode.OnCode)
&& this.state.actions.allAIFixes
this.state.actions.allAIFixes
&& this.state.actions.validActions.length === 1
) {
const action = this.state.actions.validActions[0].action;
Expand Down Expand Up @@ -135,15 +133,6 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
this.hide();
}));

this._register(this._editor.onDidChangeConfiguration(e => {
// hide when told to do so
if (e.hasChanged(EditorOption.lightbulb)) {
if (!this._editor.getOption(EditorOption.lightbulb).enabled) {
this.hide();
}
this._updateLightBulbTitleAndIcon();
}
}));

this._register(Event.runAndSubscribe(this._keybindingService.onDidUpdateKeybindings, () => {
this._preferredKbLabel = this._keybindingService.lookupKeybinding(autoFixCommandId)?.getLabel() ?? undefined;
Expand Down Expand Up @@ -180,11 +169,6 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
return this.hide();
}

const onlyAIActions = actions.allAIFixes;
const showAiIcon = this._editor.getOption(EditorOption.lightbulb).experimental.showAiIcon;
if (onlyAIActions && showAiIcon === ShowAiIconMode.Off) {
return this.hide();
}

const model = this._editor.getModel();
if (!model) {
Expand All @@ -194,7 +178,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
const { lineNumber, column } = model.validatePosition(atPosition);

const tabSize = model.getOptions().tabSize;
const fontInfo = options.get(EditorOption.fontInfo);
const fontInfo = this._editor.getOptions().get(EditorOption.fontInfo);
const lineContent = model.getLineContent(lineNumber);
const indent = computeIndentLevel(lineContent, tabSize);
const lineHasSpace = fontInfo.spaceWidth * indent > 22;
Expand Down Expand Up @@ -248,30 +232,21 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
}
let icon: ThemeIcon;
let autoRun = false;
const option = this._editor.getOption(EditorOption.lightbulb).experimental.showAiIcon;
if (option === ShowAiIconMode.On || option === ShowAiIconMode.OnCode) {
if (option === ShowAiIconMode.On && this.state.actions.allAIFixes) {
icon = Codicon.sparkleFilled;
if (this.state.actions.validActions.length === 1) {
autoRun = true;
}
} else if (this.state.actions.hasAutoFix) {
if (this.state.actions.hasAIFix) {
icon = Codicon.lightbulbSparkleAutofix;
} else {
icon = Codicon.lightbulbAutofix;
}
} else if (this.state.actions.hasAIFix) {
icon = Codicon.lightbulbSparkle;
} else {
icon = Codicon.lightBulb;
if (this.state.actions.allAIFixes) {
icon = Codicon.sparkleFilled;
if (this.state.actions.validActions.length === 1) {
autoRun = true;
}
} else {
if (this.state.actions.hasAutoFix) {
icon = Codicon.lightbulbAutofix;
} else if (this.state.actions.hasAutoFix) {
if (this.state.actions.hasAIFix) {
icon = Codicon.lightbulbSparkleAutofix;
} else {
icon = Codicon.lightBulb;
icon = Codicon.lightbulbAutofix;
}
} else if (this.state.actions.hasAIFix) {
icon = Codicon.lightbulbSparkle;
} else {
icon = Codicon.lightBulb;
}
this._updateLightbulbTitle(this.state.actions.hasAutoFix, autoRun);
this._iconClasses = ThemeIcon.asClassNameArray(icon);
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/standalone/browser/standaloneEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor {
WrappingIndent: standaloneEnums.WrappingIndent,
InjectedTextCursorStops: standaloneEnums.InjectedTextCursorStops,
PositionAffinity: standaloneEnums.PositionAffinity,
ShowAiIconMode: standaloneEnums.ShowAiIconMode,
ShowLightbulbIconMode: standaloneEnums.ShowLightbulbIconMode,

// classes
ConfigurationChangedEvent: <any>ConfigurationChangedEvent,
Expand Down
15 changes: 6 additions & 9 deletions src/vs/monaco.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4131,7 +4131,7 @@ declare namespace monaco.editor {
readonly minimapCanvasOuterHeight: number;
}

export enum ShowAiIconMode {
export enum ShowLightbulbIconMode {
Off = 'off',
OnCode = 'onCode',
On = 'on'
Expand All @@ -4143,15 +4143,12 @@ declare namespace monaco.editor {
export interface IEditorLightbulbOptions {
/**
* Enable the lightbulb code action.
* Defaults to true.
* The three possible values are `off`, `on` and `onCode` and the default is `onCode`.
* `off` disables the code action menu.
* `on` shows the code action menu on code and on empty lines.
* `onCode` shows the code action menu on code only.
*/
enabled?: boolean;
experimental?: {
/**
* Highlight AI code actions with AI icon
*/
showAiIcon?: ShowAiIconMode;
};
enabled?: ShowLightbulbIconMode;
}

export interface IEditorStickyScrollOptions {
Expand Down

0 comments on commit 6d747bb

Please sign in to comment.