Skip to content

Commit f82f553

Browse files
authored
Merge branch 'master' into fix-omnisharp-downloader-tests
2 parents a00c1b0 + 201a495 commit f82f553

File tree

4 files changed

+54
-66
lines changed

4 files changed

+54
-66
lines changed

package-lock.json

Lines changed: 19 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"vscode-debugprotocol": "1.33.0",
7676
"vscode-extension-telemetry": "0.1.6",
7777
"vscode-languageserver-protocol": "3.16.0",
78+
"vscode-nls": "^5.0.0",
7879
"yauzl": "2.10.0"
7980
},
8081
"devDependencies": {

src/features/codeActionProvider.ts

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,73 +13,47 @@ import OptionProvider from '../observers/OptionProvider';
1313
import { LanguageMiddlewareFeature } from '../omnisharp/LanguageMiddlewareFeature';
1414
import { buildEditForResponse } from '../omnisharp/fileOperationsResponseEditBuilder';
1515

16-
export default class CodeActionProvider extends AbstractProvider implements vscode.CodeActionProvider {
17-
16+
export default class CodeActionProvider extends AbstractProvider implements vscode.CodeActionProvider<vscode.CodeAction> {
1817
private _commandId: string;
1918

2019
constructor(server: OmniSharpServer, private optionProvider: OptionProvider, languageMiddlewareFeature: LanguageMiddlewareFeature) {
2120
super(server, languageMiddlewareFeature);
2221
this._commandId = 'omnisharp.runCodeAction';
23-
let registerCommandDisposable = vscode.commands.registerCommand(this._commandId, this._runCodeAction, this);
22+
const registerCommandDisposable = vscode.commands.registerCommand(this._commandId, this._runCodeAction, this);
2423
this.addDisposables(new CompositeDisposable(registerCommandDisposable));
2524
}
2625

27-
public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise<vscode.Command[]> {
28-
let options = this.optionProvider.GetLatestOptions();
26+
public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range | vscode.Selection, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise<vscode.CodeAction[]> {
27+
const options = this.optionProvider.GetLatestOptions();
2928
if (options.disableCodeActions) {
3029
return;
3130
}
3231

33-
let line: number;
34-
let column: number;
35-
let selection: protocol.V2.Range;
36-
37-
// VS Code will pass the range of the word at the editor caret, even if there isn't a selection.
38-
// To ensure that we don't suggest selection-based refactorings when there isn't a selection, we first
39-
// find the text editor for this document and verify that there is a selection.
40-
let editor = vscode.window.visibleTextEditors.find(e => e.document === document);
41-
if (editor) {
42-
if (editor.selection.isEmpty) {
43-
// The editor does not have a selection. Use the active position of the selection (i.e. the caret).
44-
let active = editor.selection.active;
32+
const line = range.start.line;
33+
const column = range.start.character;
4534

46-
line = active.line;
47-
column = active.character;
48-
}
49-
else {
50-
// The editor has a selection. Use it.
51-
let start = editor.selection.start;
52-
let end = editor.selection.end;
35+
const request: protocol.V2.GetCodeActionsRequest = {
36+
FileName: document.fileName,
37+
Line: line,
38+
Column: column,
39+
};
5340

54-
selection = {
55-
Start: { Line: start.line, Column: start.character },
56-
End: { Line: end.line, Column: end.character }
57-
};
58-
}
59-
}
60-
else {
61-
// We couldn't find the editor, so just use the range we were provided.
62-
selection = {
41+
// Only suggest selection-based refactorings when a selection exists.
42+
// If there is no selection and the editor isn't focused,
43+
// VS Code will pass us an empty Selection rather than a Range,
44+
// hence the extra range.isEmpty check.
45+
if (range instanceof vscode.Selection && !range.isEmpty) {
46+
request.Selection = {
6347
Start: { Line: range.start.line, Column: range.start.character },
6448
End: { Line: range.end.line, Column: range.end.character }
6549
};
6650
}
6751

68-
let request: protocol.V2.GetCodeActionsRequest = {
69-
FileName: document.fileName,
70-
Line: line,
71-
Column: column,
72-
Selection: selection
73-
};
74-
7552
try {
76-
let response = await serverUtils.getCodeActions(this._server, request, token);
53+
const response = await serverUtils.getCodeActions(this._server, request, token);
7754
return response.CodeActions.map(codeAction => {
78-
let runRequest: protocol.V2.RunCodeActionRequest = {
79-
FileName: document.fileName,
80-
Line: line,
81-
Column: column,
82-
Selection: selection,
55+
const runRequest: protocol.V2.RunCodeActionRequest = {
56+
...request,
8357
Identifier: codeAction.Identifier,
8458
WantsTextChanges: true,
8559
WantsAllCodeActionOperations: true,
@@ -88,24 +62,26 @@ export default class CodeActionProvider extends AbstractProvider implements vsco
8862

8963
return {
9064
title: codeAction.Name,
91-
command: this._commandId,
92-
arguments: [runRequest, token]
65+
command: {
66+
title: codeAction.Name,
67+
command: this._commandId,
68+
arguments: [runRequest, token]
69+
},
9370
};
9471
});
95-
}
96-
catch (error) {
72+
} catch (error) {
9773
return Promise.reject(`Problem invoking 'GetCodeActions' on OmniSharp server: ${error}`);
9874
}
9975
}
10076

10177
private async _runCodeAction(req: protocol.V2.RunCodeActionRequest, token: vscode.CancellationToken): Promise<boolean | string | {}> {
102-
103-
return serverUtils.runCodeAction(this._server, req).then(async response => {
78+
try {
79+
const response = await serverUtils.runCodeAction(this._server, req);
10480
if (response) {
10581
return buildEditForResponse(response.Changes, this._languageMiddlewareFeature, token);
10682
}
107-
}, async (error) => {
83+
} catch (error) {
10884
return Promise.reject(`Problem invoking 'RunCodeAction' on OmniSharp server: ${error}`);
109-
});
85+
}
11086
}
11187
}

test/integrationTests/codeActionRename.integration.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,11 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function () {
4040

4141
test("Code actions can rename and open files", async () => {
4242
await vscode.commands.executeCommand("vscode.open", fileUri);
43-
let c = await vscode.commands.executeCommand("vscode.executeCodeActionProvider", fileUri, new vscode.Range(0, 7, 0, 7)) as { command: string, title: string, arguments: string[] }[];
44-
let command = c.find(
45-
(s) => { return s.title == "Rename file to C.cs"; }
46-
);
47-
expect(command, "Didn't find rename class command");
43+
const codeActions = await vscode.commands.executeCommand<vscode.CodeAction[]>("vscode.executeCodeActionProvider", fileUri, new vscode.Range(0, 7, 0, 7));
44+
const codeAction = codeActions.find(codeAction => codeAction.title == "Rename file to C.cs");
45+
expect(codeAction, "Didn't find rename class code action");
4846

49-
await vscode.commands.executeCommand(command.command, ...command.arguments);
47+
await vscode.commands.executeCommand(codeAction.command.command, ...codeAction.command.arguments);
5048

5149
await assertWithPoll(() => { }, 15 * 1000, 500, _ => expect(vscode.window.activeTextEditor.document.fileName).contains("C.cs"));
5250
});

0 commit comments

Comments
 (0)