Skip to content

Add support for loading host profile scripts #199

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

Merged
merged 1 commit into from
Mar 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public class LanguageServerWebSocketConnection : EditorServiceWebSocketConnectio
{
public LanguageServerWebSocketConnection()
{
Server = new LanguageServer(Channel);
Server = new LanguageServer(null, Channel);
}
}

Expand All @@ -150,7 +150,7 @@ public class DebugAdapterWebSocketConnection : EditorServiceWebSocketConnection
{
public DebugAdapterWebSocketConnection()
{
Server = new DebugAdapter(Channel);
Server = new DebugAdapter(null, Channel);
}
}

Expand Down
77 changes: 65 additions & 12 deletions src/PowerShellEditorServices.Host/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
using Microsoft.PowerShell.EditorServices.Protocol.Server;
using Microsoft.PowerShell.EditorServices.Session;
using Microsoft.PowerShell.EditorServices.Utility;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace Microsoft.PowerShell.EditorServices.Host
{
Expand Down Expand Up @@ -78,21 +78,63 @@ static void Main(string[] args)
"/debugAdapter",
StringComparison.InvariantCultureIgnoreCase));

// Catch unhandled exceptions for logging purposes
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
string hostProfileId = null;
string hostProfileIdArgument =
args.FirstOrDefault(
arg =>
arg.StartsWith(
"/hostProfileId:",
StringComparison.InvariantCultureIgnoreCase));

if (!string.IsNullOrEmpty(hostProfileIdArgument))
{
hostProfileId = hostProfileIdArgument.Substring(15).Trim('"');
}

string hostName = null;
string hostNameArgument =
args.FirstOrDefault(
arg =>
arg.StartsWith(
"/hostName:",
StringComparison.InvariantCultureIgnoreCase));

ProtocolEndpoint server = null;
if (runDebugAdapter)
if (!string.IsNullOrEmpty(hostNameArgument))
{
logPath = logPath ?? "DebugAdapter.log";
server = new DebugAdapter();
hostName = hostNameArgument.Substring(10).Trim('"');
}
else

Version hostVersion = null;
string hostVersionArgument =
args.FirstOrDefault(
arg =>
arg.StartsWith(
"/hostVersion:",
StringComparison.InvariantCultureIgnoreCase));

if (!string.IsNullOrEmpty(hostVersionArgument))
{
logPath = logPath ?? "EditorServices.log";
server = new LanguageServer();
hostVersion =
new Version(
hostVersionArgument.Substring(13).Trim('"'));
}

// Create the host details from parameters
HostDetails hostDetails =
new HostDetails(
hostName,
hostProfileId,
hostVersion);

// Catch unhandled exceptions for logging purposes
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

// Use a default log path filename if one isn't specified
logPath =
runDebugAdapter
? logPath ?? "DebugAdapter.log"
: logPath ?? "EditorServices.log";

// Start the logger with the specified log path and level
Logger.Initialize(logPath, logLevel);

Expand All @@ -103,9 +145,20 @@ static void Main(string[] args)
Logger.Write(
LogLevel.Normal,
string.Format(
"PowerShell Editor Services Host v{0} starting (pid {1})...",
"PowerShell Editor Services Host v{0} starting (pid {1})...\r\n\r\n" +
" Host application details:\r\n\r\n" +
" Name: {2}\r\n ProfileId: {3}\r\n Version: {4}",
fileVersionInfo.FileVersion,
Process.GetCurrentProcess().Id));
Process.GetCurrentProcess().Id,
hostDetails.Name,
hostDetails.ProfileId,
hostDetails.Version));

// Create the appropriate server type
ProtocolEndpoint server =
runDebugAdapter
? (ProtocolEndpoint) new DebugAdapter(hostDetails)
: (ProtocolEndpoint) new LanguageServer(hostDetails);

// Start the server
server.Start().Wait();
Expand Down
9 changes: 6 additions & 3 deletions src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.PowerShell.EditorServices.Protocol.DebugAdapter;
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;
Expand All @@ -25,14 +26,16 @@ public class DebugAdapter : DebugAdapterBase
private string scriptPathToLaunch;
private string arguments;

public DebugAdapter() : this(new StdioServerChannel())
public DebugAdapter(HostDetails hostDetails)
: this(hostDetails, new StdioServerChannel())
{
}

public DebugAdapter(ChannelBase serverChannel) : base(serverChannel)
public DebugAdapter(HostDetails hostDetails, ChannelBase serverChannel)
: base(serverChannel)
{
this.editorSession = new EditorSession();
this.editorSession.StartSession();
this.editorSession.StartSession(hostDetails);
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
this.editorSession.ConsoleService.OutputWritten += this.powerShellContext_OutputWritten;

Expand Down
30 changes: 24 additions & 6 deletions src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using Microsoft.PowerShell.EditorServices.Protocol.LanguageServer;
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel;
using Microsoft.PowerShell.EditorServices.Protocol.Messages;
using Microsoft.PowerShell.EditorServices.Session;
using Microsoft.PowerShell.EditorServices.Utility;
using System;
using System.Collections.Generic;
Expand All @@ -24,18 +24,27 @@ public class LanguageServer : LanguageServerBase
{
private static CancellationTokenSource existingRequestCancellation;

private bool profilesLoaded;
private EditorSession editorSession;
private OutputDebouncer outputDebouncer;
private LanguageServerSettings currentSettings = new LanguageServerSettings();

public LanguageServer() : this(new StdioServerChannel())
/// <param name="hostDetails">
/// Provides details about the host application.
/// </param>
public LanguageServer(HostDetails hostDetails)
: this(hostDetails, new StdioServerChannel())
{
}

public LanguageServer(ChannelBase serverChannel) : base(serverChannel)
/// <param name="hostDetails">
/// Provides details about the host application.
/// </param>
public LanguageServer(HostDetails hostDetails, ChannelBase serverChannel)
: base(serverChannel)
{
this.editorSession = new EditorSession();
this.editorSession.StartSession();
this.editorSession.StartSession(hostDetails);
this.editorSession.ConsoleService.OutputWritten += this.powerShellContext_OutputWritten;

// Always send console prompts through the UI in the language service
Expand All @@ -59,7 +68,7 @@ protected override void Initialize()
this.SetEventHandler(DidOpenTextDocumentNotification.Type, this.HandleDidOpenTextDocumentNotification);
this.SetEventHandler(DidCloseTextDocumentNotification.Type, this.HandleDidCloseTextDocumentNotification);
this.SetEventHandler(DidChangeTextDocumentNotification.Type, this.HandleDidChangeTextDocumentNotification);
this.SetEventHandler(DidChangeConfigurationNotification<SettingsWrapper>.Type, this.HandleDidChangeConfigurationNotification);
this.SetEventHandler(DidChangeConfigurationNotification<LanguageServerSettingsWrapper>.Type, this.HandleDidChangeConfigurationNotification);

this.SetRequestHandler(DefinitionRequest.Type, this.HandleDefinitionRequest);
this.SetRequestHandler(ReferencesRequest.Type, this.HandleReferencesRequest);
Expand Down Expand Up @@ -287,15 +296,24 @@ protected Task HandleDidChangeTextDocumentNotification(
}

protected async Task HandleDidChangeConfigurationNotification(
DidChangeConfigurationParams<SettingsWrapper> configChangeParams,
DidChangeConfigurationParams<LanguageServerSettingsWrapper> configChangeParams,
EventContext eventContext)
{
bool oldLoadProfiles = this.currentSettings.EnableProfileLoading;
bool oldScriptAnalysisEnabled =
this.currentSettings.ScriptAnalysis.Enable.HasValue;

this.currentSettings.Update(
configChangeParams.Settings.Powershell);

if (!this.profilesLoaded &&
this.currentSettings.EnableProfileLoading &&
oldLoadProfiles != this.currentSettings.EnableProfileLoading)
{
await this.editorSession.PowerShellContext.LoadHostProfiles();
this.profilesLoaded = true;
}

if (oldScriptAnalysisEnabled != this.currentSettings.ScriptAnalysis.Enable)
{
// If the user just turned off script analysis, send a diagnostics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.Server
{
public class LanguageServerSettings
{
public bool EnableProfileLoading { get; set; }

public ScriptAnalysisSettings ScriptAnalysis { get; set; }

public LanguageServerSettings()
Expand All @@ -18,6 +20,7 @@ public void Update(LanguageServerSettings settings)
{
if (settings != null)
{
this.EnableProfileLoading = settings.EnableProfileLoading;
this.ScriptAnalysis.Update(settings.ScriptAnalysis);
}
}
Expand All @@ -41,7 +44,7 @@ public void Update(ScriptAnalysisSettings settings)
}
}

public class SettingsWrapper
public class LanguageServerSettingsWrapper
{
// NOTE: This property is capitalized as 'Powershell' because the
// mode name sent from the client is written as 'powershell' and
Expand Down
2 changes: 2 additions & 0 deletions src/PowerShellEditorServices/PowerShellEditorServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
<Compile Include="Console\ChoiceDetails.cs" />
<Compile Include="Session\EditorSession.cs" />
<Compile Include="Console\IConsoleHost.cs" />
<Compile Include="Session\HostDetails.cs" />
<Compile Include="Session\IVersionSpecificOperations.cs" />
<Compile Include="Session\OutputType.cs" />
<Compile Include="Session\OutputWrittenEventArgs.cs" />
Expand All @@ -107,6 +108,7 @@
<Compile Include="Session\PowerShellExecutionResult.cs" />
<Compile Include="Session\PowerShellContext.cs" />
<Compile Include="Session\PowerShellContextState.cs" />
<Compile Include="Session\ProfilePaths.cs" />
<Compile Include="Session\ProgressDetails.cs" />
<Compile Include="Session\RunspaceHandle.cs" />
<Compile Include="Session\SessionPSHost.cs" />
Expand Down
20 changes: 14 additions & 6 deletions src/PowerShellEditorServices/Session/EditorSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@
//

using Microsoft.PowerShell.EditorServices.Console;
using Microsoft.PowerShell.EditorServices.Session;
using Microsoft.PowerShell.EditorServices.Utility;
using System;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Reflection;
using System.Threading;

namespace Microsoft.PowerShell.EditorServices
{
Expand Down Expand Up @@ -61,9 +57,21 @@ public class EditorSession
/// for the ConsoleService.
/// </summary>
public void StartSession()
{
this.StartSession(null);
}

/// <summary>
/// Starts the session using the provided IConsoleHost implementation
/// for the ConsoleService.
/// </summary>
/// <param name="hostDetails">
/// Provides details about the host application.
/// </param>
public void StartSession(HostDetails hostDetails)
{
// Initialize all services
this.PowerShellContext = new PowerShellContext();
this.PowerShellContext = new PowerShellContext(hostDetails);
this.LanguageService = new LanguageService(this.PowerShellContext);
this.DebugService = new DebugService(this.PowerShellContext);
this.ConsoleService = new ConsoleService(this.PowerShellContext);
Expand Down
Loading