@@ -11,6 +11,8 @@ import (
11
11
"net/url"
12
12
"path/filepath"
13
13
"regexp"
14
+ "strings"
15
+ "unicode"
14
16
15
17
"github.com/arduino/go-paths-helper"
16
18
"go.bug.st/json"
@@ -29,7 +31,11 @@ type DocumentURI struct {
29
31
// NilURI is the empty DocumentURI
30
32
var NilURI = DocumentURI {}
31
33
32
- var expDriveID = regexp .MustCompile ("^/[a-zA-Z]:" )
34
+ // for example, `"/c:"` or `"/A:"`
35
+ var expDriveWithLeadingSlashID = regexp .MustCompile ("^/[a-zA-Z]:" )
36
+
37
+ // for example, `"C:"` or `"A:"`
38
+ var expUppercaseDriveID = regexp .MustCompile ("^[A-Z]:" )
33
39
34
40
// AsPath convert the DocumentURI to a paths.Path
35
41
func (uri DocumentURI ) AsPath () * paths.Path {
@@ -39,12 +45,23 @@ func (uri DocumentURI) AsPath() *paths.Path {
39
45
// unbox convert the DocumentURI to a file path string
40
46
func (uri DocumentURI ) unbox () string {
41
47
path := uri .url .Path
42
- if expDriveID .MatchString (path ) {
48
+ if expDriveWithLeadingSlashID .MatchString (path ) {
43
49
return path [1 :]
44
50
}
45
51
return path
46
52
}
47
53
54
+ // Converts `"C:"` to `"c:"` to be compatible with VS Code URI's drive letter casing
55
+ // https://github.com/Microsoft/vscode/issues/68325#issuecomment-462239992
56
+ func lowercaseDriveSegment (pathSegment string ) string {
57
+ if expUppercaseDriveID .MatchString (pathSegment ) {
58
+ chars := []rune (pathSegment )
59
+ chars [0 ] = unicode .ToLower (chars [0 ])
60
+ return string (chars )
61
+ }
62
+ return pathSegment
63
+ }
64
+
48
65
func (uri DocumentURI ) String () string {
49
66
return uri .url .String ()
50
67
}
@@ -68,11 +85,23 @@ func NewDocumentURI(path string) DocumentURI {
68
85
if len (path ) == 0 || path [0 ] != '/' {
69
86
path = "/" + path
70
87
}
71
- uri , err := NewDocumentURIFromURL ("file://" )
88
+ segments := strings .Split (path , "/" )
89
+ encodedSegments := make ([]string , len (segments ))
90
+ for i , segment := range segments {
91
+ if len (segment ) == 0 {
92
+ encodedSegments [i ] = segment
93
+ } else {
94
+ segment = lowercaseDriveSegment (segment )
95
+ segment = url .QueryEscape (segment )
96
+ // Spaces must be turned into `%20`. Otherwise, `url.QueryEscape`` encodes them to `+`.
97
+ encodedSegments [i ] = strings .ReplaceAll (segment , "+" , "%20" )
98
+ }
99
+ }
100
+ urlPath := strings .Join (encodedSegments , "/" )
101
+ uri , err := NewDocumentURIFromURL ("file://" + urlPath )
72
102
if err != nil {
73
103
panic (err )
74
104
}
75
- uri .url .Path = path
76
105
return uri
77
106
}
78
107
@@ -89,7 +118,7 @@ func NewDocumentURIFromURL(inURL string) (DocumentURI, error) {
89
118
func (uri * DocumentURI ) UnmarshalJSON (data []byte ) error {
90
119
var s string
91
120
if err := json .Unmarshal (data , & s ); err != nil {
92
- return fmt .Errorf ("expoected JSON string for DocumentURI: %s" , err )
121
+ return fmt .Errorf ("expected JSON string for DocumentURI: %s" , err )
93
122
}
94
123
95
124
newDocURI , err := NewDocumentURIFromURL (s )
0 commit comments