shareable-twoslash-comments 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.js +138 -65
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
A TypeScript Playground plugin that injects twoslash (// ^?) type hints as literal comments in your code, making them easy to copy and share.
|
|
4
4
|
|
|
5
|
+
This plugin also supports twoslash arrow queries (`//=>`).
|
|
6
|
+
|
|
7
|
+
If placed at the end of a line, it finds the first position on that line with type information and inserts it.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
let foo = 1; //=> number
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
If placed on its own line, it looks at the previous line, finds the first position with type information, and inserts it.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
let foo = 1;
|
|
17
|
+
//=> number
|
|
18
|
+
```
|
|
19
|
+
|
|
5
20
|
https://github.com/user-attachments/assets/5e42a08e-7570-4d04-9434-6a93cd898e7f
|
|
6
21
|
|
|
7
22
|
## Running this plugin
|
package/dist/index.js
CHANGED
|
@@ -59,12 +59,53 @@ define(function () { 'use strict';
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
var twoSlashQueryRegex = /(^[ \t]*)(\/\/\s*\^\?)/gm;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
var twoSlashArrowQueryRegex = /(^.*)\/\/=>/gm;
|
|
63
|
+
function fillTwoSlashQueries(sandbox_1) {
|
|
64
|
+
return __awaiter(this, arguments, void 0, function (sandbox, isUndoRedoChange) {
|
|
65
|
+
function getLeftMostQuickInfo(_a) {
|
|
66
|
+
return __awaiter(this, arguments, void 0, function (_b) {
|
|
67
|
+
var col, quickInfoPos, quickInfoOffset, quickInfo;
|
|
68
|
+
var line = _b.line, column = _b.column;
|
|
69
|
+
return __generator(this, function (_c) {
|
|
70
|
+
switch (_c.label) {
|
|
71
|
+
case 0:
|
|
72
|
+
col = column;
|
|
73
|
+
_c.label = 1;
|
|
74
|
+
case 1:
|
|
75
|
+
if (!(col <= model.getLineContent(line).length)) return [3 /*break*/, 4];
|
|
76
|
+
quickInfoPos = new sandbox.monaco.Position(line, col);
|
|
77
|
+
quickInfoOffset = model.getOffsetAt(quickInfoPos);
|
|
78
|
+
return [4 /*yield*/, worker.getQuickInfoAtPosition("file://" + model.uri.path, quickInfoOffset)];
|
|
79
|
+
case 2:
|
|
80
|
+
quickInfo = _c.sent();
|
|
81
|
+
if (quickInfo === null || quickInfo === void 0 ? void 0 : quickInfo.displayParts) {
|
|
82
|
+
return [2 /*return*/, quickInfo.displayParts.map(function (d) { return d.text; }).join("")];
|
|
83
|
+
}
|
|
84
|
+
_c.label = 3;
|
|
85
|
+
case 3:
|
|
86
|
+
col++;
|
|
87
|
+
return [3 /*break*/, 1];
|
|
88
|
+
case 4: return [2 /*return*/, ""];
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function getPreviousQuickInfoComment(_a) {
|
|
94
|
+
var lineNumber = _a.lineNumber, commentPrefix = _a.commentPrefix;
|
|
95
|
+
var prevQuickInfoLines = [model.getLineContent(lineNumber)];
|
|
96
|
+
for (var currLineNumber = lineNumber + 1; currLineNumber <= model.getLineCount(); currLineNumber++) {
|
|
97
|
+
var lineContent = model.getLineContent(currLineNumber);
|
|
98
|
+
if (!lineContent.startsWith(commentPrefix)) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
prevQuickInfoLines.push(lineContent);
|
|
102
|
+
}
|
|
103
|
+
return prevQuickInfoLines.join(model.getEOL());
|
|
104
|
+
}
|
|
105
|
+
var multilineEnabled, truncationDisabled, pauseOnError, model, worker, diagnostics, text, editOperations, matches, _i, matches_1, _a, match, queryType, textBeforeQuery, commentPrefix, isInlineArrowQuery, lineNumber, column, caretOffset, caretPos, quickInfoLine, quickInfoString, quickInfoComment, prevQuickInfoComment, prevQuickInfoLines, prevQuickInfoEndLine;
|
|
106
|
+
if (isUndoRedoChange === void 0) { isUndoRedoChange = false; }
|
|
107
|
+
return __generator(this, function (_b) {
|
|
108
|
+
switch (_b.label) {
|
|
68
109
|
case 0:
|
|
69
110
|
multilineEnabled = localStorage.getItem("shareable-twoslash-comments/enable-multiline-comments") === "true";
|
|
70
111
|
truncationDisabled = localStorage.getItem("shareable-twoslash-comments/disable-truncation") === "true";
|
|
@@ -72,76 +113,93 @@ define(function () { 'use strict';
|
|
|
72
113
|
model = sandbox.getModel();
|
|
73
114
|
return [4 /*yield*/, sandbox.getWorkerProcess()];
|
|
74
115
|
case 1:
|
|
75
|
-
worker =
|
|
116
|
+
worker = _b.sent();
|
|
76
117
|
if (!pauseOnError) return [3 /*break*/, 3];
|
|
77
118
|
return [4 /*yield*/, Promise.all([
|
|
78
119
|
worker.getSyntacticDiagnostics("file://" + model.uri.path),
|
|
79
120
|
worker.getSemanticDiagnostics("file://" + model.uri.path),
|
|
80
121
|
])];
|
|
81
122
|
case 2:
|
|
82
|
-
diagnostics =
|
|
123
|
+
diagnostics = _b.sent();
|
|
83
124
|
if (diagnostics.flat().length > 0) {
|
|
84
125
|
return [2 /*return*/];
|
|
85
126
|
}
|
|
86
|
-
|
|
127
|
+
_b.label = 3;
|
|
87
128
|
case 3:
|
|
88
129
|
text = model.getValue();
|
|
89
130
|
editOperations = [];
|
|
90
|
-
|
|
91
|
-
|
|
131
|
+
matches = Array.from(text.matchAll(twoSlashQueryRegex))
|
|
132
|
+
.map(function (match) { return ({
|
|
133
|
+
match: match,
|
|
134
|
+
queryType: "twoSlashQuery",
|
|
135
|
+
}); })
|
|
136
|
+
.concat(Array.from(text.matchAll(twoSlashArrowQueryRegex)).map(function (match) { return ({
|
|
137
|
+
match: match,
|
|
138
|
+
queryType: "twoSlashArrowQuery",
|
|
139
|
+
}); }));
|
|
140
|
+
_i = 0, matches_1 = matches;
|
|
141
|
+
_b.label = 4;
|
|
92
142
|
case 4:
|
|
93
|
-
if (!(_i <
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
143
|
+
if (!(_i < matches_1.length)) return [3 /*break*/, 7];
|
|
144
|
+
_a = matches_1[_i], match = _a.match, queryType = _a.queryType;
|
|
145
|
+
textBeforeQuery = match[1];
|
|
146
|
+
commentPrefix = "".concat(" ".repeat(textBeforeQuery.length), "//").padEnd(match[0].length + 1);
|
|
147
|
+
isInlineArrowQuery = queryType === "twoSlashArrowQuery" && textBeforeQuery.trim().length > 0;
|
|
148
|
+
lineNumber = model.getPositionAt(match.index).lineNumber;
|
|
149
|
+
column = model.getLineMinColumn(lineNumber);
|
|
150
|
+
if (queryType === "twoSlashQuery") {
|
|
151
|
+
caretOffset = match.index + match[0].length - 2;
|
|
152
|
+
caretPos = model.getPositionAt(caretOffset);
|
|
153
|
+
lineNumber = caretPos.lineNumber;
|
|
154
|
+
column = caretPos.column;
|
|
155
|
+
}
|
|
156
|
+
quickInfoLine = lineNumber - (isInlineArrowQuery ? 0 : 1);
|
|
157
|
+
if (quickInfoLine < 1) {
|
|
158
|
+
return [3 /*break*/, 6];
|
|
159
|
+
}
|
|
160
|
+
return [4 /*yield*/, getLeftMostQuickInfo({ line: quickInfoLine, column: column })];
|
|
101
161
|
case 5:
|
|
102
|
-
|
|
103
|
-
quickInfoString = (_c = (_b = quickInfo === null || quickInfo === void 0 ? void 0 : quickInfo.displayParts) === null || _b === void 0 ? void 0 : _b.map(function (d) { return d.text; }).join("")) !== null && _c !== void 0 ? _c : "";
|
|
162
|
+
quickInfoString = _b.sent();
|
|
104
163
|
quickInfoComment = "".concat(match[0]).concat(quickInfoString.length > 0 ? " " : "").concat(multilineEnabled
|
|
105
164
|
? quickInfoString.replace(/\r?\n/g, model.getEOL() + commentPrefix)
|
|
106
165
|
: truncate(quickInfoString.replace(/\r?\n\s*/g, " "), truncationDisabled ? Number.POSITIVE_INFINITY : 100));
|
|
107
|
-
prevQuickInfoComment = getPreviousQuickInfoComment({
|
|
108
|
-
model: model,
|
|
109
|
-
lineNumber: caretPos.lineNumber,
|
|
110
|
-
commentPrefix: commentPrefix,
|
|
111
|
-
});
|
|
166
|
+
prevQuickInfoComment = getPreviousQuickInfoComment({ lineNumber: lineNumber, commentPrefix: commentPrefix });
|
|
112
167
|
prevQuickInfoLines = prevQuickInfoComment.split("\n").length;
|
|
113
|
-
prevQuickInfoEndLine =
|
|
168
|
+
prevQuickInfoEndLine = lineNumber + prevQuickInfoLines - 1;
|
|
114
169
|
if (prevQuickInfoComment !== quickInfoComment) {
|
|
115
170
|
editOperations.push({
|
|
116
|
-
range: new sandbox.monaco.Range(
|
|
171
|
+
range: new sandbox.monaco.Range(lineNumber, 0, prevQuickInfoEndLine, model.getLineContent(prevQuickInfoEndLine).length + 1),
|
|
117
172
|
text: quickInfoComment,
|
|
118
173
|
});
|
|
119
174
|
}
|
|
120
|
-
|
|
175
|
+
_b.label = 6;
|
|
121
176
|
case 6:
|
|
122
177
|
_i++;
|
|
123
178
|
return [3 /*break*/, 4];
|
|
124
179
|
case 7:
|
|
125
180
|
if (editOperations.length > 0) {
|
|
126
|
-
|
|
181
|
+
if (!isUndoRedoChange) {
|
|
182
|
+
model.popStackElement();
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
if (isUndoRedoChange) {
|
|
186
|
+
model.applyEdits(editOperations);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
sandbox.editor.executeEdits("shareable-twoslash-comments", editOperations);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
if (!isUndoRedoChange) {
|
|
194
|
+
model.pushStackElement();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
127
197
|
}
|
|
128
198
|
return [2 /*return*/];
|
|
129
199
|
}
|
|
130
200
|
});
|
|
131
201
|
});
|
|
132
202
|
}
|
|
133
|
-
function getPreviousQuickInfoComment(_a) {
|
|
134
|
-
var model = _a.model, lineNumber = _a.lineNumber, commentPrefix = _a.commentPrefix;
|
|
135
|
-
var prevQuickInfoLines = [model.getLineContent(lineNumber)];
|
|
136
|
-
for (var currLineNumber = lineNumber + 1; currLineNumber <= model.getLineCount(); currLineNumber++) {
|
|
137
|
-
var lineContent = model.getLineContent(currLineNumber);
|
|
138
|
-
if (!lineContent.startsWith(commentPrefix)) {
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
prevQuickInfoLines.push(lineContent);
|
|
142
|
-
}
|
|
143
|
-
return prevQuickInfoLines.join(model.getEOL());
|
|
144
|
-
}
|
|
145
203
|
function debounce(callback, delay) {
|
|
146
204
|
if (delay === void 0) { delay = 1000; }
|
|
147
205
|
var timeoutId;
|
|
@@ -172,11 +230,21 @@ define(function () { 'use strict';
|
|
|
172
230
|
data: { firstMount: true },
|
|
173
231
|
shouldBeSelected: function () { return true; },
|
|
174
232
|
didMount: function (sandbox, container) {
|
|
233
|
+
container.style.paddingRight = "8px";
|
|
175
234
|
// Create a design system object to handle
|
|
176
235
|
// making DOM elements which fit the playground (and handle mobile/light/dark etc)
|
|
177
236
|
var ds = utils.createDesignSystem(container);
|
|
178
237
|
ds.p("This plugin embeds twoslash (// ^?) type hints as literal comments in your code, making them easy to copy and share.");
|
|
179
|
-
|
|
238
|
+
var optionsContainer = document.createElement("div");
|
|
239
|
+
Object.assign(optionsContainer.style, {
|
|
240
|
+
backgroundColor: "var(--raised-background, rgba(0,0,0,0.05))",
|
|
241
|
+
padding: "0 12px",
|
|
242
|
+
margin: "8px 0",
|
|
243
|
+
border: "1px solid var(--border-color, rgba(0,0,0,0.1))",
|
|
244
|
+
});
|
|
245
|
+
container.appendChild(optionsContainer);
|
|
246
|
+
var optionsDs = utils.createDesignSystem(optionsContainer);
|
|
247
|
+
optionsDs.showOptionList([
|
|
180
248
|
{
|
|
181
249
|
blurb: "Preserve multiline types instead of collapsing them to a single line.",
|
|
182
250
|
flag: "shareable-twoslash-comments/enable-multiline-comments",
|
|
@@ -198,11 +266,36 @@ define(function () { 'use strict';
|
|
|
198
266
|
], {
|
|
199
267
|
style: "separated",
|
|
200
268
|
});
|
|
269
|
+
ds.p("This plugin also supports twoslash arrow queries (//=>).");
|
|
270
|
+
ds.p("If placed at the end of a line, it finds the first position on that line with type information and inserts it.");
|
|
271
|
+
var code1 = "let foo = 1; //=> number";
|
|
272
|
+
var code1El = ds.code(code1);
|
|
273
|
+
if (code1El.parentElement) {
|
|
274
|
+
code1El.parentElement.style.width = "auto";
|
|
275
|
+
}
|
|
276
|
+
sandbox.monaco.editor.colorize(code1, "typescript", {}).then(function (html) {
|
|
277
|
+
code1El.innerHTML = html;
|
|
278
|
+
});
|
|
279
|
+
ds.p("If placed on its own line, it looks at the previous line, finds the first position with type information, and inserts it.");
|
|
280
|
+
var code2 = "let foo = 1;\n//=> number";
|
|
281
|
+
var code2El = ds.code(code2);
|
|
282
|
+
if (code2El.parentElement) {
|
|
283
|
+
code2El.parentElement.style.width = "auto";
|
|
284
|
+
code2El.parentElement.style.marginBottom = "8px";
|
|
285
|
+
}
|
|
286
|
+
sandbox.monaco.editor.colorize(code2, "typescript", {}).then(function (html) {
|
|
287
|
+
code2El.innerHTML = html;
|
|
288
|
+
});
|
|
201
289
|
var model = sandbox.getModel();
|
|
202
290
|
if (customPlugin.data.firstMount) {
|
|
203
291
|
debouncedFillTwoSlashQueries(sandbox);
|
|
204
|
-
model.onDidChangeContent(function () {
|
|
205
|
-
|
|
292
|
+
model.onDidChangeContent(function (e) {
|
|
293
|
+
if (e.isRedoing || e.isUndoing) {
|
|
294
|
+
fillTwoSlashQueries(sandbox, true);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
debouncedFillTwoSlashQueries(sandbox);
|
|
298
|
+
}
|
|
206
299
|
});
|
|
207
300
|
customPlugin.data.firstMount = false;
|
|
208
301
|
}
|
|
@@ -224,26 +317,6 @@ define(function () { 'use strict';
|
|
|
224
317
|
};
|
|
225
318
|
return customPlugin;
|
|
226
319
|
};
|
|
227
|
-
// type GetLeftMostQuickInfo = (args: {
|
|
228
|
-
// sandbox: Sandbox;
|
|
229
|
-
// model: import("monaco-editor").editor.ITextModel;
|
|
230
|
-
// lineNumber: number;
|
|
231
|
-
// }) => Promise<number | undefined>;
|
|
232
|
-
// const getLeftMostQuickInfo: GetLeftMostQuickInfo = async ({ sandbox, model, lineNumber }) => {
|
|
233
|
-
// const worker = await sandbox.getWorkerProcess();
|
|
234
|
-
// const lineLength = model.getLineContent(lineNumber).length;
|
|
235
|
-
// for (let column = 0; column <= lineLength; column++) {
|
|
236
|
-
// const quickInfoPos = new sandbox.monaco.Position(lineNumber, column);
|
|
237
|
-
// const quickInfoOffset = model.getOffsetAt(quickInfoPos);
|
|
238
|
-
// const quickInfo = await worker.getQuickInfoAtPosition(
|
|
239
|
-
// "file://" + model.uri.path,
|
|
240
|
-
// quickInfoOffset,
|
|
241
|
-
// );
|
|
242
|
-
// if (quickInfo) {
|
|
243
|
-
// return column;
|
|
244
|
-
// }
|
|
245
|
-
// }
|
|
246
|
-
// };
|
|
247
320
|
//# sourceMappingURL=index.js.map
|
|
248
321
|
|
|
249
322
|
return makePlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shareable-twoslash-comments",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"description": "A TypeScript Playground plugin that embeds twoslash (// ^?) type hints as literal comments in your code, making them easy to copy and share.",
|
|
6
6
|
"license": "MIT",
|