Skip to content

Commit 729cc22

Browse files
committed
Add support for InlayHint.TextEdits
1 parent c7239d9 commit 729cc22

File tree

6 files changed

+72
-31
lines changed

6 files changed

+72
-31
lines changed

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
"@types/semver": "5.5.0",
9696
"@types/tmp": "0.0.33",
9797
"@types/unzipper": "^0.9.1",
98-
"@types/vscode": "1.65.0",
98+
"@types/vscode": "1.66.0",
9999
"@types/yauzl": "2.9.1",
100100
"archiver": "5.3.0",
101101
"chai": "4.3.4",
@@ -541,7 +541,7 @@
541541
}
542542
],
543543
"engines": {
544-
"vscode": "^1.65.0"
544+
"vscode": "^1.66.0"
545545
},
546546
"activationEvents": [
547547
"onDebugInitialConfigurations",

src/features/inlayHintProvider.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import AbstractProvider from './abstractProvider';
88
import { OmniSharpServer } from '../omnisharp/server';
99
import { LanguageMiddlewareFeature } from '../omnisharp/LanguageMiddlewareFeature';
1010
import CompositeDisposable from '../CompositeDisposable';
11-
import { InlayHint, InlayHintRequest, InlayHintResolve as InlayHintResolveRequest } from '../omnisharp/protocol';
12-
import { fromVSCodeRange, toVSCodePosition } from '../omnisharp/typeConversion';
11+
import { InlayHint, InlayHintRequest, InlayHintResolve as InlayHintResolveRequest, LinePositionSpanTextChange } from '../omnisharp/protocol';
12+
import { fromVSCodeRange, toVSCodePosition, toVSCodeTextEdit } from '../omnisharp/typeConversion';
1313
import { isVirtualCSharpDocument } from './virtualDocumentTracker';
1414

1515
export default class CSharpInlayHintProvider extends AbstractProvider implements vscode.InlayHintsProvider {
@@ -34,7 +34,7 @@ export default class CSharpInlayHintProvider extends AbstractProvider implements
3434
if (document.uri.scheme !== "file") {
3535
return [];
3636
}
37-
37+
3838
if (isVirtualCSharpDocument(document)) {
3939
return [];
4040
}
@@ -50,7 +50,7 @@ export default class CSharpInlayHintProvider extends AbstractProvider implements
5050
const hints = await serverUtils.getInlayHints(this._server, request, token);
5151

5252
return hints.InlayHints.map((inlayHint): vscode.InlayHint => {
53-
const mappedHint = this.toVscodeHint(inlayHint);
53+
const mappedHint = this.toVSCodeHint(inlayHint);
5454
this._hintsMap.set(mappedHint, inlayHint);
5555
return mappedHint;
5656
});
@@ -68,17 +68,22 @@ export default class CSharpInlayHintProvider extends AbstractProvider implements
6868

6969
try {
7070
const result = await serverUtils.resolveInlayHints(this._server, request, token);
71-
return this.toVscodeHint(result);
71+
return this.toVSCodeHint(result);
7272
} catch (error) {
7373
return Promise.reject(`Problem invoking 'ResolveInlayHints' on OmniSharpServer: ${error}`);
7474
}
7575
}
7676

77-
private toVscodeHint(inlayHint: InlayHint): vscode.InlayHint {
77+
private toVSCodeHint(inlayHint: InlayHint): vscode.InlayHint {
7878
return {
7979
label: inlayHint.Label,
8080
position: toVSCodePosition(inlayHint.Position),
81-
tooltip: new vscode.MarkdownString(inlayHint.Tooltip ?? "")
81+
tooltip: new vscode.MarkdownString(inlayHint.Tooltip ?? ""),
82+
textEdits: toVSCodeTextEdits(inlayHint.TextEdits),
8283
};
84+
85+
function toVSCodeTextEdits(textEdits: LinePositionSpanTextChange[]): vscode.TextEdit[] {
86+
return textEdits ? textEdits.map(toVSCodeTextEdit) : undefined;
87+
}
8388
}
8489
}

src/omnisharp/protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ export interface InlayHint {
592592
Label: string;
593593
Tooltip?: string;
594594
Data: any;
595+
TextEdits?: LinePositionSpanTextChange[];
595596
}
596597

597598
export interface InlayHintResponse {

src/omnisharp/typeConversion.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ export function toVSCodePosition(point: protocol.V2.Point): vscode.Position {
6262
return new vscode.Position(point.Line, point.Column);
6363
}
6464

65+
export function toVSCodeTextEdit(textChange: protocol.LinePositionSpanTextChange): vscode.TextEdit {
66+
return new vscode.TextEdit(toVSCodeRange(textChange), textChange.NewText);
67+
68+
function toVSCodeRange(textChange: protocol.LinePositionSpanTextChange): vscode.Range {
69+
const newStart = new vscode.Position(textChange.StartLine, textChange.StartColumn);
70+
const newEnd = new vscode.Position(textChange.EndLine, textChange.EndColumn);
71+
return new vscode.Range(newStart, newEnd);
72+
}
73+
}
74+
6575
export function createRequest<T extends protocol.Request>(document: vscode.TextDocument, where: vscode.Position | vscode.Range, includeBuffer: boolean = false): T {
6676

6777
let Line: number, Column: number;

test/integrationTests/inlayHints.integration.test.ts

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { should, assert } from 'chai';
99
import { activateCSharpExtension, isRazorWorkspace, isSlnWithGenerator, restartOmniSharpServer } from './integrationHelpers';
1010
import testAssetWorkspace from './testAssets/testAssetWorkspace';
1111
import * as path from 'path';
12+
import { InlayHint, LinePositionSpanTextChange } from '../../src/omnisharp/protocol';
1213

1314
const chai = require('chai');
1415
chai.use(require('chai-arrays'));
@@ -49,7 +50,7 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () {
4950
const projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath;
5051
const filePath = path.join(projectDirectory, fileName);
5152
fileUri = vscode.Uri.file(filePath);
52-
53+
5354
await vscode.commands.executeCommand("vscode.open", fileUri);
5455
await testAssetWorkspace.waitForIdle(activation.eventStream);
5556
});
@@ -60,19 +61,42 @@ suite(`Inlay Hints ${testAssetWorkspace.description}`, function () {
6061

6162
test("Hints retrieved for region", async () => {
6263
const range = new vscode.Range(new vscode.Position(4, 8), new vscode.Position(15, 85));
63-
const hints : vscode.InlayHint[] = await vscode.commands.executeCommand('vscode.executeInlayHintProvider', fileUri, range);
64+
const hints: vscode.InlayHint[] = await vscode.commands.executeCommand('vscode.executeInlayHintProvider', fileUri, range);
65+
6466
assert.lengthOf(hints, 6);
65-
assertValues(hints[0], 'InlayHints ', 6, 12);
66-
assertValues(hints[1], ' InlayHints', 7, 27);
67-
assertValues(hints[2], 'string ', 8, 28);
68-
assertValues(hints[3], 'i: ', 9, 17);
69-
assertValues(hints[4], 'param1: ', 10, 15);
70-
assertValues(hints[5], 'param1: ', 11, 27);
71-
72-
function assertValues(hint: vscode.InlayHint, expectedLabel: string, expectedLine: number, expectedCharacter: number) {
73-
assert.equal(hint.label, expectedLabel);
74-
assert.equal(hint.position.line, expectedLine);
75-
assert.equal(hint.position.character, expectedCharacter);
67+
68+
assertInlayHintEqual(hints[0], { Label: 'InlayHints ', Position: { Line: 6, Column: 12 }, Data: {}, TextEdits: [{ StartLine: 6, StartColumn: 8, EndLine: 6, EndColumn: 11, NewText: 'InlayHints' }] });
69+
assertInlayHintEqual(hints[1], { Label: ' InlayHints', Position: { Line: 7, Column: 27 }, Data: {}, TextEdits: [{ StartLine: 7, StartColumn: 27, EndLine: 7, EndColumn: 27, NewText: ' InlayHints' }] });
70+
assertInlayHintEqual(hints[2], { Label: 'string ', Position: { Line: 8, Column: 28 }, Data: {}, TextEdits: [{ StartLine: 8, StartColumn: 28, EndLine: 8, EndColumn: 28, NewText: 'string ' }] });
71+
assertInlayHintEqual(hints[3], { Label: 'i: ', Position: { Line: 9, Column: 17 }, Data: {}, TextEdits: [{ StartLine: 9, StartColumn: 17, EndLine: 9, EndColumn: 17, NewText: 'i: ' }] });
72+
assertInlayHintEqual(hints[4], { Label: 'param1: ', Position: { Line: 10, Column: 15 }, Data: {}, TextEdits: [{ StartLine: 10, StartColumn: 15, EndLine: 10, EndColumn: 15, NewText: 'param1: ' }] });
73+
assertInlayHintEqual(hints[5], { Label: 'param1: ', Position: { Line: 11, Column: 27 }, Data: {}, TextEdits: [{ StartLine: 11, StartColumn: 27, EndLine: 11, EndColumn: 27, NewText: 'param1: ' }] });
74+
75+
function assertInlayHintEqual(actual: vscode.InlayHint, expected: InlayHint) {
76+
assert.equal(actual.label, expected.Label);
77+
assert.equal(actual.position.line, expected.Position.Line);
78+
assert.equal(actual.position.character, expected.Position.Column);
79+
80+
if (!actual.textEdits) {
81+
assert.isUndefined(expected.TextEdits);
82+
return;
83+
}
84+
85+
assert.equal(actual.textEdits.length, expected.TextEdits.length);
86+
for (let i = 0; i < actual.textEdits.length; i++) {
87+
const actualTextEdit = actual.textEdits[i];
88+
const expectedTextEdit = expected.TextEdits[i];
89+
90+
assertTextEditEqual(actualTextEdit, expectedTextEdit);
91+
}
92+
}
93+
94+
function assertTextEditEqual(actual: vscode.TextEdit, expected: LinePositionSpanTextChange) {
95+
assert.equal(actual.range.start.line, expected.StartLine);
96+
assert.equal(actual.range.start.character, expected.StartColumn);
97+
assert.equal(actual.range.end.line, expected.EndLine);
98+
assert.equal(actual.range.end.character, expected.EndColumn);
99+
assert.equal(actual.newText, expected.NewText);
76100
}
77101
});
78102
});

0 commit comments

Comments
 (0)