Skip to content

Commit 1cf726f

Browse files
authored
Merge pull request #5177 from JoeRobich/add-inlayhint-textedit
Add support for InlayHint.TextEdits
2 parents 9981d44 + a149662 commit 1cf726f

File tree

9 files changed

+71
-32
lines changed

9 files changed

+71
-32
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
gulp test
4545
npm run test:artifacts
4646
env:
47-
CODE_VERSION: 1.65.0
47+
CODE_VERSION: 1.66.0
4848
DISPLAY: :99.0
4949

5050
- name: Build platform-specific extension package

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* coreclr debug configuration should support input variables for envFile ([#5102](https://github.com/OmniSharp/omnisharp-vscode/issues/5102), PR: [#5189](https://github.com/OmniSharp/omnisharp-vscode/pull/5189))
2222
* Fix small spelling mistake (PR: [#5215](https://github.com/OmniSharp/omnisharp-vscode/pull/5215))
2323
* Low-hanging nullable fruit (PR: [#5186](https://github.com/OmniSharp/omnisharp-vscode/pull/5186))
24+
* Fire a buffer update instead of filechanged when active editor changes ([#5216](https://github.com/OmniSharp/omnisharp-vscode/issues/5216), PR: [#5218](https://github.com/OmniSharp/omnisharp-vscode/pull/5218))
25+
* Add support for InlayHint.TextEdits (PR: [#5177](https://github.com/OmniSharp/omnisharp-vscode/pull/5177))
2426
* Fix .net6 OmniSharp acquisition on Linux arm64 (PR: [#5172](https://github.com/OmniSharp/omnisharp-vscode/pull/5172))
2527
* Remove project.json reference in debugger.md (PR: [#5210](https://github.com/OmniSharp/omnisharp-vscode/pull/5210))
2628
* Update debugger to 1.24.5 (PR: [#5211](https://github.com/OmniSharp/omnisharp-vscode/pull/5211))

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ See issue [#5120](https://github.com/OmniSharp/omnisharp-vscode/issues/5120) for
3333
* coreclr debug configuration should support input variables for envFile ([#5102](https://github.com/OmniSharp/omnisharp-vscode/issues/5102), PR: [#5189](https://github.com/OmniSharp/omnisharp-vscode/pull/5189))
3434
* Fix small spelling mistake (PR: [#5215](https://github.com/OmniSharp/omnisharp-vscode/pull/5215))
3535
* Low-hanging nullable fruit (PR: [#5186](https://github.com/OmniSharp/omnisharp-vscode/pull/5186))
36+
* Fire a buffer update instead of filechanged when active editor changes ([#5216](https://github.com/OmniSharp/omnisharp-vscode/issues/5216), PR: [#5218](https://github.com/OmniSharp/omnisharp-vscode/pull/5218))
37+
* Add support for InlayHint.TextEdits (PR: [#5177](https://github.com/OmniSharp/omnisharp-vscode/pull/5177))
3638
* Fix .net6 OmniSharp acquisition on Linux arm64 (PR: [#5172](https://github.com/OmniSharp/omnisharp-vscode/pull/5172))
3739
* Remove project.json reference in debugger.md (PR: [#5210](https://github.com/OmniSharp/omnisharp-vscode/pull/5210))
3840
* Update debugger to 1.24.5 (PR: [#5211](https://github.com/OmniSharp/omnisharp-vscode/pull/5211))

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
"@vscode/test-electron": "2.1.3",
101101
"archiver": "5.3.0",
@@ -576,7 +576,7 @@
576576
}
577577
],
578578
"engines": {
579-
"vscode": "^1.65.0"
579+
"vscode": "^1.66.0"
580580
},
581581
"activationEvents": [
582582
"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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ 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(toRange2(textChange), textChange.NewText);
67+
}
68+
6569
export function createRequest<T extends protocol.Request>(document: vscode.TextDocument, where: vscode.Position, includeBuffer: boolean = false): T {
6670
// for metadata sources, we need to remove the [metadata] from the filename, and prepend the $metadata$ authority
6771
// this is expected by the Omnisharp server to support metadata-to-metadata navigation

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)