Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions extensions/typescript/src/features/refactorProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

'use strict';

import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, workspace, WorkspaceEdit, window, QuickPickItem, Selection, Position } from 'vscode';
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, workspace, WorkspaceEdit, window, QuickPickItem, Selection, Position, CodeAction } from 'vscode';

import * as Proto from '../protocol';
import { ITypescriptServiceClient } from '../typescriptService';
Expand Down Expand Up @@ -56,20 +56,22 @@ export default class TypeScriptRefactorProvider implements CodeActionProvider {
return [];
}

const actions: Command[] = [];
const actions: CodeAction[] = [];
for (const info of response.body) {
if (info.inlineable === false) {
actions.push({
title: info.description,
command: this.selectRefactorCommandId,
arguments: [file, info, range]
arguments: [file, info, range],
dontTriggerLightBulb: true
});
} else {
for (const action of info.actions) {
actions.push({
title: action.description,
command: this.doRefactorCommandId,
arguments: [file, info.name, action.name, range]
arguments: [file, info.name, action.name, range],
dontTriggerLightBulb: true
});
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/vs/editor/common/modes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ export interface CodeActionProvider {
/**
* Provide commands for the given document and range.
*/
provideCodeActions(model: editorCommon.IReadOnlyModel, range: Range, token: CancellationToken): Command[] | Thenable<Command[]>;
provideCodeActions(model: editorCommon.IReadOnlyModel, range: Range, token: CancellationToken): CodeAction[] | Thenable<CodeAction[]>;
}

/**
Expand Down Expand Up @@ -737,6 +737,11 @@ export interface Command {
tooltip?: string;
arguments?: any[];
}

export interface CodeAction extends Command {
dontTriggerLightBulb?: boolean;
}

export interface ICodeLensSymbol {
range: IRange;
id?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class LightBulbWidget implements IDisposable {
const { token } = this._futureFixes;

e.fixes.done(fixes => {
if (!token.isCancellationRequested && fixes && fixes.length > 0) {
if (!token.isCancellationRequested && fixes && fixes.some(fix => !fix.dontTriggerLightBulb)) {
this.show(e);
} else {
this.hide();
Expand Down
6 changes: 3 additions & 3 deletions src/vs/editor/contrib/quickFix/browser/quickFix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
import URI from 'vs/base/common/uri';
import { IReadOnlyModel } from 'vs/editor/common/editorCommon';
import { Range } from 'vs/editor/common/core/range';
import { Command, CodeActionProviderRegistry } from 'vs/editor/common/modes';
import { CodeAction, CodeActionProviderRegistry } from 'vs/editor/common/modes';
import { asWinJsPromise } from 'vs/base/common/async';
import { TPromise } from 'vs/base/common/winjs.base';
import { onUnexpectedExternalError, illegalArgument } from 'vs/base/common/errors';
import { IModelService } from 'vs/editor/common/services/modelService';
import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';

export function getCodeActions(model: IReadOnlyModel, range: Range): TPromise<Command[]> {
export function getCodeActions(model: IReadOnlyModel, range: Range): TPromise<CodeAction[]> {

const allResults: Command[] = [];
const allResults: CodeAction[] = [];
const promises = CodeActionProviderRegistry.all(model).map(support => {
return asWinJsPromise(token => support.provideCodeActions(model, range, token)).then(result => {
if (Array.isArray(result)) {
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/contrib/quickFix/browser/quickFixModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { Range } from 'vs/editor/common/core/range';
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { CodeActionProviderRegistry, Command } from 'vs/editor/common/modes';
import { CodeActionProviderRegistry, CodeAction } from 'vs/editor/common/modes';
import { getCodeActions } from './quickFix';
import { Position } from 'vs/editor/common/core/position';

Expand Down Expand Up @@ -116,7 +116,7 @@ export interface QuickFixComputeEvent {
type: 'auto' | 'manual';
range: Range;
position: Position;
fixes: TPromise<Command[]>;
fixes: TPromise<CodeAction[]>;
}

export class QuickFixModel {
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/contrib/quickFix/browser/quickFixWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { always } from 'vs/base/common/async';
import { getDomNodePagePosition } from 'vs/base/browser/dom';
import { Position } from 'vs/editor/common/core/position';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { Command } from 'vs/editor/common/modes';
import { CodeAction } from 'vs/editor/common/modes';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { Action } from 'vs/base/common/actions';
Expand All @@ -32,7 +32,7 @@ export class QuickFixContextMenu {
this._commandService = commandService;
}

show(fixes: TPromise<Command[]>, at: { x: number; y: number } | Position) {
show(fixes: TPromise<CodeAction[]>, at: { x: number; y: number } | Position) {

const actions = fixes.then(value => {
return value.map(command => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Model } from 'vs/editor/common/model/model';
import { mockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
import { MarkerService } from 'vs/platform/markers/common/markerService';
import { QuickFixOracle } from 'vs/editor/contrib/quickFix/browser/quickFixModel';
import { CodeActionProviderRegistry, LanguageIdentifier } from 'vs/editor/common/modes';
import { CodeActionProviderRegistry, LanguageIdentifier, CodeAction } from 'vs/editor/common/modes';
import { IDisposable } from 'vs/base/common/lifecycle';
import Event from 'vs/base/common/event';
import { Range } from 'vs/editor/common/core/range';
Expand Down Expand Up @@ -248,5 +248,4 @@ suite('QuickFix', () => {

reg.dispose();
});

});
6 changes: 3 additions & 3 deletions src/vs/editor/standalone/browser/standaloneLanguages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ export function registerCodeLensProvider(languageId: string, provider: modes.Cod
*/
export function registerCodeActionProvider(languageId: string, provider: CodeActionProvider): IDisposable {
return modes.CodeActionProviderRegistry.register(languageId, {
provideCodeActions: (model: editorCommon.IReadOnlyModel, range: Range, token: CancellationToken): modes.Command[] | Thenable<modes.Command[]> => {
provideCodeActions: (model: editorCommon.IReadOnlyModel, range: Range, token: CancellationToken): modes.CodeAction[] | Thenable<modes.CodeAction[]> => {
let markers = StaticServices.markerService.get().read({ resource: model.uri }).filter(m => {
return Range.areIntersectingOrTouching(m, range);
});
Expand Down Expand Up @@ -411,7 +411,7 @@ export interface CodeActionProvider {
/**
* Provide commands for the given document and range.
*/
provideCodeActions(model: editorCommon.IReadOnlyModel, range: Range, context: CodeActionContext, token: CancellationToken): modes.Command[] | Thenable<modes.Command[]>;
provideCodeActions(model: editorCommon.IReadOnlyModel, range: Range, context: CodeActionContext, token: CancellationToken): modes.CodeAction[] | Thenable<modes.CodeAction[]>;
}

/**
Expand Down Expand Up @@ -738,6 +738,6 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages {
DocumentHighlightKind: modes.DocumentHighlightKind,
CompletionItemKind: CompletionItemKind,
SymbolKind: modes.SymbolKind,
IndentAction: IndentAction,
IndentAction: IndentAction
};
}
6 changes: 5 additions & 1 deletion src/vs/monaco.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4065,7 +4065,7 @@ declare module monaco.languages {
/**
* Provide commands for the given document and range.
*/
provideCodeActions(model: editor.IReadOnlyModel, range: Range, context: CodeActionContext, token: CancellationToken): Command[] | Thenable<Command[]>;
provideCodeActions(model: editor.IReadOnlyModel, range: Range, context: CodeActionContext, token: CancellationToken): CodeAction[] | Thenable<CodeAction[]>;
}

/**
Expand Down Expand Up @@ -4859,6 +4859,10 @@ declare module monaco.languages {
arguments?: any[];
}

export interface CodeAction extends Command {
dontTriggerLightBulb?: boolean;
}

export interface ICodeLensSymbol {
range: IRange;
id?: string;
Expand Down
12 changes: 11 additions & 1 deletion src/vs/vscode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,16 @@ declare module 'vscode' {
readonly diagnostics: Diagnostic[];
}

/**
* A code action for the [light bulb](https://code.visualstudio.com/docs/editor/editingevolved#_code-action) feature.
*/
export interface CodeAction extends Command {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a CodeAction type is also something we may want to consider for #33049

/**
* Should the lightbulb automatically be shown in the UI?
*/
dontTriggerLightBulb?: boolean;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a boolean, I also considered using a enum for when the lightbulb should be shown or not. For example, base on #33441, it may be expected that the lightbulb is shown when the user has a selection but not when the selection is empty

}

/**
* The code action interface defines the contract between extensions and
* the [light bulb](https://code.visualstudio.com/docs/editor/editingevolved#_code-action) feature.
Expand All @@ -1682,7 +1692,7 @@ declare module 'vscode' {
* @return An array of commands or a thenable of such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): ProviderResult<Command[]>;
provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): ProviderResult<CodeAction[]>;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha

$registerQuickFixSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
this._registrations[handle] = modes.CodeActionProviderRegistry.register(selector, <modes.CodeActionProvider>{
provideCodeActions: (model: IReadOnlyModel, range: EditorRange, token: CancellationToken): Thenable<modes.Command[]> => {
provideCodeActions: (model: IReadOnlyModel, range: EditorRange, token: CancellationToken): Thenable<modes.CodeAction[]> => {
return this._heapService.trackRecursive(wireCancellationToken(token, this._proxy.$provideCodeActions(handle, model.uri, range)));
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/node/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideHover(handle: number, resource: URI, position: IPosition): TPromise<modes.Hover>;
$provideDocumentHighlights(handle: number, resource: URI, position: IPosition): TPromise<modes.DocumentHighlight[]>;
$provideReferences(handle: number, resource: URI, position: IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]>;
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.Command[]>;
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.CodeAction[]>;
$provideDocumentFormattingEdits(handle: number, resource: URI, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
$provideDocumentRangeFormattingEdits(handle: number, resource: URI, range: IRange, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
$provideOnTypeFormattingEdits(handle: number, resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
Expand Down
14 changes: 9 additions & 5 deletions src/vs/workbench/api/node/extHostLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class QuickFixAdapter {
this._provider = provider;
}

provideCodeActions(resource: URI, range: IRange): TPromise<modes.Command[]> {
provideCodeActions(resource: URI, range: IRange): TPromise<modes.CodeAction[]> {

const doc = this._documents.getDocumentData(resource).document;
const ran = TypeConverters.toRange(range);
Expand All @@ -296,11 +296,15 @@ class QuickFixAdapter {
}
});

return asWinJsPromise(token => this._provider.provideCodeActions(doc, ran, { diagnostics: allDiagnostics }, token)).then(commands => {
if (!Array.isArray(commands)) {
return asWinJsPromise(token => this._provider.provideCodeActions(doc, ran, { diagnostics: allDiagnostics }, token)).then(actions => {
if (!Array.isArray(actions)) {
return undefined;
}
return commands.map(command => this._commands.toInternal(command));
return actions.map(action => {
const a: modes.CodeAction = this._commands.toInternal(action as vscode.Command);
a.dontTriggerLightBulb = action.dontTriggerLightBulb;
return a;
});
});
}
}
Expand Down Expand Up @@ -921,7 +925,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}

$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.Command[]> {
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.CodeAction[]> {
return this._withAdapter(handle, QuickFixAdapter, adapter => adapter.provideCodeActions(resource, range));
}

Expand Down