Skip to content

Commit 7d8d2e3

Browse files
authored
add windows support (#13)
* add windows support * Update open-in-vscode.ts
1 parent efee2cb commit 7d8d2e3

File tree

2 files changed

+167
-2
lines changed

2 files changed

+167
-2
lines changed

src/open-in-vscode.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as sourcegraph from 'sourcegraph'
2-
import * as path from 'path'
2+
import path from './path'
33

44
function getOpenUrl(textDocumentUri: URL): URL {
55
const rawRepoName = decodeURIComponent(textDocumentUri.hostname + textDocumentUri.pathname)
@@ -18,7 +18,15 @@ function getOpenUrl(textDocumentUri: URL): URL {
1818
}
1919
const relativePath = decodeURIComponent(textDocumentUri.hash.slice('#'.length))
2020
const absolutePath = path.join(basePath, repoBaseName, relativePath)
21-
const openUrl = new URL('vscode://file' + absolutePath)
21+
22+
// if windows add an extra slash in the beginning
23+
let uri = '';
24+
if (/^[a-zA-Z]:\\/.test(basePath)) {
25+
uri = 'vscode://file/' + absolutePath
26+
} else {
27+
uri = 'vscode://file' + absolutePath
28+
}
29+
const openUrl = new URL(uri)
2230
if (sourcegraph.app.activeWindow?.activeViewComponent?.type === 'CodeEditor') {
2331
const selection = sourcegraph.app.activeWindow?.activeViewComponent?.selection
2432
if (selection) {

src/path.ts

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// 'path' module extracted from Node.js v8.11.1 (only the posix part)
2+
// transplited with Babel, some manual changes
3+
4+
function assertPath(path: string): void {
5+
if (typeof path !== 'string') {
6+
throw new TypeError('Path must be a string. Received ' + JSON.stringify(path))
7+
}
8+
}
9+
10+
// Resolves . and .. elements in a path with directory names
11+
function normalizeStringPosix(path: string, allowAboveRoot: boolean): string {
12+
let res = ''
13+
let lastSegmentLength = 0
14+
let lastSlash = -1
15+
let dots = 0
16+
let code
17+
for (let i = 0; i <= path.length; ++i) {
18+
if (i < path.length) {
19+
code = path.charCodeAt(i)
20+
} else if (code === 47) {
21+
break
22+
} else {
23+
code = 47
24+
}
25+
if (code === 47) {
26+
if (lastSlash === i - 1 || dots === 1) {
27+
// NOOP
28+
} else if (lastSlash !== i - 1 && dots === 2) {
29+
if (
30+
res.length < 2 ||
31+
lastSegmentLength !== 2 ||
32+
res.charCodeAt(res.length - 1) !== 46 ||
33+
res.charCodeAt(res.length - 2) !== 46
34+
) {
35+
if (res.length > 2) {
36+
const lastSlashIndex = res.lastIndexOf('/')
37+
if (lastSlashIndex !== res.length - 1) {
38+
if (lastSlashIndex === -1) {
39+
res = ''
40+
lastSegmentLength = 0
41+
} else {
42+
res = res.slice(0, lastSlashIndex)
43+
lastSegmentLength = res.length - 1 - res.lastIndexOf('/')
44+
}
45+
lastSlash = i
46+
dots = 0
47+
continue
48+
}
49+
} else if (res.length === 2 || res.length === 1) {
50+
res = ''
51+
lastSegmentLength = 0
52+
lastSlash = i
53+
dots = 0
54+
continue
55+
}
56+
}
57+
if (allowAboveRoot) {
58+
if (res.length > 0) {
59+
res += '/..'
60+
} else {
61+
res = '..'
62+
}
63+
lastSegmentLength = 2
64+
}
65+
} else {
66+
if (res.length > 0) {
67+
res += '/' + path.slice(lastSlash + 1, i)
68+
} else {
69+
res = path.slice(lastSlash + 1, i)
70+
}
71+
lastSegmentLength = i - lastSlash - 1
72+
}
73+
lastSlash = i
74+
dots = 0
75+
} else if (code === 46 && dots !== -1) {
76+
++dots
77+
} else {
78+
dots = -1
79+
}
80+
}
81+
return res
82+
}
83+
84+
const posix = {
85+
/**
86+
* Making sure the paths are correctly formatted is beyond the scope of this pollyfill
87+
*/
88+
normalize: (path: string) => {
89+
assertPath(path)
90+
91+
if (path.length === 0) {
92+
return '.'
93+
}
94+
95+
// If windows-path replace slashes
96+
if (/^[a-zA-Z]:\\/.test(path)) {
97+
path = path.replace(/\\/g, '/')
98+
}
99+
100+
const isAbsolute = posix.isAbsolute(path)
101+
const trailingSeparator = path.charCodeAt(path.length - 1) === 47
102+
103+
// Normalize the path
104+
path = normalizeStringPosix(path, !isAbsolute)
105+
106+
if (path.length === 0 && !isAbsolute) {
107+
path = '.'
108+
}
109+
if (path.length > 0 && trailingSeparator) {
110+
path += '/'
111+
}
112+
113+
if (isAbsolute) {
114+
return '/' + path
115+
}
116+
return path
117+
},
118+
isAbsolute: (path: string) => {
119+
assertPath(path)
120+
if (path.length === 0) {
121+
return false
122+
}
123+
let isAbsolute = true
124+
125+
if (path.charCodeAt(0) === 47) {
126+
isAbsolute = true
127+
} else if (/^[a-zA-Z]:\\/.test(path)) {
128+
isAbsolute = true
129+
} else {
130+
isAbsolute = false
131+
}
132+
133+
return isAbsolute
134+
},
135+
join: (...args: string[]) => {
136+
if (args.length === 0) {
137+
return '.'
138+
}
139+
let joined
140+
for (const arg of args) {
141+
assertPath(arg)
142+
if (arg.length > 0) {
143+
if (joined === undefined) {
144+
joined = arg
145+
} else {
146+
joined += '/' + arg
147+
}
148+
}
149+
}
150+
if (joined === undefined) {
151+
return '.'
152+
}
153+
return posix.normalize(joined)
154+
},
155+
}
156+
157+
export default posix

0 commit comments

Comments
 (0)