Skip to content

Commit c09fa73

Browse files
committed
Fix unable to open files in problems/peek windows issue
This is due to PSES not properly storing a language client path in the ClientFilePath property of ScriptFile. This change ensures that a ClientFilePath is always stored in the text document Uri that a LSP client expects. This code has mostly been provided by @SeeminglyScience. Thanks for the reference to your code. This fixes issue 1732 in the vscode-powershell repo.
1 parent 5a6299e commit c09fa73

File tree

1 file changed

+54
-2
lines changed

1 file changed

+54
-2
lines changed

src/PowerShellEditorServices/Workspace/ScriptFile.cs

+54-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6-
using Microsoft.PowerShell.EditorServices.Utility;
76
using System;
87
using System.Collections.Generic;
98
using System.IO;
109
using System.Linq;
1110
using System.Management.Automation;
1211
using System.Management.Automation.Language;
12+
using System.Runtime.InteropServices;
13+
using Microsoft.PowerShell.EditorServices.Utility;
1314

1415
namespace Microsoft.PowerShell.EditorServices
1516
{
@@ -27,6 +28,7 @@ public class ScriptFile
2728
};
2829

2930
private Version powerShellVersion;
31+
private string _clientPath;
3032

3133
#endregion
3234

@@ -50,7 +52,20 @@ public string Id
5052
/// <summary>
5153
/// Gets the path which the editor client uses to identify this file.
5254
/// </summary>
53-
public string ClientFilePath { get; private set; }
55+
public string ClientFilePath
56+
{
57+
get { return _clientPath; }
58+
59+
private set
60+
{
61+
if (value == null)
62+
{
63+
throw new ArgumentNullException(nameof(value));
64+
}
65+
66+
_clientPath = GetPathAsClientPath(value);
67+
}
68+
}
5469

5570
/// <summary>
5671
/// Gets or sets a boolean that determines whether
@@ -564,6 +579,43 @@ public BufferRange GetRangeBetweenOffsets(int startOffset, int endOffset)
564579

565580
#region Private Methods
566581

582+
private static string GetPathAsClientPath(string path)
583+
{
584+
const string fileUriPrefix = "file:///";
585+
586+
if (path.StartsWith("untitled:", StringComparison.Ordinal))
587+
{
588+
return path;
589+
}
590+
591+
if (path.StartsWith("file:///", StringComparison.Ordinal))
592+
{
593+
return path;
594+
}
595+
596+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
597+
{
598+
return new Uri(path).AbsoluteUri;
599+
}
600+
601+
// VSCode file URIs on Windows need the drive letter lowercase, and the colon
602+
// URI encoded. System.Uri won't do that, so we manually create the URI.
603+
var newUri = System.Web.HttpUtility.UrlPathEncode(path);
604+
int colonIndex = path.IndexOf(":");
605+
for (var i = colonIndex - 1; i >= 0; i--)
606+
{
607+
newUri.Remove(i, 1);
608+
newUri.Insert(i, char.ToLowerInvariant(path[i]).ToString());
609+
}
610+
611+
return newUri
612+
.Remove(colonIndex, 1)
613+
.Insert(colonIndex, "%3A")
614+
.Replace("\\", "/")
615+
.Insert(0, fileUriPrefix)
616+
.ToString();
617+
}
618+
567619
private void SetFileContents(string fileContents)
568620
{
569621
// Split the file contents into lines and trim

0 commit comments

Comments
 (0)