Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSP: wire up handler for workspace/symbol #1799

Merged
merged 8 commits into from
Jun 15, 2020
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All changes to the project will be documented in this file.
## [1.35.3] - not yet released
* Added LSP handler for `textDocument/codeAction` request. (PR: [#1795](https://github.com/OmniSharp/omnisharp-roslyn/pull/1795))
* Expose a custom LSP `omnisharp/client/findReferences` command via code lens (meant to be handled by LSP client). (PR: [#1807](https://github.com/OmniSharp/omnisharp-roslyn/pull/1807))
* Added LSP handler for the `workspace/symbol` request. (PR: [#1799](https://github.com/OmniSharp/omnisharp-roslyn/pull/1799))

## [1.35.2] - 2020-05-20
* Added support for `WarningsAsErrors` in csproj files (PR: [#1779](https://github.com/OmniSharp/omnisharp-roslyn/pull/1779))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,6 @@ public static IEnumerable<IJsonRpcHandler> Enumerate(RequestHandlers handlers)

private readonly Mef.IRequestHandler<CodeStructureRequest, CodeStructureResponse> _codeStructureHandler;

private static readonly IDictionary<string, SymbolKind> Kinds = new Dictionary<string, SymbolKind>
{
{ OmniSharp.Models.V2.SymbolKinds.Class, SymbolKind.Class },
{ OmniSharp.Models.V2.SymbolKinds.Delegate, SymbolKind.Class },
{ OmniSharp.Models.V2.SymbolKinds.Enum, SymbolKind.Enum },
{ OmniSharp.Models.V2.SymbolKinds.Interface, SymbolKind.Interface },
{ OmniSharp.Models.V2.SymbolKinds.Struct, SymbolKind.Struct },
{ OmniSharp.Models.V2.SymbolKinds.Constant, SymbolKind.Constant },
{ OmniSharp.Models.V2.SymbolKinds.Destructor, SymbolKind.Method },
{ OmniSharp.Models.V2.SymbolKinds.EnumMember, SymbolKind.EnumMember },
{ OmniSharp.Models.V2.SymbolKinds.Event, SymbolKind.Event },
{ OmniSharp.Models.V2.SymbolKinds.Field, SymbolKind.Field },
{ OmniSharp.Models.V2.SymbolKinds.Indexer, SymbolKind.Property },
{ OmniSharp.Models.V2.SymbolKinds.Method, SymbolKind.Method },
{ OmniSharp.Models.V2.SymbolKinds.Operator, SymbolKind.Operator },
{ OmniSharp.Models.V2.SymbolKinds.Property, SymbolKind.Property },
{ OmniSharp.Models.V2.SymbolKinds.Namespace, SymbolKind.Namespace },
{ OmniSharp.Models.V2.SymbolKinds.Unknown, SymbolKind.Class },
};

public OmniSharpDocumentSymbolHandler(Mef.IRequestHandler<CodeStructureRequest, CodeStructureResponse> codeStructureHandler, DocumentSelector documentSelector)
: base(new TextDocumentRegistrationOptions()
{
Expand Down Expand Up @@ -76,7 +56,7 @@ private static DocumentSymbol ToDocumentSymbol(CodeElement node)
return new DocumentSymbol
{
Name = node.Name,
Kind = Kinds.ContainsKey(node.Kind) ? Kinds[node.Kind] : SymbolKind.Class,
Kind = Helpers.ToSymbolKind(node.Kind),
Range = Helpers.ToRange(node.Ranges[OmniSharp.Models.V2.SymbolRangeNames.Full]),
SelectionRange = Helpers.ToRange(node.Ranges[OmniSharp.Models.V2.SymbolRangeNames.Name]),
Children = new Container<DocumentSymbol>(node.Children?.Select(ToDocumentSymbol) ?? Enumerable.Empty<DocumentSymbol>())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
using OmniSharp.Mef;
using OmniSharp.Models;
using OmniSharp.Models.FindSymbols;

namespace OmniSharp.LanguageServerProtocol.Handlers
{
internal sealed class OmniSharpWorkspaceSymbolsHandler : WorkspaceSymbolsHandler
{
private readonly IRequestHandler<FindSymbolsRequest, QuickFixResponse> _FindSymbolsHandler;

public static IEnumerable<IJsonRpcHandler> Enumerate(RequestHandlers handlers)
{
foreach (var (selector, findSymbolsHandler) in handlers
.OfType<Mef.IRequestHandler<FindSymbolsRequest, QuickFixResponse>>())
{
//
// TODO: remove the conditional when we upgrade to v0.16.0 of Omnisharp.Extensions.LSP
//
// we have no WorkspaceSymbolRegistrationOptions/DocumentSelector until version 0.16.0 of Omnisharp.Extensions.LSP
// thus we artificially limit the handler to C# language for now
// (as Cake version of <FindSymbolsRequest,QuickFixResponse> would get selected otherwise)
//
if (selector.Any(f => f.Pattern == "**/*.cs"))
{
yield return new OmniSharpWorkspaceSymbolsHandler(findSymbolsHandler, selector);
}
}
}

public OmniSharpWorkspaceSymbolsHandler(
IRequestHandler<FindSymbolsRequest, QuickFixResponse> findSymbolsHandler,
DocumentSelector selector)
{
_FindSymbolsHandler = findSymbolsHandler;
}

public async override Task<SymbolInformationContainer>
Handle(WorkspaceSymbolParams request, CancellationToken cancellationToken)
{
var omnisharpRequest = new FindSymbolsRequest {
Filter = request.Query,
MaxItemsToReturn = 100,
};

var omnisharpResponse = await _FindSymbolsHandler.Handle(omnisharpRequest);

var symbols = omnisharpResponse.QuickFixes?.Cast<SymbolLocation>().Select(
x => new SymbolInformation {
Name = x.Text,
Kind = Helpers.ToSymbolKind(x.Kind),
Location = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Location {
Uri = Helpers.ToUri(x.FileName),
Range = Helpers.ToRange((x.Column, x.Line), (x.EndColumn, x.EndLine))
}
})
.ToArray();

return symbols ?? Array.Empty<SymbolInformation>();
}
}
}
26 changes: 26 additions & 0 deletions src/OmniSharp.LanguageServerProtocol/Helpers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Models;
Expand Down Expand Up @@ -143,5 +144,30 @@ public static string EscapeMarkdown(string markdown)
return null;
return Regex.Replace(markdown, @"([\\`\*_\{\}\[\]\(\)#+\-\.!])", @"\$1");
}

private static readonly IDictionary<string, SymbolKind> Kinds = new Dictionary<string, SymbolKind>
{
{ OmniSharp.Models.V2.SymbolKinds.Class, SymbolKind.Class },
{ OmniSharp.Models.V2.SymbolKinds.Delegate, SymbolKind.Class },
{ OmniSharp.Models.V2.SymbolKinds.Enum, SymbolKind.Enum },
{ OmniSharp.Models.V2.SymbolKinds.Interface, SymbolKind.Interface },
{ OmniSharp.Models.V2.SymbolKinds.Struct, SymbolKind.Struct },
{ OmniSharp.Models.V2.SymbolKinds.Constant, SymbolKind.Constant },
{ OmniSharp.Models.V2.SymbolKinds.Destructor, SymbolKind.Method },
{ OmniSharp.Models.V2.SymbolKinds.EnumMember, SymbolKind.EnumMember },
{ OmniSharp.Models.V2.SymbolKinds.Event, SymbolKind.Event },
{ OmniSharp.Models.V2.SymbolKinds.Field, SymbolKind.Field },
{ OmniSharp.Models.V2.SymbolKinds.Indexer, SymbolKind.Property },
{ OmniSharp.Models.V2.SymbolKinds.Method, SymbolKind.Method },
{ OmniSharp.Models.V2.SymbolKinds.Operator, SymbolKind.Operator },
{ OmniSharp.Models.V2.SymbolKinds.Property, SymbolKind.Property },
{ OmniSharp.Models.V2.SymbolKinds.Namespace, SymbolKind.Namespace },
{ OmniSharp.Models.V2.SymbolKinds.Unknown, SymbolKind.Class },
};

public static SymbolKind ToSymbolKind(string omnisharpKind)
{
return Kinds.TryGetValue(omnisharpKind.ToLowerInvariant(), out var symbolKind) ? symbolKind : SymbolKind.Class;
}
}
}
1 change: 1 addition & 0 deletions src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ private Task Initialize(Extensions.LanguageServer.Server.ILanguageServer server,
.Concat(OmniSharpCompletionHandler.Enumerate(_handlers))
.Concat(OmniSharpSignatureHelpHandler.Enumerate(_handlers))
.Concat(OmniSharpRenameHandler.Enumerate(_handlers))
.Concat(OmniSharpWorkspaceSymbolsHandler.Enumerate(_handlers))
.Concat(OmniSharpDocumentSymbolHandler.Enumerate(_handlers))
.Concat(OmniSharpReferencesHandler.Enumerate(_handlers))
.Concat(OmniSharpCodeLensHandler.Enumerate(_handlers))
Expand Down