Skip to content

Add "Expand Alias" support #59

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 5 commits into from
Dec 9, 2015
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
46 changes: 43 additions & 3 deletions src/PowerShellEditorServices.Host/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public void Initialize()
this.AddRequestHandler(WorkspaceSymbolRequest.Type, this.HandleWorkspaceSymbolRequest);

this.AddRequestHandler(ShowOnlineHelpRequest.Type, this.HandleShowOnlineHelpRequest);
this.AddRequestHandler(ExpandAliasRequest.Type, this.HandleExpandAliasRequest);

this.AddRequestHandler(DebugAdapterMessages.EvaluateRequest.Type, this.HandleEvaluateRequest);
}
Expand Down Expand Up @@ -152,6 +153,45 @@ await editorSession.PowerShellContext.ExecuteCommand<object>(
await requestContext.SendResult(null);
}

private async Task HandleExpandAliasRequest(
string content,
EditorSession editorSession,
RequestContext<string, object> requestContext)
{
var script = @"
function __Expand-Alias {

param($targetScript)

[ref]$errors=$null

$tokens = [System.Management.Automation.PsParser]::Tokenize($targetScript, $errors).Where({$_.type -eq 'command'}) |
Sort Start -Descending

foreach ($token in $tokens) {
$definition=(Get-Command ('`'+$token.Content) -CommandType Alias -ErrorAction SilentlyContinue).Definition

if($definition) {
$lhs=$targetScript.Substring(0, $token.Start)
$rhs=$targetScript.Substring($token.Start + $token.Length)

$targetScript=$lhs + $definition + $rhs
}
}

$targetScript
}";
var psCommand = new PSCommand();
psCommand.AddScript(script);
await editorSession.PowerShellContext.ExecuteCommand<PSObject>(psCommand);

psCommand = new PSCommand();
psCommand.AddCommand("__Expand-Alias").AddArgument(content);
var result = await editorSession.PowerShellContext.ExecuteCommand<string>(psCommand);

await requestContext.SendResult(result.First().ToString());
}

protected Task HandleExitNotification(
object exitParams,
EditorSession editorSession,
Expand Down Expand Up @@ -235,7 +275,7 @@ protected async Task HandleDidChangeConfigurationNotification(
EditorSession editorSession,
EventContext eventContext)
{
bool oldScriptAnalysisEnabled =
bool oldScriptAnalysisEnabled =
this.currentSettings.ScriptAnalysis.Enable.HasValue;

this.currentSettings.Update(
Expand Down Expand Up @@ -887,8 +927,8 @@ await eventContext.SendEvent(
new PublishDiagnosticsNotification
{
Uri = scriptFile.ClientFilePath,
Diagnostics =
allMarkers
Diagnostics =
allMarkers
.Select(GetDiagnosticFromMarker)
.ToArray()
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// 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.Protocol.MessageProtocol;

namespace Microsoft.PowerShell.EditorServices.Protocol.LanguageServer
{
public class ExpandAliasRequest
{
public static readonly
RequestType<string, string, object> Type =
RequestType<string, string, object>.Create("powerShell/expandAlias");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<Compile Include="LanguageServer\Configuration.cs" />
<Compile Include="LanguageServer\Definition.cs" />
<Compile Include="LanguageServer\DocumentHighlight.cs" />
<Compile Include="LanguageServer\ExpandAliasRequest.cs" />
<Compile Include="LanguageServer\Hover.cs" />
<Compile Include="LanguageServer\ShowOnlineHelpRequest.cs" />
<Compile Include="LanguageServer\SignatureHelp.cs" />
Expand Down
26 changes: 15 additions & 11 deletions src/PowerShellEditorServices/Session/PowerShellContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public Task<RunspaceHandle> GetRunspaceHandle()
/// execution completes.
/// </returns>
public async Task<IEnumerable<TResult>> ExecuteCommand<TResult>(
PSCommand psCommand,
PSCommand psCommand,
bool sendOutputToHost = false)
{
// If the debugger is active and the caller isn't on the pipeline
Expand Down Expand Up @@ -207,7 +207,7 @@ public async Task<IEnumerable<TResult>> ExecuteCommand<TResult>(
this.debuggerStoppedTask != null)
{
Logger.Write(
LogLevel.Verbose,
LogLevel.Verbose,
string.Format(
"Attempting to execute nested pipeline command(s):\r\n\r\n{0}",
GetStringForPSCommand(psCommand)));
Expand All @@ -231,7 +231,7 @@ public async Task<IEnumerable<TResult>> ExecuteCommand<TResult>(
else
{
Logger.Write(
LogLevel.Verbose,
LogLevel.Verbose,
string.Format(
"Attempting to execute command(s):\r\n\r\n{0}",
GetStringForPSCommand(psCommand)));
Expand Down Expand Up @@ -262,15 +262,19 @@ await Task.Factory.StartNew<IEnumerable<TResult>>(

if (this.powerShell.HadErrors)
{
// TODO: Find a good way to extract errors!
Logger.Write(
LogLevel.Error,
"Execution completed with errors.");
string errorMessage = "Execution completed with errors:\r\n\r\n";

foreach (var error in this.powerShell.Streams.Error)
{
errorMessage += error.ToString() + "\r\n";
}

Logger.Write(LogLevel.Error, errorMessage);
}
else
{
Logger.Write(
LogLevel.Verbose,
LogLevel.Verbose,
"Execution completed successfully.");
}

Expand Down Expand Up @@ -411,7 +415,7 @@ internal void ReleaseRunspaceHandle(RunspaceHandle runspaceHandle)
if (!this.runspaceWaitQueue.IsEmpty)
{
this.currentRunspaceHandle = new RunspaceHandle(this.currentRunspace, this);
dequeuedTask =
dequeuedTask =
this.runspaceWaitQueue.Dequeue(
this.currentRunspaceHandle);
}
Expand Down Expand Up @@ -442,7 +446,7 @@ private void OnSessionStateChanged(object sender, SessionStateChangedEventArgs e
this.SessionState.ToString(),
e.NewSessionState.ToString()));

this.SessionState = e.NewSessionState;
this.SessionState = e.NewSessionState;

if (this.SessionStateChanged != null)
{
Expand Down Expand Up @@ -557,7 +561,7 @@ private void SetExecutionPolicy(ExecutionPolicy desiredExecutionPolicy)
currentPolicy = result.FirstOrDefault();
}

if (desiredExecutionPolicy < currentPolicy ||
if (desiredExecutionPolicy < currentPolicy ||
desiredExecutionPolicy == ExecutionPolicy.Bypass ||
currentPolicy == ExecutionPolicy.Undefined)
{
Expand Down
105 changes: 58 additions & 47 deletions test/PowerShellEditorServices.Test.Host/ScenarioTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ public class ScenarioTests : IDisposable
{
private int messageId = 0;

private LanguageServiceManager languageServiceManager =
private LanguageServiceManager languageServiceManager =
new LanguageServiceManager();

private MessageReader MessageReader
{
get { return this.languageServiceManager.MessageReader; }
private MessageReader MessageReader
{
get { return this.languageServiceManager.MessageReader; }
}

private MessageWriter MessageWriter
Expand Down Expand Up @@ -109,7 +109,7 @@ await this.SendRequest(
Assert.Equal("string", consoleFileNameItem.Detail);
}

[Fact(Skip="Skipped until variable documentation gathering is added back.")]
[Fact(Skip = "Skipped until variable documentation gathering is added back.")]
public async Task CompletesDetailOnVariableDocSuggestion()
{
//await this.SendOpenFileEvent("TestFiles\\CompleteFunctionName.ps1");
Expand Down Expand Up @@ -429,51 +429,62 @@ await this.SendRequestWithoutWait(
Assert.Equal("stdout", outputEvent.Category);
}

[Fact]
public async Task ServiceExpandsAliases()
{
string expandedText =
await this.SendRequest(
ExpandAliasRequest.Type,
"gci\r\npwd");

Assert.Equal("Get-ChildItem\r\nGet-Location", expandedText);
}

[Fact]//(Skip = "Choice prompt functionality is currently in transition to a new model.")]
public async Task ServiceExecutesReplCommandAndReceivesChoicePrompt()
{
// TODO: This test is removed until a new choice prompt strategy is determined.

// string choiceScript =
// @"
// $caption = ""Test Choice"";
// $message = ""Make a selection"";
// $choiceA = new-Object System.Management.Automation.Host.ChoiceDescription ""&A"",""A"";
// $choiceB = new-Object System.Management.Automation.Host.ChoiceDescription ""&B"",""B"";
// $choices = [System.Management.Automation.Host.ChoiceDescription[]]($choiceA,$choiceB);
// $response = $host.ui.PromptForChoice($caption, $message, $choices, 1)
// $response";

// await this.MessageWriter.WriteMessage(
// new ReplExecuteRequest
// {
// Arguments = new ReplExecuteArgs
// {
// CommandString = choiceScript
// }
// });

// // Wait for the choice prompt event and check expected values
// ReplPromptChoiceEvent replPromptChoiceEvent = this.WaitForMessage<ReplPromptChoiceEvent>();
// Assert.Equal(1, replPromptChoiceEvent.Body.DefaultChoice);

// // Respond to the prompt event
// await this.MessageWriter.WriteMessage(
// new ReplPromptChoiceResponse
// {
// Body = new ReplPromptChoiceResponseBody
// {
// Choice = 0
// }
// });

// // Wait for the selection to appear as output
// ReplWriteOutputEvent replWriteLineEvent = this.WaitForMessage<ReplWriteOutputEvent>();
// Assert.Equal("0", replWriteLineEvent.Body.LineContents);
// string choiceScript =
// @"
// $caption = ""Test Choice"";
// $message = ""Make a selection"";
// $choiceA = new-Object System.Management.Automation.Host.ChoiceDescription ""&A"",""A"";
// $choiceB = new-Object System.Management.Automation.Host.ChoiceDescription ""&B"",""B"";
// $choices = [System.Management.Automation.Host.ChoiceDescription[]]($choiceA,$choiceB);
// $response = $host.ui.PromptForChoice($caption, $message, $choices, 1)
// $response";

// await this.MessageWriter.WriteMessage(
// new ReplExecuteRequest
// {
// Arguments = new ReplExecuteArgs
// {
// CommandString = choiceScript
// }
// });

// // Wait for the choice prompt event and check expected values
// ReplPromptChoiceEvent replPromptChoiceEvent = this.WaitForMessage<ReplPromptChoiceEvent>();
// Assert.Equal(1, replPromptChoiceEvent.Body.DefaultChoice);

// // Respond to the prompt event
// await this.MessageWriter.WriteMessage(
// new ReplPromptChoiceResponse
// {
// Body = new ReplPromptChoiceResponseBody
// {
// Choice = 0
// }
// });

// // Wait for the selection to appear as output
// ReplWriteOutputEvent replWriteLineEvent = this.WaitForMessage<ReplWriteOutputEvent>();
// Assert.Equal("0", replWriteLineEvent.Body.LineContents);
}

private async Task<TResult> SendRequest<TParams, TResult, TError>(
RequestType<TParams, TResult, TError> requestType,
RequestType<TParams, TResult, TError> requestType,
TParams requestParams)
{
await this.SendRequestWithoutWait(requestType, requestParams);
Expand All @@ -491,7 +502,7 @@ await this.MessageWriter.WriteMessage(
this.messageId.ToString(),
requestType.TypeName,
JToken.FromObject(requestParams)));
}
}

private async Task SendEvent<TParams>(EventType<TParams> eventType, TParams eventParams)
{
Expand All @@ -506,9 +517,9 @@ private async Task SendOpenFileEvent(string filePath, bool waitForDiagnostics =
string fileContents = string.Join(Environment.NewLine, File.ReadAllLines(filePath));

await this.SendEvent(
DidOpenTextDocumentNotification.Type,
new DidOpenTextDocumentNotification()
{
DidOpenTextDocumentNotification.Type,
new DidOpenTextDocumentNotification()
{
Uri = filePath,
Text = fileContents
});
Expand All @@ -535,7 +546,7 @@ private TParams WaitForEvent<TParams>(EventType<TParams> eventType)
}

private TResult WaitForResponse<TParams, TResult, TError>(
RequestType<TParams, TResult, TError> requestType,
RequestType<TParams, TResult, TError> requestType,
int expectedId)
{
// TODO: Integrate timeout!
Expand Down