1
- // Copyright (c) Microsoft Corporation.
1
+ // Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
3
4
4
using System ;
5
5
using System . Collections . Concurrent ;
6
6
using System . Collections . Generic ;
7
7
using System . IO ;
8
+ using System . Linq ;
8
9
using System . Security ;
9
10
using System . Text ;
10
11
using Microsoft . Extensions . FileSystemGlobbing ;
13
14
using Microsoft . PowerShell . EditorServices . Services . Workspace ;
14
15
using Microsoft . PowerShell . EditorServices . Utility ;
15
16
using OmniSharp . Extensions . LanguageServer . Protocol ;
17
+ using OmniSharp . Extensions . LanguageServer . Protocol . Models ;
16
18
17
19
namespace Microsoft . PowerShell . EditorServices . Services
18
20
{
@@ -58,9 +60,19 @@ internal class WorkspaceService
58
60
#region Properties
59
61
60
62
/// <summary>
61
- /// Gets or sets the root path of the workspace.
63
+ /// <para>Gets or sets the initial working directory.</para>
64
+ /// <para>
65
+ /// This is settable by the same key in the initialization options, and likely corresponds
66
+ /// to the root of the workspace if only one workspace folder is being used. However, in
67
+ /// multi-root workspaces this may be any workspace folder's root (or none if overridden).
68
+ /// </para>
62
69
/// </summary>
63
- public string WorkspacePath { get ; set ; }
70
+ public string InitialWorkingDirectory { get ; set ; }
71
+
72
+ /// <summary>
73
+ /// Gets or sets the folders of the workspace.
74
+ /// </summary>
75
+ public List < WorkspaceFolder > WorkspaceFolders { get ; set ; }
64
76
65
77
/// <summary>
66
78
/// Gets or sets the default list of file globs to exclude during workspace searches.
@@ -83,6 +95,7 @@ public WorkspaceService(ILoggerFactory factory)
83
95
{
84
96
powerShellVersion = VersionUtils . PSVersion ;
85
97
logger = factory . CreateLogger < WorkspaceService > ( ) ;
98
+ WorkspaceFolders = new List < WorkspaceFolder > ( ) ;
86
99
ExcludeFilesGlob = new List < string > ( ) ;
87
100
FollowSymlinks = true ;
88
101
}
@@ -299,9 +312,9 @@ public string GetRelativePath(string filePath)
299
312
{
300
313
string resolvedPath = filePath ;
301
314
302
- if ( ! IsPathInMemory ( filePath ) && ! string . IsNullOrEmpty ( WorkspacePath ) )
315
+ if ( ! IsPathInMemory ( filePath ) && ! string . IsNullOrEmpty ( InitialWorkingDirectory ) )
303
316
{
304
- Uri workspaceUri = new ( WorkspacePath ) ;
317
+ Uri workspaceUri = new ( InitialWorkingDirectory ) ;
305
318
Uri fileUri = new ( filePath ) ;
306
319
307
320
resolvedPath = workspaceUri . MakeRelativeUri ( fileUri ) . ToString ( ) ;
@@ -331,39 +344,46 @@ public IEnumerable<string> EnumeratePSFiles()
331
344
}
332
345
333
346
/// <summary>
334
- /// 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.
335
349
/// </summary>
336
350
/// <returns>An enumerator over the PowerShell files found in the workspace.</returns>
337
351
public IEnumerable < string > EnumeratePSFiles (
338
352
string [ ] excludeGlobs ,
339
353
string [ ] includeGlobs ,
340
354
int maxDepth ,
341
- bool ignoreReparsePoints
342
- )
355
+ bool ignoreReparsePoints )
343
356
{
344
- if ( WorkspacePath is null || ! Directory . Exists ( WorkspacePath ) )
345
- {
346
- yield break ;
347
- }
357
+ IEnumerable < string > rootPaths = WorkspaceFolders . Count == 0
358
+ ? new List < string > { InitialWorkingDirectory }
359
+ : WorkspaceFolders . Select ( i => i . Uri . GetFileSystemPath ( ) ) ;
348
360
349
361
Matcher matcher = new ( ) ;
350
362
foreach ( string pattern in includeGlobs ) { matcher . AddInclude ( pattern ) ; }
351
363
foreach ( string pattern in excludeGlobs ) { matcher . AddExclude ( pattern ) ; }
352
364
353
- WorkspaceFileSystemWrapperFactory fsFactory = new (
354
- WorkspacePath ,
355
- maxDepth ,
356
- VersionUtils . IsNetCore ? s_psFileExtensionsCoreFramework : s_psFileExtensionsFullFramework ,
357
- ignoreReparsePoints ,
358
- logger
359
- ) ;
360
- PatternMatchingResult fileMatchResult = matcher . Execute ( fsFactory . RootDirectory ) ;
361
- foreach ( FilePatternMatch item in fileMatchResult . Files )
365
+ foreach ( string rootPath in rootPaths )
362
366
{
363
- // item.Path always contains forward slashes in paths when it should be backslashes on Windows.
364
- // Since we're returning strings here, it's important to use the correct directory separator.
365
- string path = VersionUtils . IsWindows ? item . Path . Replace ( '/' , Path . DirectorySeparatorChar ) : item . Path ;
366
- yield return Path . Combine ( WorkspacePath , 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
+ }
367
387
}
368
388
}
369
389
@@ -423,7 +443,7 @@ internal static bool IsPathInMemory(string filePath)
423
443
return isInMemory ;
424
444
}
425
445
426
- internal string ResolveWorkspacePath ( string path ) => ResolveRelativeScriptPath ( WorkspacePath , path ) ;
446
+ internal string ResolveWorkspacePath ( string path ) => ResolveRelativeScriptPath ( InitialWorkingDirectory , path ) ;
427
447
428
448
internal string ResolveRelativeScriptPath ( string baseFilePath , string relativePath )
429
449
{
0 commit comments