//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//using Microsoft.PowerShell.EditorServices.Extensions;
using Microsoft.PowerShell.EditorServices.Protocol.LanguageServer;
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel;
using Microsoft.PowerShell.EditorServices.Session;
//using Microsoft.PowerShell.EditorServices.Utility;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
//using System.Management.Automation;
//using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using DebugAdapterMessages = Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter;
namespace Microsoft.PowerShell.EditorServices.Protocol.Server
{
public class LanguageServer : LanguageServerBase
{
// private static CancellationTokenSource existingRequestCancellation;
// private bool profilesLoaded;
// private EditorSession editorSession;
// private OutputDebouncer outputDebouncer;
// private LanguageServerEditorOperations editorOperations;
// private LanguageServerSettings currentSettings = new LanguageServerSettings();
///
/// Provides details about the host application.
///
public LanguageServer(HostDetails hostDetails, ProfilePaths profilePaths)
: this(hostDetails, profilePaths, new StdioServerChannel())
{
}
///
/// Provides details about the host application.
///
public LanguageServer(HostDetails hostDetails, ProfilePaths profilePaths, ChannelBase serverChannel)
: base(serverChannel)
{
#if false
this.editorSession = new EditorSession();
this.editorSession.StartSession(hostDetails, profilePaths);
this.editorSession.ConsoleService.OutputWritten += this.powerShellContext_OutputWritten;
// Attach to ExtensionService events
this.editorSession.ExtensionService.CommandAdded += ExtensionService_ExtensionAdded;
this.editorSession.ExtensionService.CommandUpdated += ExtensionService_ExtensionUpdated;
this.editorSession.ExtensionService.CommandRemoved += ExtensionService_ExtensionRemoved;
// Create the IEditorOperations implementation
this.editorOperations =
new LanguageServerEditorOperations(
this.editorSession,
this);
// Always send console prompts through the UI in the language service
// TODO: This will change later once we have a general REPL available
// in VS Code.
this.editorSession.ConsoleService.PushPromptHandlerContext(
new ProtocolPromptHandlerContext(
this,
this.editorSession.ConsoleService));
// Set up the output debouncer to throttle output event writes
this.outputDebouncer = new OutputDebouncer(this);
#endif
}
protected async Task HandleInitializeRequest(
InitializeRequest initializeParams,
RequestContext requestContext)
{
// Grab the workspace path from the parameters
//editorSession.Workspace.WorkspacePath = initializeParams.RootPath;
await requestContext.SendResult(
new InitializeResult
{
Capabilities = new ServerCapabilities
{
TextDocumentSync = TextDocumentSyncKind.Incremental,
DefinitionProvider = true,
ReferencesProvider = true,
DocumentHighlightProvider = true,
DocumentSymbolProvider = true,
WorkspaceSymbolProvider = true,
HoverProvider = true,
CompletionProvider = new CompletionOptions
{
ResolveProvider = true,
TriggerCharacters = new string[] { ".", "-", ":", "\\" }
},
SignatureHelpProvider = new SignatureHelpOptions
{
TriggerCharacters = new string[] { " " } // TODO: Other characters here?
}
}
});
}
protected override void Initialize()
{
// Register all supported message types
this.SetRequestHandler(InitializeRequest.Type, this.HandleInitializeRequest);
// this.SetEventHandler(DidOpenTextDocumentNotification.Type, this.HandleDidOpenTextDocumentNotification);
// this.SetEventHandler(DidCloseTextDocumentNotification.Type, this.HandleDidCloseTextDocumentNotification);
// this.SetEventHandler(DidChangeTextDocumentNotification.Type, this.HandleDidChangeTextDocumentNotification);
// this.SetEventHandler(DidChangeConfigurationNotification.Type, this.HandleDidChangeConfigurationNotification);
// this.SetRequestHandler(DefinitionRequest.Type, this.HandleDefinitionRequest);
// this.SetRequestHandler(ReferencesRequest.Type, this.HandleReferencesRequest);
// this.SetRequestHandler(CompletionRequest.Type, this.HandleCompletionRequest);
// this.SetRequestHandler(CompletionResolveRequest.Type, this.HandleCompletionResolveRequest);
// this.SetRequestHandler(SignatureHelpRequest.Type, this.HandleSignatureHelpRequest);
// this.SetRequestHandler(DocumentHighlightRequest.Type, this.HandleDocumentHighlightRequest);
// this.SetRequestHandler(HoverRequest.Type, this.HandleHoverRequest);
// this.SetRequestHandler(DocumentSymbolRequest.Type, this.HandleDocumentSymbolRequest);
// this.SetRequestHandler(WorkspaceSymbolRequest.Type, this.HandleWorkspaceSymbolRequest);
// this.SetRequestHandler(ShowOnlineHelpRequest.Type, this.HandleShowOnlineHelpRequest);
// this.SetRequestHandler(ExpandAliasRequest.Type, this.HandleExpandAliasRequest);
// this.SetRequestHandler(FindModuleRequest.Type, this.HandleFindModuleRequest);
// this.SetRequestHandler(InstallModuleRequest.Type, this.HandleInstallModuleRequest);
// this.SetRequestHandler(InvokeExtensionCommandRequest.Type, this.HandleInvokeExtensionCommandRequest);
// this.SetRequestHandler(DebugAdapterMessages.EvaluateRequest.Type, this.HandleEvaluateRequest);
#if false
// Initialize the extension service
// TODO: This should be made awaited once Initialize is async!
this.editorSession.ExtensionService.Initialize(
this.editorOperations).Wait();
#endif
}
#if false
protected override async Task Shutdown()
{
// Make sure remaining output is flushed before exiting
await this.outputDebouncer.Flush();
//Logger.Write(LogLevel.Normal, "Language service is shutting down...");
if (this.editorSession != null)
{
this.editorSession.Dispose();
this.editorSession = null;
}
}
#region Built-in Message Handlers
protected async Task HandleInitializeRequest(
InitializeRequest initializeParams,
RequestContext requestContext)
{
// Grab the workspace path from the parameters
//editorSession.Workspace.WorkspacePath = initializeParams.RootPath;
await requestContext.SendResult(
new InitializeResult
{
Capabilities = new ServerCapabilities
{
TextDocumentSync = TextDocumentSyncKind.Incremental,
DefinitionProvider = true,
ReferencesProvider = true,
DocumentHighlightProvider = true,
DocumentSymbolProvider = true,
WorkspaceSymbolProvider = true,
HoverProvider = true,
CompletionProvider = new CompletionOptions
{
ResolveProvider = true,
TriggerCharacters = new string[] { ".", "-", ":", "\\" }
},
SignatureHelpProvider = new SignatureHelpOptions
{
TriggerCharacters = new string[] { " " } // TODO: Other characters here?
}
}
});
}
protected async Task HandleShowOnlineHelpRequest(
string helpParams,
RequestContext