Skip to content

Commit 4010fce

Browse files
authored
Merge pull request #314 from PowerShell/daviwil/some-fixes
Various fixes and improvements for 0.8.0
2 parents 1f3df7a + 5c0ac2c commit 4010fce

File tree

11 files changed

+139
-8
lines changed

11 files changed

+139
-8
lines changed

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ protected async Task HandleInitializeRequest(
141141
// Grab the workspace path from the parameters
142142
editorSession.Workspace.WorkspacePath = initializeParams.RootPath;
143143

144+
// Set the working directory of the PowerShell session to the workspace path
145+
if (editorSession.Workspace.WorkspacePath != null)
146+
{
147+
editorSession.PowerShellContext.SetWorkingDirectory(
148+
editorSession.Workspace.WorkspacePath);
149+
}
150+
144151
await requestContext.SendResult(
145152
new InitializeResult
146153
{

src/PowerShellEditorServices.Protocol/Server/LanguageServerEditorOperations.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using Microsoft.PowerShell.EditorServices.Protocol.LanguageServer;
88
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
99
using System.Threading.Tasks;
10-
using System;
1110

1211
namespace Microsoft.PowerShell.EditorServices.Protocol.Server
1312
{
@@ -111,6 +110,16 @@ public Task OpenFile(string filePath)
111110
true);
112111
}
113112

113+
public string GetWorkspacePath()
114+
{
115+
return this.editorSession.Workspace.WorkspacePath;
116+
}
117+
118+
public string GetWorkspaceRelativePath(string filePath)
119+
{
120+
return this.editorSession.Workspace.GetRelativePath(filePath);
121+
}
122+
114123
public Task ShowInformationMessage(string message)
115124
{
116125
return

src/PowerShellEditorServices/Extensions/EditorWorkspace.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ public class EditorWorkspace
1717

1818
#endregion
1919

20+
#region Properties
21+
22+
/// <summary>
23+
/// Gets the current workspace path if there is one or null otherwise.
24+
/// </summary>
25+
public string Path
26+
{
27+
get { return this.editorOperations.GetWorkspacePath(); }
28+
}
29+
30+
#endregion
31+
2032
#region Constructors
2133

2234
internal EditorWorkspace(IEditorOperations editorOperations)

src/PowerShellEditorServices/Extensions/FileContext.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ public string Path
3232
get { return this.scriptFile.FilePath; }
3333
}
3434

35+
/// <summary>
36+
/// Gets the workspace-relative path of the file.
37+
/// </summary>
38+
public string WorkspacePath
39+
{
40+
get
41+
{
42+
return
43+
this.editorOperations.GetWorkspaceRelativePath(
44+
this.scriptFile.FilePath);
45+
}
46+
}
47+
3548
/// <summary>
3649
/// Gets the parsed abstract syntax tree for the file.
3750
/// </summary>

src/PowerShellEditorServices/Extensions/IEditorOperations.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ public interface IEditorOperations
2020
/// <returns>A new EditorContext object.</returns>
2121
Task<EditorContext> GetEditorContext();
2222

23+
/// <summary>
24+
/// Gets the path to the editor's active workspace.
25+
/// </summary>
26+
/// <returns>The workspace path or null if there isn't one.</returns>
27+
string GetWorkspacePath();
28+
29+
/// <summary>
30+
/// Resolves the given file path relative to the current workspace path.
31+
/// </summary>
32+
/// <param name="filePath">The file path to be resolved.</param>
33+
/// <returns>The resolved file path.</returns>
34+
string GetWorkspaceRelativePath(string filePath);
35+
2336
/// <summary>
2437
/// Causes a file to be opened in the editor. If the file is
2538
/// already open, the editor must switch to the file.

src/PowerShellEditorServices/Language/FindDotSourcedVisitor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public FindDotSourcedVisitor()
3232
/// or a decision to continue if it wasn't found</returns>
3333
public override AstVisitAction VisitCommand(CommandAst commandAst)
3434
{
35-
if (commandAst.InvocationOperator.Equals(TokenKind.Dot))
35+
if (commandAst.InvocationOperator.Equals(TokenKind.Dot) &&
36+
commandAst.CommandElements[0] is StringConstantExpressionAst)
3637
{
3738
// Strip any quote characters off of the string
3839
string fileName = commandAst.CommandElements[0].Extent.Text.Trim('\'', '"');

src/PowerShellEditorServices/Session/SessionPSHostUserInterface.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,8 @@ private void WaitForPromptCompletion<TResult>(
320320
try
321321
{
322322
// This will synchronously block on the prompt task
323-
// method which gets run on another thread. Use a
324-
// 30 second timeout so that everything doesn't get
325-
// backed up if the user doesn't respond.
326-
promptTask.Wait(15000);
323+
// method which gets run on another thread.
324+
promptTask.Wait();
327325

328326
if (promptTask.Status == TaskStatus.WaitingForActivation)
329327
{

src/PowerShellEditorServices/Workspace/Workspace.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,32 @@ public ScriptFile[] ExpandScriptReferences(ScriptFile scriptFile)
176176
return expandedReferences.ToArray();
177177
}
178178

179+
/// <summary>
180+
/// Gets the workspace-relative path of the given file path.
181+
/// </summary>
182+
/// <param name="filePath">The original full file path.</param>
183+
/// <returns>A relative file path</returns>
184+
public string GetRelativePath(string filePath)
185+
{
186+
string resolvedPath = filePath;
187+
188+
if (!IsPathInMemory(filePath) && !string.IsNullOrEmpty(this.WorkspacePath))
189+
{
190+
Uri workspaceUri = new Uri(this.WorkspacePath);
191+
Uri fileUri = new Uri(filePath);
192+
193+
resolvedPath = workspaceUri.MakeRelativeUri(fileUri).ToString();
194+
195+
// Convert the directory separators if necessary
196+
if (System.IO.Path.DirectorySeparatorChar == '\\')
197+
{
198+
resolvedPath = resolvedPath.Replace('/', '\\');
199+
}
200+
}
201+
202+
return resolvedPath;
203+
}
204+
179205
#endregion
180206

181207
#region Private Methods
@@ -264,10 +290,13 @@ internal static bool IsPathInMemory(string filePath)
264290
// When viewing PowerShell files in the Git diff viewer, VS Code
265291
// sends the contents of the file at HEAD with a URI that starts
266292
// with 'inmemory'. Untitled files which have been marked of
267-
// type PowerShell have a path starting with 'untitled'.
293+
// type PowerShell have a path starting with 'untitled'. Files
294+
// opened from the find/replace view will be prefixed with
295+
// 'private'.
268296
return
269297
filePath.StartsWith("inmemory") ||
270-
filePath.StartsWith("untitled");
298+
filePath.StartsWith("untitled") ||
299+
filePath.StartsWith("private");
271300
}
272301

273302
private string GetBaseFilePath(string filePath)

test/PowerShellEditorServices.Test/Extensions/ExtensionServiceTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,16 @@ await this.extensionEventQueue.EnqueueAsync(
168168

169169
public class TestEditorOperations : IEditorOperations
170170
{
171+
public string GetWorkspacePath()
172+
{
173+
throw new NotImplementedException();
174+
}
175+
176+
public string GetWorkspaceRelativePath(string filePath)
177+
{
178+
throw new NotImplementedException();
179+
}
180+
171181
public Task OpenFile(string filePath)
172182
{
173183
throw new NotImplementedException();

test/PowerShellEditorServices.Test/PowerShellEditorServices.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
<Compile Include="Console\ConsoleServiceTests.cs" />
7474
<Compile Include="Console\ChoicePromptHandlerTests.cs" />
7575
<Compile Include="Session\ScriptFileTests.cs" />
76+
<Compile Include="Session\WorkspaceTests.cs" />
7677
<Compile Include="Utility\AsyncDebouncerTests.cs" />
7778
<Compile Include="Utility\AsyncLockTests.cs" />
7879
<Compile Include="Utility\AsyncQueueTests.cs" />
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using Microsoft.PowerShell.EditorServices;
7+
using System;
8+
using System.IO;
9+
using System.Linq;
10+
using Xunit;
11+
12+
namespace Microsoft.PowerShell.EditorServices.Test.Session
13+
{
14+
public class WorkspaceTests
15+
{
16+
private static readonly Version PowerShellVersion = new Version("5.0");
17+
18+
[Fact]
19+
public void CanResolveWorkspaceRelativePath()
20+
{
21+
string workspacePath = @"c:\Test\Workspace\";
22+
string testPathInside = @"c:\Test\Workspace\SubFolder\FilePath.ps1";
23+
string testPathOutside = @"c:\Test\PeerPath\FilePath.ps1";
24+
string testPathAnotherDrive = @"z:\TryAndFindMe\FilePath.ps1";
25+
26+
Workspace workspace = new Workspace(PowerShellVersion);
27+
28+
// Test without a workspace path
29+
Assert.Equal(testPathOutside, workspace.GetRelativePath(testPathOutside));
30+
31+
// Test with a workspace path
32+
workspace.WorkspacePath = workspacePath;
33+
Assert.Equal(@"SubFolder\FilePath.ps1", workspace.GetRelativePath(testPathInside));
34+
Assert.Equal(@"..\PeerPath\FilePath.ps1", workspace.GetRelativePath(testPathOutside));
35+
Assert.Equal(testPathAnotherDrive, workspace.GetRelativePath(testPathAnotherDrive));
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)