Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f80df34

Browse filesBrowse files
auvreddanvk
authored andcommitted
chore(website): [playground] add twoslash queries (typescript-eslint#8119)
1 parent 8070b5e commit f80df34
Copy full SHA for f80df34

File tree

Expand file treeCollapse file tree

2 files changed

+106
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+106
-0
lines changed
+98Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// The following code is adapted from the code in microsoft/TypeScript-Website.
2+
// Source: https://github.com/microsoft/TypeScript-Website/blob/c8b2ea8c8fc216c163fe293650b2666c8563a67d/packages/playground/src/twoslashInlays.ts
3+
// License: https://github.com/microsoft/TypeScript-Website/blob/c8b2ea8c8fc216c163fe293650b2666c8563a67d/LICENSE-CODE
4+
5+
import type Monaco from 'monaco-editor';
6+
import type * as ts from 'typescript';
7+
8+
import type { SandboxInstance } from './useSandboxServices';
9+
10+
function findTwoshashQueries(code: string): RegExpExecArray[] {
11+
let match: RegExpExecArray | null = null;
12+
const matches: RegExpExecArray[] = [];
13+
// RegExp that matches '^<spaces>//?<spaces>$'
14+
const twoslashQueryRegex = /^(\s*\/\/\s*\^\?)\s*$/gm;
15+
while ((match = twoslashQueryRegex.exec(code))) {
16+
matches.push(match);
17+
}
18+
return matches;
19+
}
20+
21+
export function createTwoslashInlayProvider(
22+
sandbox: SandboxInstance,
23+
): Monaco.languages.InlayHintsProvider {
24+
return {
25+
provideInlayHints: async (
26+
model,
27+
_,
28+
cancel,
29+
): Promise<Monaco.languages.InlayHintList> => {
30+
const worker = await sandbox.getWorkerProcess();
31+
if (model.isDisposed() || cancel.isCancellationRequested) {
32+
return {
33+
hints: [],
34+
dispose(): void {
35+
/* nop */
36+
},
37+
};
38+
}
39+
40+
const queryMatches = findTwoshashQueries(model.getValue());
41+
42+
const results: Monaco.languages.InlayHint[] = [];
43+
44+
for (const result of await Promise.all(
45+
queryMatches.map(q => resolveInlayHint(q)),
46+
)) {
47+
if (result) {
48+
results.push(result);
49+
}
50+
}
51+
52+
return {
53+
hints: results,
54+
dispose(): void {
55+
/* nop */
56+
},
57+
};
58+
59+
async function resolveInlayHint(
60+
queryMatch: RegExpExecArray,
61+
): Promise<Monaco.languages.InlayHint | undefined> {
62+
const end = queryMatch.index + queryMatch[1].length - 1;
63+
const endPos = model.getPositionAt(end);
64+
const inspectionPos = new sandbox.monaco.Position(
65+
endPos.lineNumber - 1,
66+
endPos.column,
67+
);
68+
const inspectionOff = model.getOffsetAt(inspectionPos);
69+
70+
const hint = await (worker.getQuickInfoAtPosition(
71+
'file://' + model.uri.path,
72+
inspectionOff,
73+
) as Promise<ts.QuickInfo | undefined>);
74+
if (!hint?.displayParts) {
75+
return;
76+
}
77+
78+
let text = hint.displayParts
79+
.map(d => d.text)
80+
.join('')
81+
.replace(/\r?\n\s*/g, ' ');
82+
if (text.length > 120) {
83+
text = text.slice(0, 119) + '...';
84+
}
85+
86+
return {
87+
kind: sandbox.monaco.languages.InlayHintKind.Type,
88+
position: new sandbox.monaco.Position(
89+
endPos.lineNumber,
90+
endPos.column + 1,
91+
),
92+
label: text,
93+
paddingLeft: true,
94+
};
95+
}
96+
},
97+
};
98+
}

‎packages/website/src/components/editor/useSandboxServices.ts

Copy file name to clipboardExpand all lines: packages/website/src/components/editor/useSandboxServices.ts
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { createFileSystem } from '../linter/bridge';
1010
import { type CreateLinter, createLinter } from '../linter/createLinter';
1111
import type { PlaygroundSystem } from '../linter/types';
1212
import type { RuleDetails } from '../types';
13+
import { createTwoslashInlayProvider } from './createProvideTwoslashInlay';
1314
import { editorEmbedId } from './EditorEmbed';
1415
import { sandboxSingleton } from './loadSandbox';
1516
import type { CommonEditorProps } from './types';
@@ -71,6 +72,13 @@ export const useSandboxServices = (
7172
colorMode === 'dark' ? 'vs-dark' : 'vs-light',
7273
);
7374

75+
// registerInlayHintsProvider was added in TS 4.4 and isn't in TS <= 4.3.
76+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
77+
sandboxInstance.monaco.languages.registerInlayHintsProvider?.(
78+
sandboxInstance.language,
79+
createTwoslashInlayProvider(sandboxInstance),
80+
);
81+
7482
const system = createFileSystem(props, sandboxInstance.tsvfs);
7583

7684
const worker = await sandboxInstance.getWorkerProcess();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.