Skip to content

Commit 327a1a1

Browse files
authored
fix(language-server): add support of URI fragments in UriConverter (#276)
1 parent 5b28063 commit 327a1a1

File tree

4 files changed

+27
-5
lines changed

4 files changed

+27
-5
lines changed

.github/workflows/auto-fix.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515

1616
- uses: actions/setup-node@v4
1717
with:
18-
node-version: 20
18+
node-version: 22
1919
cache: pnpm
2020

2121
- run: pnpm install

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88

99
strategy:
1010
matrix:
11-
node-version: [18]
11+
node-version: [22]
1212
os: [macos-latest, windows-latest, ubuntu-latest]
1313

1414
steps:

packages/language-server/lib/project/typescriptProject.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ export function createTypeScriptProject(
274274
export function createUriConverter(rootFolders: URI[]) {
275275
const encodeds = new Map<string, URI>();
276276
const isFileScheme = rootFolders.every(folder => folder.scheme === 'file');
277+
const fragmentPrefix = '/' + encodeURIComponent('#');
277278

278279
return {
279280
asFileName,
@@ -291,7 +292,8 @@ export function createUriConverter(rootFolders: URI[]) {
291292
}
292293
const encoded = encodeURIComponent(`${parsed.scheme}://${parsed.authority}`);
293294
encodeds.set(encoded, parsed);
294-
return `/${encoded}${parsed.path}`;
295+
const fragment = parsed.fragment ? fragmentPrefix + encodeURIComponent(parsed.fragment) : '';
296+
return `/${encoded}${parsed.path}${fragment}`;
295297
}
296298

297299
function asUri(fileName: string) {
@@ -308,7 +310,7 @@ export function createUriConverter(rootFolders: URI[]) {
308310
return URI.from({
309311
scheme: uri.scheme,
310312
authority: uri.authority,
311-
path: fileName.substring(prefix.length),
313+
...getComponents(fileName, prefix.length),
312314
});
313315
}
314316
}
@@ -317,7 +319,7 @@ export function createUriConverter(rootFolders: URI[]) {
317319
return URI.from({
318320
scheme: uri.scheme,
319321
authority: uri.authority,
320-
path: fileName.substring(prefix.length),
322+
...getComponents(fileName, prefix.length),
321323
});
322324
}
323325
}
@@ -329,6 +331,22 @@ export function createUriConverter(rootFolders: URI[]) {
329331
}
330332
return URI.file(fileName);
331333
}
334+
335+
function getComponents(fileName: string, prefixLength: number) {
336+
// Fragment is present when the fileName contains the fragment prefix and is not followed by a slash.
337+
const fragmentPosition = fileName.lastIndexOf(fragmentPrefix);
338+
if (fragmentPosition >= prefixLength) {
339+
if (fileName.indexOf('/', fragmentPosition + fragmentPrefix.length) < 0) {
340+
return {
341+
path: fileName.substring(prefixLength, fragmentPosition),
342+
fragment: decodeURIComponent(fileName.substring(fragmentPosition + fragmentPrefix.length)),
343+
};
344+
}
345+
}
346+
return {
347+
path: fileName.substring(prefixLength),
348+
};
349+
}
332350
}
333351

334352
export function sortTSConfigs(file: string, a: string, b: string) {

packages/language-server/tests/uri.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ describe('URI', () => {
1212
'file:///c:/a/b/c',
1313
'file:///C:/a/b/c',
1414
'untitled:Untitled-1',
15+
'vscode-notebook-cell:///a/b/c.one.ts',
16+
'vscode-notebook-cell:///a/b/c.one.ts#xdf4Gt6/a',
17+
'vscode-notebook-cell:///a/b/c.one.ts##a/%/v',
1518
];
1619

1720
for (const uri of cases) {
@@ -26,6 +29,7 @@ describe('URI', () => {
2629

2730
expect(uriConverter.asFileName(URI.parse('http://a/b'))).toBe('/b');
2831
expect(uriConverter.asFileName(URI.parse('https://a/b'))).toBe('/https%3A%2F%2Fa/b');
32+
expect(uriConverter.asFileName(URI.parse('https://a/b/##a/%/v'))).toBe('/https%3A%2F%2Fa/b//%23%23a%2F%25%2Fv');
2933

3034
expect(uriConverter.asUri('/b').toString()).toBe('http://a/b');
3135
expect(uriConverter.asUri('/c').toString()).toBe('http://a/c');

0 commit comments

Comments
 (0)