diff --git a/src/PowerShellEditorServices/PowerShellEditorServices.csproj b/src/PowerShellEditorServices/PowerShellEditorServices.csproj
index 921395f34..da1496d17 100644
--- a/src/PowerShellEditorServices/PowerShellEditorServices.csproj
+++ b/src/PowerShellEditorServices/PowerShellEditorServices.csproj
@@ -30,7 +30,7 @@
-
+
@@ -40,6 +40,6 @@
-
+
diff --git a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs
index fbb975b6d..b2ffff59f 100644
--- a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs
+++ b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs
@@ -101,7 +101,7 @@ public async Task StartAsync()
// Grab the workspace path from the parameters
if (request.RootUri != null)
{
- workspaceService.WorkspacePath = workspaceService.ResolveFilePath(request.RootUri.ToString());
+ workspaceService.WorkspacePath = workspaceService.ResolveFileUri(request.RootUri).OriginalString;
}
// Set the working directory of the PowerShell session to the workspace path
diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs
index eeac33c5c..01b28b745 100644
--- a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs
+++ b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs
@@ -85,7 +85,7 @@ public async Task SetSelectionAsync(BufferRange selectionRange)
public EditorContext ConvertClientEditorContext(
ClientEditorContext clientContext)
{
- ScriptFile scriptFile = _workspaceService.CreateScriptFileFromFileBuffer(
+ ScriptFile scriptFile = _workspaceService.GetFileBuffer(
clientContext.CurrentFilePath,
clientContext.CurrentFileContent);
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs
index 80180ca61..36d5a5a92 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs
@@ -55,7 +55,7 @@ public void SetCapability(CodeActionCapability capability)
public async Task Handle(CodeActionParams request, CancellationToken cancellationToken)
{
- IReadOnlyDictionary corrections = await _analysisService.GetMostRecentCodeActionsForFileAsync(request.TextDocument.Uri.ToString());
+ IReadOnlyDictionary corrections = await _analysisService.GetMostRecentCodeActionsForFileAsync(request.TextDocument.Uri.OriginalString);
if (corrections == null)
{
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs
index a4c9d2ca8..d594e4318 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs
@@ -61,8 +61,7 @@ CodeLensRegistrationOptions IRegistration.GetRegist
public Task Handle(CodeLensParams request, CancellationToken cancellationToken)
{
- ScriptFile scriptFile = _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
CodeLens[] codeLensResults = ProvideCodeLenses(scriptFile);
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs
index 6f4bb6715..a768ad7fd 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs
@@ -65,9 +65,7 @@ public async Task Handle(CompletionParams request, CancellationT
int cursorLine = (int) request.Position.Line + 1;
int cursorColumn = (int) request.Position.Character + 1;
- ScriptFile scriptFile =
- _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
CompletionResults completionResults =
await GetCompletionsInFileAsync(
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs
index 64033c564..1b59f9d7f 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs
@@ -52,9 +52,7 @@ public TextDocumentRegistrationOptions GetRegistrationOptions()
public async Task Handle(DefinitionParams request, CancellationToken cancellationToken)
{
- ScriptFile scriptFile =
- _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
SymbolReference foundSymbol =
_symbolsService.FindSymbolAtLocation(
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs
index 102d0ab17..afc90f7f3 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs
@@ -56,7 +56,7 @@ public Task Handle(
DocumentHighlightParams request,
CancellationToken cancellationToken)
{
- ScriptFile scriptFile = _workspaceService.GetFile(PathUtils.FromUri(request.TextDocument.Uri));
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
IReadOnlyList symbolOccurrences = _symbolsService.FindOccurrencesInFile(
scriptFile,
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs
index 3a2af8838..9cd9aed2e 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentSymbolHandler.cs
@@ -60,9 +60,7 @@ public TextDocumentRegistrationOptions GetRegistrationOptions()
public Task Handle(DocumentSymbolParams request, CancellationToken cancellationToken)
{
- ScriptFile scriptFile =
- _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
IEnumerable foundSymbols =
this.ProvideDocumentSymbols(scriptFile);
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FoldingRangeHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FoldingRangeHandler.cs
index dbb554fb0..6945e379f 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FoldingRangeHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FoldingRangeHandler.cs
@@ -54,7 +54,7 @@ public Task> Handle(FoldingRangeRequestParam request, Ca
// Perhaps a better option would be to parse the contents of the document as a string
// as opposed to reading a file but the scenario of "no backing file" probably doesn't
// warrant the extra effort.
- if (!_workspaceService.TryGetFile(request.TextDocument.Uri.ToString(), out ScriptFile scriptFile)) { return null; }
+ if (!_workspaceService.TryGetFile(request.TextDocument.Uri, out ScriptFile scriptFile)) { return null; }
var result = new List();
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs
index aabdeb615..160587fa1 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs
@@ -46,7 +46,7 @@ public TextDocumentRegistrationOptions GetRegistrationOptions()
public async Task Handle(DocumentFormattingParams request, CancellationToken cancellationToken)
{
- var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri.ToString());
+ var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
var pssaSettings = _configurationService.CurrentSettings.CodeFormatting.GetPSSASettingsHashtable(
(int)request.Options.TabSize,
request.Options.InsertSpaces);
@@ -124,7 +124,7 @@ public TextDocumentRegistrationOptions GetRegistrationOptions()
public async Task Handle(DocumentRangeFormattingParams request, CancellationToken cancellationToken)
{
- var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri.ToString());
+ var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
var pssaSettings = _configurationService.CurrentSettings.CodeFormatting.GetPSSASettingsHashtable(
(int)request.Options.TabSize,
request.Options.InsertSpaces);
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs
index 8a107ed42..21de3b42a 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs
@@ -54,9 +54,7 @@ public TextDocumentRegistrationOptions GetRegistrationOptions()
public async Task Handle(HoverParams request, CancellationToken cancellationToken)
{
- ScriptFile scriptFile =
- _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
SymbolDetails symbolDetails =
await _symbolsService.FindSymbolDetailsAtLocationAsync(
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs
index c72ce141e..36f8f5dfe 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs
@@ -48,9 +48,7 @@ public TextDocumentRegistrationOptions GetRegistrationOptions()
public async Task Handle(ReferenceParams request, CancellationToken cancellationToken)
{
- ScriptFile scriptFile =
- _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
SymbolReference foundSymbol =
_symbolsService.FindSymbolAtLocation(
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs
index eac0303ab..b89755cf0 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs
@@ -58,9 +58,7 @@ public SignatureHelpRegistrationOptions GetRegistrationOptions()
public async Task Handle(SignatureHelpParams request, CancellationToken cancellationToken)
{
- ScriptFile scriptFile =
- _workspaceService.GetFile(
- request.TextDocument.Uri.ToString());
+ ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
ParameterSetSignatures parameterSets =
await _symbolsService.FindParameterSetsInFileAsync(
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs
index 9bf4546eb..e54779af3 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs
@@ -51,7 +51,7 @@ public TextDocumentHandler(
public Task Handle(DidChangeTextDocumentParams notification, CancellationToken token)
{
- ScriptFile changedFile = _workspaceService.GetFile(notification.TextDocument.Uri.ToString());
+ ScriptFile changedFile = _workspaceService.GetFile(notification.TextDocument.Uri);
// A text change notification can batch multiple change requests
foreach (TextDocumentContentChangeEvent textChange in notification.ContentChanges)
@@ -85,7 +85,7 @@ public Task Handle(DidOpenTextDocumentParams notification, CancellationTok
{
ScriptFile openedFile =
_workspaceService.GetFileBuffer(
- notification.TextDocument.Uri.ToString(),
+ notification.TextDocument.Uri,
notification.TextDocument.Text);
// TODO: Get all recently edited files in the workspace
@@ -106,7 +106,7 @@ TextDocumentRegistrationOptions IRegistration.G
public Task Handle(DidCloseTextDocumentParams notification, CancellationToken token)
{
// Find and close the file in the current session
- var fileToClose = _workspaceService.GetFile(notification.TextDocument.Uri.ToString());
+ var fileToClose = _workspaceService.GetFile(notification.TextDocument.Uri);
if (fileToClose != null)
{
@@ -120,9 +120,7 @@ public Task Handle(DidCloseTextDocumentParams notification, CancellationTo
public async Task Handle(DidSaveTextDocumentParams notification, CancellationToken token)
{
- ScriptFile savedFile =
- _workspaceService.GetFile(
- notification.TextDocument.Uri.ToString());
+ ScriptFile savedFile = _workspaceService.GetFile(notification.TextDocument.Uri);
if (savedFile != null)
{
diff --git a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs
index da1ba6f21..c10c138e7 100644
--- a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs
+++ b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs
@@ -90,15 +90,6 @@ private bool IsQueryMatch(string query, string symbolName)
return symbolName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;
}
- private static string GetFileUri(string filePath)
- {
- // If the file isn't untitled, return a URI-style path
- return
- !filePath.StartsWith("untitled") && !filePath.StartsWith("inmemory")
- ? new Uri("file://" + filePath).AbsoluteUri
- : filePath;
- }
-
private static Range GetRangeFromScriptRegion(ScriptRegion scriptRegion)
{
return new Range
diff --git a/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs b/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs
index cae7e36a7..dba1362c3 100644
--- a/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs
+++ b/src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs
@@ -96,33 +96,18 @@ public WorkspaceService(ILoggerFactory factory)
#region Public Methods
///
- /// Creates a new ScriptFile instance which is identified by the given file
- /// path and initially contains the given buffer contents.
+ /// Gets an open file in the workspace. If the file isn't open but exists on the filesystem, load and return it.
+ /// IMPORTANT: Not all documents have a backing file e.g. untitled: scheme documents. Consider using
+ /// instead.
///
- /// The file path for which a buffer will be retrieved.
- /// The initial buffer contents if there is not an existing ScriptFile for this path.
- /// A ScriptFile instance for the specified path.
- public ScriptFile CreateScriptFileFromFileBuffer(string filePath, string initialBuffer)
- {
- Validate.IsNotNullOrEmptyString("filePath", filePath);
-
- // Resolve the full file path
- string resolvedFilePath = this.ResolveFilePath(filePath);
- string keyName = resolvedFilePath.ToLower();
-
- ScriptFile scriptFile =
- new ScriptFile(
- resolvedFilePath,
- filePath,
- initialBuffer,
- powerShellVersion);
-
- workspaceFiles[keyName] = scriptFile;
-
- logger.LogDebug("Opened file as in-memory buffer: " + resolvedFilePath);
-
- return scriptFile;
- }
+ /// The file path at which the script resides.
+ ///
+ /// is not found.
+ ///
+ ///
+ /// contains a null or empty string.
+ ///
+ public ScriptFile GetFile(string filePath) => GetFile(new Uri(filePath));
///
/// Gets an open file in the workspace. If the file isn't open but exists on the filesystem, load and return it.
@@ -136,33 +121,36 @@ public ScriptFile CreateScriptFileFromFileBuffer(string filePath, string initial
///
/// contains a null or empty string.
///
- public ScriptFile GetFile(string filePath)
+ public ScriptFile GetFile(Uri fileUri)
{
- Validate.IsNotNullOrEmptyString("filePath", filePath);
+ Validate.IsNotNull(nameof(fileUri), fileUri);
// Resolve the full file path
- string resolvedFilePath = this.ResolveFilePath(filePath);
- string keyName = resolvedFilePath.ToLower();
+ Uri resolvedFileUri = ResolveFileUri(fileUri);
+
+ string keyName = VersionUtils.IsLinux
+ ? resolvedFileUri.OriginalString
+ : resolvedFileUri.OriginalString.ToLower();
// Make sure the file isn't already loaded into the workspace
if (!this.workspaceFiles.TryGetValue(keyName, out ScriptFile scriptFile))
{
// This method allows FileNotFoundException to bubble up
// if the file isn't found.
- using (FileStream fileStream = new FileStream(resolvedFilePath, FileMode.Open, FileAccess.Read))
+ using (FileStream fileStream = new FileStream(resolvedFileUri.LocalPath, FileMode.Open, FileAccess.Read))
using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
scriptFile =
new ScriptFile(
- resolvedFilePath,
- filePath,
+ resolvedFileUri.LocalPath,
+ resolvedFileUri.OriginalString,
streamReader,
this.powerShellVersion);
this.workspaceFiles.Add(keyName, scriptFile);
}
- this.logger.LogDebug("Opened file on disk: " + resolvedFilePath);
+ this.logger.LogDebug("Opened file on disk: " + resolvedFileUri.OriginalString);
}
return scriptFile;
@@ -173,10 +161,16 @@ public ScriptFile GetFile(string filePath)
///
/// The file path at which the script resides.
/// The out parameter that will contain the ScriptFile object.
- public bool TryGetFile(string filePath, out ScriptFile scriptFile)
- {
- var fileUri = new Uri(filePath);
+ public bool TryGetFile(string filePath, out ScriptFile scriptFile) =>
+ TryGetFile(new Uri(filePath), out scriptFile);
+ ///
+ /// Tries to get an open file in the workspace. Returns true if it succeeds, false otherwise.
+ ///
+ /// The file uri at which the script resides.
+ /// The out parameter that will contain the ScriptFile object.
+ public bool TryGetFile(Uri fileUri, out ScriptFile scriptFile)
+ {
switch (fileUri.Scheme)
{
// List supported schemes here
@@ -191,7 +185,7 @@ public bool TryGetFile(string filePath, out ScriptFile scriptFile)
try
{
- scriptFile = GetFile(filePath);
+ scriptFile = GetFile(fileUri);
return true;
}
catch (Exception e) when (
@@ -203,7 +197,7 @@ e is IOException ||
e is SecurityException ||
e is UnauthorizedAccessException)
{
- this.logger.LogWarning($"Failed to get file for {nameof(filePath)}: '{filePath}'", e);
+ this.logger.LogWarning($"Failed to get file for fileUri: '{fileUri.OriginalString}'", e);
scriptFile = null;
return false;
}
@@ -214,10 +208,7 @@ e is SecurityException ||
///
/// The file path for which a buffer will be retrieved.
/// A ScriptFile instance if there is a buffer for the path, null otherwise.
- public ScriptFile GetFileBuffer(string filePath)
- {
- return this.GetFileBuffer(filePath, null);
- }
+ public ScriptFile GetFileBuffer(string filePath) => GetFileBuffer(filePath, initialBuffer: null);
///
/// Gets a new ScriptFile instance which is identified by the given file
@@ -226,27 +217,46 @@ public ScriptFile GetFileBuffer(string filePath)
/// The file path for which a buffer will be retrieved.
/// The initial buffer contents if there is not an existing ScriptFile for this path.
/// A ScriptFile instance for the specified path.
- public ScriptFile GetFileBuffer(string filePath, string initialBuffer)
+ public ScriptFile GetFileBuffer(string filePath, string initialBuffer) => GetFileBuffer(new Uri(filePath), initialBuffer);
+
+ ///
+ /// Gets a new ScriptFile instance which is identified by the given file path.
+ ///
+ /// The file Uri for which a buffer will be retrieved.
+ /// A ScriptFile instance if there is a buffer for the path, null otherwise.
+ public ScriptFile GetFileBuffer(Uri fileUri) => GetFileBuffer(fileUri, initialBuffer: null);
+
+ ///
+ /// Gets a new ScriptFile instance which is identified by the given file
+ /// path and initially contains the given buffer contents.
+ ///
+ /// The file Uri for which a buffer will be retrieved.
+ /// The initial buffer contents if there is not an existing ScriptFile for this path.
+ /// A ScriptFile instance for the specified path.
+ public ScriptFile GetFileBuffer(Uri fileUri, string initialBuffer)
{
- Validate.IsNotNullOrEmptyString("filePath", filePath);
+ Validate.IsNotNull(nameof(fileUri), fileUri);
// Resolve the full file path
- string resolvedFilePath = this.ResolveFilePath(filePath);
- string keyName = resolvedFilePath.ToLower();
+ Uri resolvedFileUri = ResolveFileUri(fileUri);
+
+ string keyName = VersionUtils.IsLinux
+ ? resolvedFileUri.OriginalString
+ : resolvedFileUri.OriginalString.ToLower();
// Make sure the file isn't already loaded into the workspace
if (!this.workspaceFiles.TryGetValue(keyName, out ScriptFile scriptFile) && initialBuffer != null)
{
scriptFile =
new ScriptFile(
- resolvedFilePath,
- filePath,
+ resolvedFileUri.LocalPath,
+ resolvedFileUri.OriginalString,
initialBuffer,
this.powerShellVersion);
- this.workspaceFiles.Add(keyName, scriptFile);
+ this.workspaceFiles[keyName] = scriptFile;
- this.logger.LogDebug("Opened file as in-memory buffer: " + resolvedFilePath);
+ this.logger.LogDebug("Opened file as in-memory buffer: " + resolvedFileUri.OriginalString);
}
return scriptFile;
@@ -452,6 +462,17 @@ internal string ResolveFilePath(string filePath)
return filePath;
}
+ internal Uri ResolveFileUri(Uri fileUri)
+ {
+ if (fileUri.IsFile)
+ {
+ fileUri = WorkspaceService.UnescapeDriveColon(fileUri);
+ }
+
+ this.logger.LogDebug("Resolved path: " + fileUri.OriginalString);
+ return fileUri;
+ }
+
internal static bool IsPathInMemory(string filePath)
{
bool isInMemory = false;
@@ -590,6 +611,42 @@ private static string UnescapeDriveColon(string fileUri)
return sb.ToString();
}
+ private static Uri UnescapeDriveColon(Uri fileUri)
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return fileUri;
+ }
+
+ string driveSegment = fileUri.Segments[1];
+ // Check here that we have something like "file:///C%3A/" as a prefix (caller must check the file:// part)
+ if (!(char.IsLetter(driveSegment[0]) &&
+ driveSegment[1] == '%' &&
+ driveSegment[2] == '3' &&
+ driveSegment[3] == 'A' &&
+ driveSegment[4] == '/'))
+ {
+ return fileUri;
+ }
+
+ // We lost "%3A" and gained ":", so length - 2
+ var sb = new StringBuilder(fileUri.OriginalString.Length - 2);
+ sb.Append("file:///");
+
+ // The drive letter.
+ sb.Append(driveSegment[0]);
+ sb.Append(":/");
+
+ // The rest of the URI after the colon.
+ // Skip the first two segments which are / and the drive.
+ for (int i = 2; i < fileUri.Segments.Length; i++)
+ {
+ sb.Append(fileUri.Segments[i]);
+ }
+
+ return new Uri(sb.ToString());
+ }
+
///
/// Converts a file system path into a DocumentUri required by Language Server Protocol.
///
diff --git a/src/PowerShellEditorServices/Utility/PathUtils.cs b/src/PowerShellEditorServices/Utility/PathUtils.cs
index 13a8cccd0..26deebd72 100644
--- a/src/PowerShellEditorServices/Utility/PathUtils.cs
+++ b/src/PowerShellEditorServices/Utility/PathUtils.cs
@@ -53,20 +53,6 @@ public static Uri ToUri(string filePath)
return new Uri($"file://{filePath}");
}
- public static string FromUri(Uri uri)
- {
- if (uri.Segments.Length > 1)
- {
- // On windows of the Uri contains %3a local path
- // doesn't come out as a proper windows path
- if (uri.Segments[1].IndexOf("%3a", StringComparison.OrdinalIgnoreCase) > -1)
- {
- return FromUri(new Uri(uri.AbsoluteUri.Replace("%3a", ":").Replace("%3A", ":")));
- }
- }
- return uri.LocalPath;
- }
-
///
/// Converts all alternate path separators to the current platform's main path separators.
///
diff --git a/src/PowerShellEditorServices/Utility/VersionUtils.cs b/src/PowerShellEditorServices/Utility/VersionUtils.cs
index 5493467aa..159ceb97a 100644
--- a/src/PowerShellEditorServices/Utility/VersionUtils.cs
+++ b/src/PowerShellEditorServices/Utility/VersionUtils.cs
@@ -53,6 +53,16 @@ internal static class VersionUtils
/// True if we are running in on Windows, false otherwise.
///
public static bool IsWindows { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+
+ ///
+ /// True if we are running in on macOS, false otherwise.
+ ///
+ public static bool IsMacOS { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+
+ ///
+ /// True if we are running in on Linux, false otherwise.
+ ///
+ public static bool IsLinux { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
}
internal static class PowerShellReflectionUtils
diff --git a/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj b/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj
index bfebb3075..5521f4a68 100644
--- a/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj
+++ b/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj
@@ -10,7 +10,7 @@
-
+