Skip to content

Commit f390d45

Browse files
committed
Add WorkspaceFolders and use it when enumerating files
1 parent 101784e commit f390d45

File tree

3 files changed

+52
-36
lines changed

3 files changed

+52
-36
lines changed

src/PowerShellEditorServices/Server/PsesLanguageServer.cs

+10-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
using System.IO;
5+
using System.Linq;
56
using System.Threading.Tasks;
67
using Microsoft.Extensions.DependencyInjection;
78
using Microsoft.Extensions.Logging;
@@ -13,7 +14,6 @@
1314
using Microsoft.PowerShell.EditorServices.Services.Template;
1415
using Newtonsoft.Json.Linq;
1516
using OmniSharp.Extensions.JsonRpc;
16-
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
1717
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
1818
using OmniSharp.Extensions.LanguageServer.Server;
1919
using Serilog;
@@ -130,12 +130,7 @@ public async Task StartAsync()
130130
WorkspaceService workspaceService = languageServer.Services.GetService<WorkspaceService>();
131131
if (initializeParams.WorkspaceFolders is not null)
132132
{
133-
// TODO: Support multi-workspace.
134-
foreach (WorkspaceFolder workspaceFolder in initializeParams.WorkspaceFolders)
135-
{
136-
workspaceService.InitialWorkingDirectory = workspaceFolder.Uri.GetFileSystemPath();
137-
break;
138-
}
133+
workspaceService.WorkspaceFolders.AddRange(initializeParams.WorkspaceFolders);
139134
}
140135

141136
// Parse initialization options.
@@ -149,13 +144,16 @@ public async Task StartAsync()
149144
//
150145
// NOTE: The keys start with a lowercase because OmniSharp's client
151146
// (used for testing) forces it to be that way.
152-
LoadProfiles = initializationOptions?.GetValue("enableProfileLoading")?.Value<bool>() ?? true,
153-
// TODO: Consider deprecating the setting which sets this and
154-
// instead use WorkspacePath exclusively.
155-
InitialWorkingDirectory = initializationOptions?.GetValue("initialWorkingDirectory")?.Value<string>() ?? workspaceService.InitialWorkingDirectory,
156-
ShellIntegrationEnabled = initializationOptions?.GetValue("shellIntegrationEnabled")?.Value<bool>() ?? false
147+
LoadProfiles = initializationOptions?.GetValue("enableProfileLoading")?.Value<bool>()
148+
?? true,
149+
InitialWorkingDirectory = initializationOptions?.GetValue("initialWorkingDirectory")?.Value<string>()
150+
?? workspaceService.WorkspaceFolders.FirstOrDefault()?.Uri.GetFileSystemPath(),
151+
ShellIntegrationEnabled = initializationOptions?.GetValue("shellIntegrationEnabled")?.Value<bool>()
152+
?? false
157153
};
158154

155+
workspaceService.InitialWorkingDirectory = hostStartOptions.InitialWorkingDirectory;
156+
159157
_psesHost = languageServer.Services.GetService<PsesInternalHost>();
160158
return _psesHost.TryStartAsync(hostStartOptions, cancellationToken);
161159
});

src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs

+36-21
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// Copyright (c) Microsoft Corporation.
1+
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

44
using System;
55
using System.Collections.Concurrent;
66
using System.Collections.Generic;
77
using System.IO;
8+
using System.Linq;
89
using System.Security;
910
using System.Text;
1011
using Microsoft.Extensions.FileSystemGlobbing;
@@ -13,6 +14,7 @@
1314
using Microsoft.PowerShell.EditorServices.Services.Workspace;
1415
using Microsoft.PowerShell.EditorServices.Utility;
1516
using OmniSharp.Extensions.LanguageServer.Protocol;
17+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
1618

1719
namespace Microsoft.PowerShell.EditorServices.Services
1820
{
@@ -67,6 +69,11 @@ internal class WorkspaceService
6769
/// </summary>
6870
public string InitialWorkingDirectory { get; set; }
6971

72+
/// <summary>
73+
/// Gets or sets the folders of the workspace.
74+
/// </summary>
75+
public List<WorkspaceFolder> WorkspaceFolders { get; set; }
76+
7077
/// <summary>
7178
/// Gets or sets the default list of file globs to exclude during workspace searches.
7279
/// </summary>
@@ -88,6 +95,7 @@ public WorkspaceService(ILoggerFactory factory)
8895
{
8996
powerShellVersion = VersionUtils.PSVersion;
9097
logger = factory.CreateLogger<WorkspaceService>();
98+
WorkspaceFolders = new List<WorkspaceFolder>();
9199
ExcludeFilesGlob = new List<string>();
92100
FollowSymlinks = true;
93101
}
@@ -336,39 +344,46 @@ public IEnumerable<string> EnumeratePSFiles()
336344
}
337345

338346
/// <summary>
339-
/// Enumerate all the PowerShell (ps1, psm1, psd1) files in the workspace in a recursive manner.
347+
/// Enumerate all the PowerShell (ps1, psm1, psd1) files in the workspace folders in a
348+
/// recursive manner. Falls back to initial working directory if there are no workspace folders.
340349
/// </summary>
341350
/// <returns>An enumerator over the PowerShell files found in the workspace.</returns>
342351
public IEnumerable<string> EnumeratePSFiles(
343352
string[] excludeGlobs,
344353
string[] includeGlobs,
345354
int maxDepth,
346-
bool ignoreReparsePoints
347-
)
355+
bool ignoreReparsePoints)
348356
{
349-
if (InitialWorkingDirectory is null || !Directory.Exists(InitialWorkingDirectory))
350-
{
351-
yield break;
352-
}
357+
IEnumerable<string> rootPaths = WorkspaceFolders.Count == 0
358+
? new List<string> { InitialWorkingDirectory }
359+
: WorkspaceFolders.Select(i => i.Uri.GetFileSystemPath());
353360

354361
Matcher matcher = new();
355362
foreach (string pattern in includeGlobs) { matcher.AddInclude(pattern); }
356363
foreach (string pattern in excludeGlobs) { matcher.AddExclude(pattern); }
357364

358-
WorkspaceFileSystemWrapperFactory fsFactory = new(
359-
InitialWorkingDirectory,
360-
maxDepth,
361-
VersionUtils.IsNetCore ? s_psFileExtensionsCoreFramework : s_psFileExtensionsFullFramework,
362-
ignoreReparsePoints,
363-
logger
364-
);
365-
PatternMatchingResult fileMatchResult = matcher.Execute(fsFactory.RootDirectory);
366-
foreach (FilePatternMatch item in fileMatchResult.Files)
365+
foreach (string rootPath in rootPaths)
367366
{
368-
// item.Path always contains forward slashes in paths when it should be backslashes on Windows.
369-
// Since we're returning strings here, it's important to use the correct directory separator.
370-
string path = VersionUtils.IsWindows ? item.Path.Replace('/', Path.DirectorySeparatorChar) : item.Path;
371-
yield return Path.Combine(InitialWorkingDirectory, path);
367+
if (!Directory.Exists(rootPath))
368+
{
369+
continue;
370+
}
371+
372+
WorkspaceFileSystemWrapperFactory fsFactory = new(
373+
rootPath,
374+
maxDepth,
375+
VersionUtils.IsNetCore ? s_psFileExtensionsCoreFramework : s_psFileExtensionsFullFramework,
376+
ignoreReparsePoints,
377+
logger);
378+
379+
PatternMatchingResult fileMatchResult = matcher.Execute(fsFactory.RootDirectory);
380+
foreach (FilePatternMatch item in fileMatchResult.Files)
381+
{
382+
// item.Path always contains forward slashes in paths when it should be backslashes on Windows.
383+
// Since we're returning strings here, it's important to use the correct directory separator.
384+
string path = VersionUtils.IsWindows ? item.Path.Replace('/', Path.DirectorySeparatorChar) : item.Path;
385+
yield return Path.Combine(rootPath, path);
386+
}
372387
}
373388
}
374389

test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
using Microsoft.PowerShell.EditorServices.Test.Shared.SymbolDetails;
2424
using Microsoft.PowerShell.EditorServices.Test.Shared.Symbols;
2525
using Microsoft.PowerShell.EditorServices.Utility;
26+
using OmniSharp.Extensions.LanguageServer.Protocol;
27+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
2628
using Xunit;
2729

2830
namespace PowerShellEditorServices.Test.Language
@@ -38,10 +40,11 @@ public class SymbolsServiceTests : IDisposable
3840
public SymbolsServiceTests()
3941
{
4042
psesHost = PsesHostFactory.Create(NullLoggerFactory.Instance);
41-
workspace = new WorkspaceService(NullLoggerFactory.Instance)
43+
workspace = new WorkspaceService(NullLoggerFactory.Instance);
44+
workspace.WorkspaceFolders.Add(new WorkspaceFolder()
4245
{
43-
InitialWorkingDirectory = TestUtilities.GetSharedPath("References")
44-
};
46+
Uri = DocumentUri.FromFileSystemPath(TestUtilities.GetSharedPath("References"))
47+
});
4548
symbolsService = new SymbolsService(
4649
NullLoggerFactory.Instance,
4750
psesHost,

0 commit comments

Comments
 (0)