13
13
using Microsoft . PowerShell . EditorServices . Services . Workspace ;
14
14
using Microsoft . PowerShell . EditorServices . Utility ;
15
15
using OmniSharp . Extensions . LanguageServer . Protocol ;
16
+ using OmniSharp . Extensions . LanguageServer . Protocol . Models ;
16
17
17
18
namespace Microsoft . PowerShell . EditorServices . Services
18
19
{
@@ -58,10 +59,15 @@ internal class WorkspaceService
58
59
#region Properties
59
60
60
61
/// <summary>
61
- /// Gets or sets the root path of the workspace.
62
+ /// Deprecated! Multi- root workspace support requires multiple workspace paths .
62
63
/// </summary>
63
64
public string WorkspacePath { get ; set ; }
64
65
66
+ /// <summary>
67
+ /// Gets or sets the folders of the workspace.
68
+ /// </summary>
69
+ public List < WorkspaceFolder > WorkspaceFolders { get ; set ; }
70
+
65
71
/// <summary>
66
72
/// Gets or sets the default list of file globs to exclude during workspace searches.
67
73
/// </summary>
@@ -83,6 +89,7 @@ public WorkspaceService(ILoggerFactory factory)
83
89
{
84
90
powerShellVersion = VersionUtils . PSVersion ;
85
91
logger = factory . CreateLogger < WorkspaceService > ( ) ;
92
+ WorkspaceFolders = new List < WorkspaceFolder > ( ) ;
86
93
ExcludeFilesGlob = new List < string > ( ) ;
87
94
FollowSymlinks = true ;
88
95
}
@@ -293,18 +300,23 @@ public void CloseFile(ScriptFile scriptFile)
293
300
/// <summary>
294
301
/// Gets the workspace-relative path of the given file path.
295
302
/// </summary>
296
- /// <param name="filePath">The original full file path.</param>
297
303
/// <returns>A relative file path</returns>
298
- public string GetRelativePath ( string filePath )
304
+ public string GetRelativePath ( ScriptFile scriptFile )
299
305
{
300
- string resolvedPath = filePath ;
306
+ string resolvedPath = scriptFile . FilePath ;
301
307
302
- if ( ! IsPathInMemory ( filePath ) && ! string . IsNullOrEmpty ( WorkspacePath ) )
308
+ if ( ! scriptFile . IsInMemory )
303
309
{
304
- Uri workspaceUri = new ( WorkspacePath ) ;
305
- Uri fileUri = new ( filePath ) ;
306
-
307
- resolvedPath = workspaceUri . MakeRelativeUri ( fileUri ) . ToString ( ) ;
310
+ Uri fileUri = scriptFile . DocumentUri . ToUri ( ) ;
311
+ foreach ( WorkspaceFolder workspaceFolder in WorkspaceFolders )
312
+ {
313
+ Uri workspaceUri = workspaceFolder . Uri . ToUri ( ) ;
314
+ if ( workspaceUri . IsBaseOf ( fileUri ) )
315
+ {
316
+ resolvedPath = workspaceUri . MakeRelativeUri ( fileUri ) . ToString ( ) ;
317
+ break ;
318
+ }
319
+ }
308
320
309
321
// Convert the directory separators if necessary
310
322
if ( Path . DirectorySeparatorChar == '\\ ' )
@@ -341,7 +353,7 @@ public IEnumerable<string> EnumeratePSFiles(
341
353
bool ignoreReparsePoints
342
354
)
343
355
{
344
- if ( WorkspacePath is null || ! Directory . Exists ( WorkspacePath ) )
356
+ if ( WorkspaceFolders . Count == 0 )
345
357
{
346
358
yield break ;
347
359
}
@@ -350,20 +362,29 @@ bool ignoreReparsePoints
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 ( WorkspaceFolder workspaceFolder in WorkspaceFolders )
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
+ string rootPath = workspaceFolder . Uri . GetFileSystemPath ( ) ;
368
+ if ( ! Directory . Exists ( rootPath ) )
369
+ {
370
+ continue ;
371
+ }
372
+
373
+ WorkspaceFileSystemWrapperFactory fsFactory = new (
374
+ rootPath ,
375
+ maxDepth ,
376
+ VersionUtils . IsNetCore ? s_psFileExtensionsCoreFramework : s_psFileExtensionsFullFramework ,
377
+ ignoreReparsePoints ,
378
+ logger ) ;
379
+
380
+ PatternMatchingResult fileMatchResult = matcher . Execute ( fsFactory . RootDirectory ) ;
381
+ foreach ( FilePatternMatch item in fileMatchResult . Files )
382
+ {
383
+ // item.Path always contains forward slashes in paths when it should be backslashes on Windows.
384
+ // Since we're returning strings here, it's important to use the correct directory separator.
385
+ string path = VersionUtils . IsWindows ? item . Path . Replace ( '/' , Path . DirectorySeparatorChar ) : item . Path ;
386
+ yield return Path . Combine ( rootPath , path ) ;
387
+ }
367
388
}
368
389
}
369
390
0 commit comments