Skip to content

Commit fe0a81a

Browse files
Merge pull request #43 from tintoy/feature/language-client
Initial port of LSP client from tintoy/dotnet-language-client.
2 parents 772397d + c87fd85 commit fe0a81a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+5307
-3
lines changed

LSP.sln

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26403.7
3+
VisualStudioVersion = 15.0.26730.16
54
MinimumVisualStudioVersion = 10.0.40219.1
65
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D764E024-3D3F-4112-B932-2DB722A1BACC}"
76
EndProject
@@ -28,36 +27,108 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonRpc.Tests", "test\JsonR
2827
EndProject
2928
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lsp.Tests", "test\Lsp.Tests\Lsp.Tests.csproj", "{482B180B-FD5C-4705-BBE1-094C905F1E1F}"
3029
EndProject
31-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleServer", "sample\SampleServer\SampleServer.csproj", "{F2067F5F-FA4E-4990-B301-E7898FC4C45F}"
30+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleServer", "sample\SampleServer\SampleServer.csproj", "{F2067F5F-FA4E-4990-B301-E7898FC4C45F}"
3231
EndProject
3332
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{A316FCEC-81AD-45FB-93EE-C62CA09300DC}"
3433
EndProject
34+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "src\Client\Client.csproj", "{417E95B2-5AB9-49D5-B7CD-12255472E2E7}"
35+
EndProject
36+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client.Tests", "test\Client.Tests\Client.Tests.csproj", "{97437BE1-2EC3-4F6B-AC75-C3E099040A07}"
37+
EndProject
3538
Global
3639
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3740
Debug|Any CPU = Debug|Any CPU
41+
Debug|x64 = Debug|x64
42+
Debug|x86 = Debug|x86
3843
Release|Any CPU = Release|Any CPU
44+
Release|x64 = Release|x64
45+
Release|x86 = Release|x86
3946
EndGlobalSection
4047
GlobalSection(ProjectConfigurationPlatforms) = postSolution
4148
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4249
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Debug|x64.ActiveCfg = Debug|Any CPU
51+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Debug|x64.Build.0 = Debug|Any CPU
52+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Debug|x86.ActiveCfg = Debug|Any CPU
53+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Debug|x86.Build.0 = Debug|Any CPU
4354
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
4455
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Release|x64.ActiveCfg = Release|Any CPU
57+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Release|x64.Build.0 = Release|Any CPU
58+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Release|x86.ActiveCfg = Release|Any CPU
59+
{9AF43FA2-EF35-435E-B59E-724877E44DDA}.Release|x86.Build.0 = Release|Any CPU
4560
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4661
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Debug|x64.ActiveCfg = Debug|Any CPU
63+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Debug|x64.Build.0 = Debug|Any CPU
64+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Debug|x86.ActiveCfg = Debug|Any CPU
65+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Debug|x86.Build.0 = Debug|Any CPU
4766
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
4867
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Release|x64.ActiveCfg = Release|Any CPU
69+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Release|x64.Build.0 = Release|Any CPU
70+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Release|x86.ActiveCfg = Release|Any CPU
71+
{50EA648A-67D3-4127-9517-EC7C1426E2E7}.Release|x86.Build.0 = Release|Any CPU
4972
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
5073
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
74+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Debug|x64.ActiveCfg = Debug|Any CPU
75+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Debug|x64.Build.0 = Debug|Any CPU
76+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Debug|x86.ActiveCfg = Debug|Any CPU
77+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Debug|x86.Build.0 = Debug|Any CPU
5178
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
5279
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Release|Any CPU.Build.0 = Release|Any CPU
80+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Release|x64.ActiveCfg = Release|Any CPU
81+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Release|x64.Build.0 = Release|Any CPU
82+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Release|x86.ActiveCfg = Release|Any CPU
83+
{35F9B883-36D0-4F3B-A191-9BBD05B798A7}.Release|x86.Build.0 = Release|Any CPU
5384
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
5485
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
86+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Debug|x64.ActiveCfg = Debug|Any CPU
87+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Debug|x64.Build.0 = Debug|Any CPU
88+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Debug|x86.ActiveCfg = Debug|Any CPU
89+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Debug|x86.Build.0 = Debug|Any CPU
5590
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
5691
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Release|Any CPU.Build.0 = Release|Any CPU
92+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Release|x64.ActiveCfg = Release|Any CPU
93+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Release|x64.Build.0 = Release|Any CPU
94+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Release|x86.ActiveCfg = Release|Any CPU
95+
{482B180B-FD5C-4705-BBE1-094C905F1E1F}.Release|x86.Build.0 = Release|Any CPU
5796
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
5897
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Debug|Any CPU.Build.0 = Debug|Any CPU
98+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Debug|x64.ActiveCfg = Debug|Any CPU
99+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Debug|x64.Build.0 = Debug|Any CPU
100+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Debug|x86.ActiveCfg = Debug|Any CPU
101+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Debug|x86.Build.0 = Debug|Any CPU
59102
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Release|Any CPU.ActiveCfg = Release|Any CPU
60103
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Release|Any CPU.Build.0 = Release|Any CPU
104+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Release|x64.ActiveCfg = Release|Any CPU
105+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Release|x64.Build.0 = Release|Any CPU
106+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Release|x86.ActiveCfg = Release|Any CPU
107+
{F2067F5F-FA4E-4990-B301-E7898FC4C45F}.Release|x86.Build.0 = Release|Any CPU
108+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
109+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
110+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Debug|x64.ActiveCfg = Debug|Any CPU
111+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Debug|x64.Build.0 = Debug|Any CPU
112+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Debug|x86.ActiveCfg = Debug|Any CPU
113+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Debug|x86.Build.0 = Debug|Any CPU
114+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
115+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Release|Any CPU.Build.0 = Release|Any CPU
116+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Release|x64.ActiveCfg = Release|Any CPU
117+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Release|x64.Build.0 = Release|Any CPU
118+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Release|x86.ActiveCfg = Release|Any CPU
119+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7}.Release|x86.Build.0 = Release|Any CPU
120+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
121+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
122+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Debug|x64.ActiveCfg = Debug|Any CPU
123+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Debug|x64.Build.0 = Debug|Any CPU
124+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Debug|x86.ActiveCfg = Debug|Any CPU
125+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Debug|x86.Build.0 = Debug|Any CPU
126+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
127+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Release|Any CPU.Build.0 = Release|Any CPU
128+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Release|x64.ActiveCfg = Release|Any CPU
129+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Release|x64.Build.0 = Release|Any CPU
130+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Release|x86.ActiveCfg = Release|Any CPU
131+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07}.Release|x86.Build.0 = Release|Any CPU
61132
EndGlobalSection
62133
GlobalSection(SolutionProperties) = preSolution
63134
HideSolutionNode = FALSE
@@ -68,5 +139,10 @@ Global
68139
{35F9B883-36D0-4F3B-A191-9BBD05B798A7} = {2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}
69140
{482B180B-FD5C-4705-BBE1-094C905F1E1F} = {2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}
70141
{F2067F5F-FA4E-4990-B301-E7898FC4C45F} = {A316FCEC-81AD-45FB-93EE-C62CA09300DC}
142+
{417E95B2-5AB9-49D5-B7CD-12255472E2E7} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
143+
{97437BE1-2EC3-4F6B-AC75-C3E099040A07} = {2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}
144+
EndGlobalSection
145+
GlobalSection(ExtensibilityGlobals) = postSolution
146+
SolutionGuid = {D38DD0EC-D095-4BCD-B8AF-2D788AF3B9AE}
71147
EndGlobalSection
72148
EndGlobal

src/Client/Client.csproj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0</TargetFrameworks>
5+
<PlatformTarget>AnyCPU</PlatformTarget>
6+
<AssemblyName>OmniSharp.Extensions.LanguageClient</AssemblyName>
7+
<RootNamespace>OmniSharp.Extensions.LanguageServerProtocol.Client</RootNamespace>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.0.2" />
12+
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
13+
<PackageReference Include="System.Reactive" Version="3.1.1" />
14+
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\JsonRpc\JsonRpc.csproj" />
19+
<ProjectReference Include="..\Lsp\Lsp.csproj" />
20+
</ItemGroup>
21+
</Project>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using OmniSharp.Extensions.LanguageServer.Models;
2+
using OmniSharp.Extensions.LanguageServerProtocol.Client.Utilities;
3+
using System;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace OmniSharp.Extensions.LanguageServerProtocol.Client.Clients
8+
{
9+
/// <summary>
10+
/// Client for the LSP Text Document API.
11+
/// </summary>
12+
public partial class TextDocumentClient
13+
{
14+
/// <summary>
15+
/// Request completions at the specified document position.
16+
/// </summary>
17+
/// <param name="filePath">
18+
/// The full file-system path of the text document.
19+
/// </param>
20+
/// <param name="line">
21+
/// The target line (0-based).
22+
/// </param>
23+
/// <param name="column">
24+
/// The target column (0-based).
25+
/// </param>
26+
/// <param name="cancellationToken">
27+
/// An optional <see cref="CancellationToken"/> that can be used to cancel the request.
28+
/// </param>
29+
/// <returns>
30+
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no completions are available at the specified position.
31+
/// </returns>
32+
public Task<CompletionList> Completions(string filePath, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
33+
{
34+
if (String.IsNullOrWhiteSpace(filePath))
35+
throw new ArgumentException($"Argument cannot be null, empty, or entirely composed of whitespace: {nameof(filePath)}.", nameof(filePath));
36+
37+
Uri documentUri = DocumentUri.FromFileSystemPath(filePath);
38+
39+
return Completions(documentUri, line, column, cancellationToken);
40+
}
41+
42+
/// <summary>
43+
/// Request completions at the specified document position.
44+
/// </summary>
45+
/// <param name="documentUri">
46+
/// The document URI.
47+
/// </param>
48+
/// <param name="line">
49+
/// The target line (0-based).
50+
/// </param>
51+
/// <param name="column">
52+
/// The target column (0-based).
53+
/// </param>
54+
/// <param name="cancellationToken">
55+
/// An optional <see cref="CancellationToken"/> that can be used to cancel the request.
56+
/// </param>
57+
/// <returns>
58+
/// A <see cref="Task{TResult}"/> that resolves to the completions or <c>null</c> if no completions are available at the specified position.
59+
/// </returns>
60+
public Task<CompletionList> Completions(Uri documentUri, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
61+
{
62+
return PositionalRequest<CompletionList>("textDocument/completion", documentUri, line, column, cancellationToken);
63+
}
64+
}
65+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using OmniSharp.Extensions.LanguageServer.Models;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace OmniSharp.Extensions.LanguageServerProtocol.Client.Clients
9+
{
10+
/// <summary>
11+
/// Client for the LSP Text Document API.
12+
/// </summary>
13+
public partial class TextDocumentClient
14+
{
15+
/// <summary>
16+
/// Register a handler for diagnostics published by the language server.
17+
/// </summary>
18+
/// <param name="handler">
19+
/// A <see cref="PublishDiagnosticsHandler"/> that is called to publish the diagnostics.
20+
/// </param>
21+
/// <returns>
22+
/// An <see cref="IDisposable"/> representing the registration.
23+
/// </returns>
24+
/// <remarks>
25+
/// The diagnostics should replace any previously published diagnostics for the specified document.
26+
/// </remarks>
27+
public IDisposable OnPublishDiagnostics(PublishDiagnosticsHandler handler)
28+
{
29+
if (handler == null)
30+
throw new ArgumentNullException(nameof(handler));
31+
32+
return Client.HandleNotification<PublishDiagnosticsParams>("textDocument/publishDiagnostics", notification =>
33+
{
34+
if (notification.Diagnostics == null)
35+
return; // Invalid notification.
36+
37+
List<Diagnostic> diagnostics = new List<Diagnostic>();
38+
if (notification.Diagnostics != null)
39+
diagnostics.AddRange(notification.Diagnostics);
40+
41+
handler(notification.Uri, diagnostics);
42+
});
43+
}
44+
}
45+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using OmniSharp.Extensions.LanguageServer.Models;
2+
using System;
3+
using System.IO;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using OmniSharp.Extensions.LanguageServerProtocol.Client.Utilities;
7+
8+
namespace OmniSharp.Extensions.LanguageServerProtocol.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 hover information 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 hover information or <c>null</c> if no hover information is available at the specified position.
32+
/// </returns>
33+
public Task<Hover> Hover(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: 'filePath'.", nameof(filePath));
37+
38+
Uri documentUri = DocumentUri.FromFileSystemPath(filePath);
39+
40+
return Hover(documentUri, line, column, cancellationToken);
41+
}
42+
43+
/// <summary>
44+
/// Request hover information 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 hover information or <c>null</c> if no hover information is available at the specified position.
60+
/// </returns>
61+
public Task<Hover> Hover(Uri documentUri, int line, int column, CancellationToken cancellationToken = default(CancellationToken))
62+
{
63+
return PositionalRequest<Hover>("textDocument/hover", documentUri, line, column, cancellationToken);
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)