Skip to content

Commit e7fdd68

Browse files
committed
Added DocumentHighlight support to TextDocumentClient.
1 parent e3d108f commit e7fdd68

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

src/Client/Clients/TextDocumentClient.Definition.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public partial class TextDocumentClient
2828
/// An optional <see cref="CancellationToken"/> that can be used to cancel the request.
2929
/// </param>
3030
/// <returns>
31-
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no completions are available at the specified position.
31+
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no definitions are available at the specified position.
3232
/// </returns>
3333
public Task<LocationOrLocationLinks> Definition(string filePath, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
3434
{
@@ -56,7 +56,7 @@ public partial class TextDocumentClient
5656
/// An optional <see cref="CancellationToken"/> that can be used to cancel the request.
5757
/// </param>
5858
/// <returns>
59-
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no completions are available at the specified position.
59+
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no definitions are available at the specified position.
6060
/// </returns>
6161
public Task<LocationOrLocationLinks> Definition(Uri documentUri, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
6262
{
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using OmniSharp.Extensions.LanguageServer.Client.Utilities;
5+
using OmniSharp.Extensions.LanguageServer.Protocol;
6+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
7+
8+
namespace OmniSharp.Extensions.LanguageServer.Client.Clients
9+
{
10+
/// <summary>
11+
/// Client for the LSP Text Document API.
12+
/// </summary>
13+
public partial class TextDocumentClient
14+
{
15+
/// <summary>
16+
/// Request document highlights at the specified document position.
17+
/// </summary>
18+
/// <param name="filePath">
19+
/// The full file-system path of the text document.
20+
/// </param>
21+
/// <param name="line">
22+
/// The target line (0-based).
23+
/// </param>
24+
/// <param name="column">
25+
/// The target column (0-based).
26+
/// </param>
27+
/// <param name="cancellationToken">
28+
/// An optional <see cref="CancellationToken"/> that can be used to cancel the request.
29+
/// </param>
30+
/// <returns>
31+
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no document highlights are available at the specified position.
32+
/// </returns>
33+
public Task<DocumentHighlightContainer> DocumentHighlight(string filePath, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
34+
{
35+
if (string.IsNullOrWhiteSpace(filePath))
36+
throw new ArgumentException($"Argument cannot be null, empty, or entirely composed of whitespace: {nameof(filePath)}.", nameof(filePath));
37+
38+
var documentUri = DocumentUri.FromFileSystemPath(filePath);
39+
40+
return DocumentHighlight(documentUri, line, column, cancellationToken);
41+
}
42+
43+
/// <summary>
44+
/// Request document highlights at the specified document position.
45+
/// </summary>
46+
/// <param name="documentUri">
47+
/// The document URI.
48+
/// </param>
49+
/// <param name="line">
50+
/// The target line (0-based).
51+
/// </param>
52+
/// <param name="column">
53+
/// The target column (0-based).
54+
/// </param>
55+
/// <param name="cancellationToken">
56+
/// An optional <see cref="CancellationToken"/> that can be used to cancel the request.
57+
/// </param>
58+
/// <returns>
59+
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no document highlights are available at the specified position.
60+
/// </returns>
61+
public Task<DocumentHighlightContainer> DocumentHighlight(Uri documentUri, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
62+
{
63+
return PositionalRequest<DocumentHighlightContainer>(DocumentNames.DocumentHighlight, documentUri, line, column, cancellationToken);
64+
}
65+
}
66+
}

test/Client.Tests/ClientTests.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ public async Task Definition_Success()
301301

302302
var actualDefinitions = definitions.ToArray();
303303
Assert.Collection(actualDefinitions, actualDefinition => {
304-
var expectedDefinition = expectedDefinitions.First();
304+
var expectedDefinition = expectedDefinitions.Single();
305305

306306
Assert.NotNull(actualDefinition.Location);
307307
Assert.Equal(expectedDefinition.Location.Uri, actualDefinition.Location.Uri);
@@ -316,6 +316,63 @@ public async Task Definition_Success()
316316
});
317317
}
318318

319+
/// <summary>
320+
/// Ensure that the language client can successfully request DocumentHighlight.
321+
/// </summary>
322+
[Fact(DisplayName = "Language client can successfully request document highlights", Skip = "Periodic failures")]
323+
public async Task DocumentHighlight_Success()
324+
{
325+
await Connect();
326+
327+
const int line = 5;
328+
const int column = 5;
329+
var expectedDocumentPath = AbsoluteDocumentPath;
330+
var expectedDocumentUri = DocumentUri.FromFileSystemPath(expectedDocumentPath);
331+
332+
var expectedHighlights = new DocumentHighlightContainer(
333+
new DocumentHighlight {
334+
Kind = DocumentHighlightKind.Write,
335+
Range = new Range {
336+
Start = new Position {
337+
Line = line,
338+
Character = column
339+
},
340+
End = new Position {
341+
Line = line,
342+
Character = column
343+
}
344+
},
345+
});
346+
347+
ServerDispatcher.HandleRequest<DocumentHighlightParams, DocumentHighlightContainer>(DocumentNames.DocumentHighlight, (request, cancellationToken) => {
348+
Assert.NotNull(request.TextDocument);
349+
350+
Assert.Equal(expectedDocumentUri, request.TextDocument.Uri);
351+
352+
Assert.Equal(line, request.Position.Line);
353+
Assert.Equal(column, request.Position.Character);
354+
355+
return Task.FromResult(expectedHighlights);
356+
});
357+
358+
var definitions = await LanguageClient.TextDocument.DocumentHighlight(AbsoluteDocumentPath, line, column);
359+
360+
var actualDefinitions = definitions.ToArray();
361+
Assert.Collection(actualDefinitions, actualHighlight => {
362+
var expectedHighlight = expectedHighlights.Single();
363+
364+
Assert.Equal(DocumentHighlightKind.Write, expectedHighlight.Kind);
365+
366+
Assert.NotNull(actualHighlight.Range);
367+
Assert.NotNull(actualHighlight.Range.Start);
368+
Assert.NotNull(actualHighlight.Range.End);
369+
Assert.Equal(expectedHighlight.Range.Start.Line, actualHighlight.Range.Start.Line);
370+
Assert.Equal(expectedHighlight.Range.Start.Character, actualHighlight.Range.Start.Character);
371+
Assert.Equal(expectedHighlight.Range.End.Line, actualHighlight.Range.End.Line);
372+
Assert.Equal(expectedHighlight.Range.End.Character, actualHighlight.Range.End.Character);
373+
});
374+
}
375+
319376
/// <summary>
320377
/// Ensure that the language client can successfully receive Diagnostics from the server.
321378
/// </summary>

0 commit comments

Comments
 (0)