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 @@ - +