Skip to content

Commit 6f5fc97

Browse files
committed
wip
1 parent 16f5515 commit 6f5fc97

3 files changed

Lines changed: 74 additions & 15 deletions

File tree

packages/ts-plugin/src/index.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import type { CMKConfig } from '@css-modules-kit/core';
22
import { createMatchesPattern, createResolver, readConfigFile } from '@css-modules-kit/core';
33
import { TsConfigFileNotFoundError } from '@css-modules-kit/core';
44
import { createLanguageServicePlugin } from '@volar/typescript/lib/quickstart/createLanguageServicePlugin.js';
5-
import { createCSSLanguagePlugin } from './language-plugin.js';
5+
import { CMK_DATA_KEY, createCSSLanguagePlugin, isCSSModuleScript } from './language-plugin.js';
66
import { proxyLanguageService } from './language-service/proxy.js';
7+
import type { DocumentLink } from './type.js';
78

89
const plugin = createLanguageServicePlugin((ts, info) => {
910
if (info.project.projectKind !== ts.server.ProjectKind.Configured) {
@@ -15,6 +16,7 @@ const plugin = createLanguageServicePlugin((ts, info) => {
1516
info.project.projectService.logger.info('[@css-modules-kit/ts-plugin] info: Session is not available');
1617
return { languagePlugins: [] };
1718
}
19+
const session = info.session;
1820

1921
let config: CMKConfig;
2022
try {
@@ -55,17 +57,6 @@ const plugin = createLanguageServicePlugin((ts, info) => {
5557
const resolver = createResolver(config.compilerOptions, moduleResolutionCache);
5658
const matchesPattern = createMatchesPattern(config);
5759

58-
info.session.addProtocolHandler('_css-modules-kit:rename', (request) => {
59-
const { fileName, position } = request.arguments;
60-
const result = info.languageService.findRenameLocations(fileName, position, false, false, {});
61-
return { response: { result } };
62-
});
63-
info.session.addProtocolHandler('_css-modules-kit:renameInfo', (request) => {
64-
const { fileName, position } = request.arguments;
65-
const result = info.languageService.getRenameInfo(fileName, position, {});
66-
return { response: { result } };
67-
});
68-
6960
return {
7061
languagePlugins: [createCSSLanguagePlugin(resolver, matchesPattern, config)],
7162
setup: (language) => {
@@ -77,6 +68,33 @@ const plugin = createLanguageServicePlugin((ts, info) => {
7768
matchesPattern,
7869
config,
7970
);
71+
session.addProtocolHandler('_css-modules-kit:rename', (request) => {
72+
const { fileName, position } = request.arguments;
73+
const result = info.languageService.findRenameLocations(fileName, position, false, false, {});
74+
return { response: { result } };
75+
});
76+
session.addProtocolHandler('_css-modules-kit:renameInfo', (request) => {
77+
const { fileName, position } = request.arguments;
78+
const result = info.languageService.getRenameInfo(fileName, position, {});
79+
return { response: { result } };
80+
});
81+
session.addProtocolHandler('_css-modules-kit:documentLink', (request) => {
82+
const { fileName } = request.arguments;
83+
const script = language.scripts.get(fileName);
84+
const links: DocumentLink[] = [];
85+
if (isCSSModuleScript(script)) {
86+
const { tokenImporters } = script.generated.root[CMK_DATA_KEY].cssModule;
87+
for (const { from, fromLoc } of tokenImporters) {
88+
const resolved = resolver(from, { request: fileName });
89+
if (!resolved) continue;
90+
links.push({
91+
fileName: resolved,
92+
textSpan: { start: fromLoc.start.offset, length: fromLoc.end.offset - fromLoc.start.offset },
93+
});
94+
}
95+
}
96+
return { response: { result: links } };
97+
});
8098
},
8199
};
82100
});

packages/ts-plugin/src/type.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,26 @@ export interface CSSModulesKitRenameInfoResponse extends ts.server.protocol.Resp
3030
readonly body: CSSModulesKitRenameInfoHandlerResponse['response'];
3131
}
3232

33+
export interface DocumentLink {
34+
fileName: string;
35+
textSpan: ts.TextSpan;
36+
}
37+
export interface CSSModulesKitDocumentLinkRequest extends ts.server.protocol.Request {
38+
command: '_css-modules-kit:documentLink';
39+
arguments: {
40+
fileName: string;
41+
};
42+
}
43+
export interface CSSModulesKitDocumentLinkHandlerResponse extends ts.server.HandlerResponse {
44+
response: {
45+
result: DocumentLink[];
46+
};
47+
}
48+
export interface CSSModulesKitDocumentLinkResponse extends ts.server.protocol.Response {
49+
command: '_css-modules-kit:documentLink';
50+
readonly body: CSSModulesKitDocumentLinkHandlerResponse['response'];
51+
}
52+
3353
declare module 'typescript' {
3454
// eslint-disable-next-line @typescript-eslint/no-namespace
3555
namespace server {
@@ -42,6 +62,10 @@ declare module 'typescript' {
4262
command: '_css-modules-kit:renameInfo',
4363
handler: (request: CSSModulesKitRenameInfoRequest) => CSSModulesKitRenameInfoHandlerResponse,
4464
): void;
65+
addProtocolHandler(
66+
command: '_css-modules-kit:documentLink',
67+
handler: (request: CSSModulesKitDocumentLinkRequest) => CSSModulesKitDocumentLinkHandlerResponse,
68+
): void;
4569
}
4670
}
4771
}

packages/vscode/src/index.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* eslint-disable no-console */
22

33
import type {
4+
CSSModulesKitDocumentLinkRequest,
5+
CSSModulesKitDocumentLinkResponse,
46
CSSModulesKitRenameInfoRequest,
57
CSSModulesKitRenameInfoResponse,
68
CSSModulesKitRenameRequest,
@@ -63,9 +65,24 @@ export async function activate(context: vscode.ExtensionContext) {
6365
vscode.languages.registerDocumentLinkProvider(
6466
{ scheme: 'file', language: 'css' },
6567
{
66-
provideDocumentLinks(document, _token) {
67-
// TODO
68-
return [];
68+
async provideDocumentLinks(document, _token) {
69+
const res = await vscode.commands.executeCommand<CSSModulesKitDocumentLinkResponse>(
70+
'typescript.tsserverRequest',
71+
'_css-modules-kit:documentLink',
72+
{
73+
fileName: document.fileName,
74+
} satisfies CSSModulesKitDocumentLinkRequest['arguments'],
75+
);
76+
if (!res.success || !res.body.result) return [];
77+
return res.body.result.map((link) => {
78+
return new vscode.DocumentLink(
79+
new vscode.Range(
80+
document.positionAt(link.textSpan.start),
81+
document.positionAt(link.textSpan.start + link.textSpan.length),
82+
),
83+
vscode.Uri.file(link.fileName),
84+
);
85+
});
6986
},
7087
},
7188
),

0 commit comments

Comments
 (0)