@adecore/editor-react 0.31.12 → 0.32.0
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/dist/AnchoredPopup.js +73 -19
- package/dist/AttributionCard.js +162 -4
- package/dist/BaselineStatus.js +62 -8
- package/dist/CallHierarchyPanel.js +977 -60
- package/dist/ChangeReview.js +76 -25
- package/dist/CodeAuthorsCard.js +314 -14
- package/dist/CompletionPopup.js +490 -83
- package/dist/DiffView.js +548 -181
- package/dist/EditorContextMenu.js +352 -34
- package/dist/EditorView.js +276 -99
- package/dist/FindReplace.js +525 -67
- package/dist/HoverCard.js +378 -38
- package/dist/HoverSections.js +367 -56
- package/dist/LanguagePopups.js +95 -34
- package/dist/Markdown.js +41 -6
- package/dist/PanelResizeHandle.js +199 -66
- package/dist/PathText.js +49 -7
- package/dist/PeekPanel.js +675 -72
- package/dist/PickPopup.js +304 -34
- package/dist/RenameCard.js +679 -85
- package/dist/RenderedDocs.js +329 -58
- package/dist/SignatureCard.js +91 -7
- package/dist/SplitDiffView.js +344 -254
- package/dist/SymbolPicker.js +440 -85
- package/dist/call-hierarchy-model.js +102 -68
- package/dist/call-hierarchy.js +458 -359
- package/dist/code-actions-model.js +88 -76
- package/dist/code-actions.js +372 -283
- package/dist/code-authors.js +64 -55
- package/dist/code-vision-model.js +134 -127
- package/dist/code-vision.js +224 -206
- package/dist/completion-call.js +94 -67
- package/dist/completion-model.js +334 -244
- package/dist/completion.js +840 -649
- package/dist/conflict-model.js +35 -29
- package/dist/context-menu-rows.js +42 -17
- package/dist/context-menu.js +64 -46
- package/dist/definition-link.js +88 -85
- package/dist/diagnostics-model.js +74 -55
- package/dist/diagnostics.js +121 -100
- package/dist/diff-expansion.js +38 -35
- package/dist/diff-overlays.js +144 -22
- package/dist/diff-syntax.js +65 -42
- package/dist/diff-wordmarks.js +26 -23
- package/dist/doc-comment-model.js +265 -216
- package/dist/editor-language.js +177 -152
- package/dist/error-message.js +2 -2
- package/dist/find-query.js +49 -36
- package/dist/folding.js +81 -62
- package/dist/format-on-type.js +86 -67
- package/dist/highlight-layers.js +19 -20
- package/dist/highlights.js +105 -83
- package/dist/history.js +44 -38
- package/dist/holder.js +18 -18
- package/dist/host-types.js +1 -1
- package/dist/hover-content.js +167 -129
- package/dist/hover.js +285 -245
- package/dist/index.js +10 -10
- package/dist/inlay-hints.js +369 -324
- package/dist/key-priority.js +34 -31
- package/dist/language-ids.js +45 -42
- package/dist/line-edits.js +74 -28
- package/dist/line-text.js +18 -3
- package/dist/locales/en.json +38 -38
- package/dist/locales/nl.json +41 -41
- package/dist/models.js +1 -1
- package/dist/navigation-history.js +40 -41
- package/dist/navigation.js +141 -123
- package/dist/panel-size.js +8 -8
- package/dist/patch-decorations.js +236 -160
- package/dist/patch-layout.js +331 -262
- package/dist/paths.js +3 -3
- package/dist/peek-model.js +86 -69
- package/dist/peek.js +254 -192
- package/dist/pick.js +164 -157
- package/dist/popup-focus.js +5 -5
- package/dist/popup-placement.js +36 -21
- package/dist/popups.js +13 -13
- package/dist/project-language.js +228 -211
- package/dist/project-problems.js +81 -69
- package/dist/proposal-model.js +163 -126
- package/dist/recent-choices.js +25 -25
- package/dist/refresher.js +44 -49
- package/dist/rename-model.js +113 -113
- package/dist/rename.js +321 -233
- package/dist/rendered-docs.d.ts +4 -2
- package/dist/rendered-docs.js +384 -318
- package/dist/rendering-context.js +5 -3
- package/dist/rendering.js +22 -4
- package/dist/review-group.js +42 -39
- package/dist/row-host.d.ts +4 -2
- package/dist/row-host.js +90 -78
- package/dist/selection-ranges.js +21 -17
- package/dist/semantic-delta.js +22 -19
- package/dist/semantic-model.js +86 -73
- package/dist/semantic-tokens.js +201 -162
- package/dist/shortcut-keys.js +16 -10
- package/dist/signature-model.js +34 -28
- package/dist/signature.js +177 -129
- package/dist/snippet-field-transforms.js +118 -106
- package/dist/snippet-indent.js +48 -43
- package/dist/snippet-range-order.js +11 -11
- package/dist/snippet-session.js +703 -667
- package/dist/snippet-transform-client.js +59 -59
- package/dist/snippet-transform-format.js +285 -263
- package/dist/snippet-transform-protocol.js +1 -1
- package/dist/snippet-transform-queue.js +163 -153
- package/dist/snippet-transform-worker.js +42 -35
- package/dist/snippet-variable-names.js +1 -36
- package/dist/snippet-variables.js +53 -63
- package/dist/snippet.js +477 -405
- package/dist/split-alignment.js +47 -35
- package/dist/split-scroll.js +42 -40
- package/dist/symbol-links.js +33 -25
- package/dist/symbol-picker-model.js +126 -116
- package/dist/symbol-picker.js +98 -59
- package/dist/symbols.js +117 -88
- package/dist/testing.js +248 -165
- package/dist/timers.js +35 -30
- package/dist/use-panel-body.js +49 -8
- package/dist/use-problem-counts.js +29 -15
- package/dist/view-state.js +54 -33
- package/dist/word-diff.js +18 -18
- package/dist/workspace-edit.js +300 -249
- package/package.json +6 -6
- package/src/CallHierarchyPanel.tsx +2 -2
- package/src/DiffView.tsx +3 -3
- package/src/FindReplace.tsx +2 -2
- package/src/LanguagePopups.tsx +2 -0
- package/src/PeekPanel.tsx +3 -3
- package/src/RenderedDocs.tsx +9 -10
- package/src/SymbolPicker.tsx +2 -2
- package/src/diff-overlays.tsx +6 -4
- package/src/locales/en.json +38 -38
- package/src/locales/nl.json +41 -41
- package/src/rendered-docs.ts +14 -3
- package/src/row-host.ts +14 -3
|
@@ -2,172 +2,182 @@ import { createSnippetTransformClient, SnippetTransformError } from './snippet-t
|
|
|
2
2
|
import { validateSnippetTransformJobs } from './snippet-transform-format.js';
|
|
3
3
|
import { MAX_TRANSFORM_WORK } from './snippet-transform-protocol.js';
|
|
4
4
|
import { realTimers } from './timers.js';
|
|
5
|
-
export class SnippetTransformQueueError extends Error {
|
|
6
|
-
}
|
|
5
|
+
export class SnippetTransformQueueError extends Error {}
|
|
7
6
|
const IDLE_RELEASE_MS = 1000;
|
|
8
7
|
const MAX_PENDING = 16;
|
|
9
8
|
export class SnippetTransforms {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
9
|
+
client;
|
|
10
|
+
timers;
|
|
11
|
+
owners = new Set();
|
|
12
|
+
pending = [];
|
|
13
|
+
active = null;
|
|
14
|
+
idle;
|
|
15
|
+
disposed = false;
|
|
16
|
+
constructor(factory, timers = realTimers) {
|
|
17
|
+
this.timers = timers;
|
|
18
|
+
this.client = createSnippetTransformClient({
|
|
19
|
+
workerFactory: factory,
|
|
20
|
+
schedule: (callback, delay) => {
|
|
21
|
+
const timer = timers.set(callback, delay);
|
|
22
|
+
return () => timers.clear(timer);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
acquire() {
|
|
27
|
+
const owner = Symbol('snippet');
|
|
28
|
+
this.owners.add(owner);
|
|
29
|
+
return {
|
|
30
|
+
request: (jobs, options = {}) => this.request(owner, jobs, options),
|
|
31
|
+
dispose: () => this.releaseOwner(owner)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
request(owner, jobs, options) {
|
|
35
|
+
if (this.disposed || !this.owners.has(owner)) {
|
|
36
|
+
return Promise.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
26
37
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
let copied;
|
|
39
|
+
try {
|
|
40
|
+
validateSnippetTransformJobs(jobs);
|
|
41
|
+
if (jobs.reduce((sum, job) => sum + job.value.length, 0) > MAX_TRANSFORM_WORK) {
|
|
42
|
+
throw new RangeError('The snippet transform inputs exceed the work budget.');
|
|
43
|
+
}
|
|
44
|
+
copied = jobs.map(job => ({
|
|
45
|
+
...job,
|
|
46
|
+
format: job.format.map(node => ({
|
|
47
|
+
...node
|
|
48
|
+
}))
|
|
49
|
+
}));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
return Promise.reject(new SnippetTransformError(error instanceof RangeError ? 'range' : 'syntax', error instanceof Error ? error.message : String(error)));
|
|
34
52
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return Promise.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
38
|
-
}
|
|
39
|
-
let copied;
|
|
40
|
-
try {
|
|
41
|
-
validateSnippetTransformJobs(jobs);
|
|
42
|
-
if (jobs.reduce((sum, job) => sum + job.value.length, 0) > MAX_TRANSFORM_WORK) {
|
|
43
|
-
throw new RangeError('The snippet transform inputs exceed the work budget.');
|
|
44
|
-
}
|
|
45
|
-
copied = jobs.map((job) => ({ ...job, format: job.format.map((node) => ({ ...node })) }));
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
return Promise.reject(new SnippetTransformError(error instanceof RangeError ? 'range' : 'syntax', error instanceof Error ? error.message : String(error)));
|
|
49
|
-
}
|
|
50
|
-
if (copied.length === 0) {
|
|
51
|
-
return Promise.resolve([]);
|
|
52
|
-
}
|
|
53
|
-
this.pending = this.pending.filter((job) => {
|
|
54
|
-
if (job.current()) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
job.reject(new SnippetTransformError('superseded', 'The queued snippet changed.'));
|
|
58
|
-
return false;
|
|
59
|
-
});
|
|
60
|
-
const kind = options.kind ?? 'accept';
|
|
61
|
-
if (kind === 'accept') {
|
|
62
|
-
this.pending = this.pending.filter((job) => {
|
|
63
|
-
if (job.owner !== owner || job.kind !== 'accept') {
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
job.reject(new SnippetTransformError('superseded', 'A newer snippet accept replaced the queued one.'));
|
|
67
|
-
return false;
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (this.pending.length >= MAX_PENDING) {
|
|
71
|
-
return Promise.reject(new SnippetTransformQueueError('Too many queued snippet transforms.'));
|
|
72
|
-
}
|
|
73
|
-
this.timers.clear(this.idle);
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
this.pending.push({ owner, kind, jobs: copied, current: () => this.owners.has(owner) && (options.current?.() ?? true), resolve, reject });
|
|
76
|
-
queueMicrotask(() => this.pump());
|
|
77
|
-
});
|
|
53
|
+
if (copied.length === 0) {
|
|
54
|
+
return Promise.resolve([]);
|
|
78
55
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
this.pump();
|
|
92
|
-
return;
|
|
56
|
+
this.pending = this.pending.filter(job => {
|
|
57
|
+
if (job.current()) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
job.reject(new SnippetTransformError('superseded', 'The queued snippet changed.'));
|
|
61
|
+
return false;
|
|
62
|
+
});
|
|
63
|
+
const kind = options.kind ?? 'accept';
|
|
64
|
+
if (kind === 'accept') {
|
|
65
|
+
this.pending = this.pending.filter(job => {
|
|
66
|
+
if (job.owner !== owner || job.kind !== 'accept') {
|
|
67
|
+
return true;
|
|
93
68
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
.then((values) => {
|
|
98
|
-
if (!job.current()) {
|
|
99
|
-
throw new SnippetTransformError('superseded', 'The snippet changed while transforming.');
|
|
100
|
-
}
|
|
101
|
-
job.resolve(values);
|
|
102
|
-
})
|
|
103
|
-
.catch((error) => job.reject(error))
|
|
104
|
-
.finally(() => {
|
|
105
|
-
this.active = null;
|
|
106
|
-
this.pump();
|
|
107
|
-
});
|
|
69
|
+
job.reject(new SnippetTransformError('superseded', 'A newer snippet accept replaced the queued one.'));
|
|
70
|
+
return false;
|
|
71
|
+
});
|
|
108
72
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
this.pending = this.pending.filter((job) => {
|
|
114
|
-
if (job.owner !== owner) {
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
job.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
118
|
-
return false;
|
|
119
|
-
});
|
|
120
|
-
if (this.active?.owner === owner) {
|
|
121
|
-
this.active.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
122
|
-
this.client.cancel();
|
|
123
|
-
}
|
|
124
|
-
if (this.owners.size === 0) {
|
|
125
|
-
this.dispose();
|
|
126
|
-
}
|
|
73
|
+
if (this.pending.length >= MAX_PENDING) {
|
|
74
|
+
return Promise.reject(new SnippetTransformQueueError('Too many queued snippet transforms.'));
|
|
127
75
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.owners.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
76
|
+
this.timers.clear(this.idle);
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
this.pending.push({
|
|
79
|
+
owner,
|
|
80
|
+
kind,
|
|
81
|
+
jobs: copied,
|
|
82
|
+
current: () => this.owners.has(owner) && (options.current?.() ?? true),
|
|
83
|
+
resolve,
|
|
84
|
+
reject
|
|
85
|
+
});
|
|
86
|
+
queueMicrotask(() => this.pump());
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
pump() {
|
|
90
|
+
if (this.disposed || this.active !== null) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const job = this.pending.shift();
|
|
94
|
+
if (job === undefined) {
|
|
95
|
+
this.timers.clear(this.idle);
|
|
96
|
+
this.idle = this.timers.set(() => this.client.release(), IDLE_RELEASE_MS);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!job.current()) {
|
|
100
|
+
job.reject(new SnippetTransformError('superseded', 'The queued snippet changed.'));
|
|
101
|
+
this.pump();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.active = job;
|
|
105
|
+
void this.client.transform(job.jobs).then(values => {
|
|
106
|
+
if (!job.current()) {
|
|
107
|
+
throw new SnippetTransformError('superseded', 'The snippet changed while transforming.');
|
|
108
|
+
}
|
|
109
|
+
job.resolve(values);
|
|
110
|
+
}).catch(error => job.reject(error)).finally(() => {
|
|
111
|
+
this.active = null;
|
|
112
|
+
this.pump();
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
releaseOwner(owner) {
|
|
116
|
+
if (!this.owners.delete(owner)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.pending = this.pending.filter(job => {
|
|
120
|
+
if (job.owner !== owner) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
job.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
124
|
+
return false;
|
|
125
|
+
});
|
|
126
|
+
if (this.active?.owner === owner) {
|
|
127
|
+
this.active.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
128
|
+
this.client.cancel();
|
|
129
|
+
}
|
|
130
|
+
if (this.owners.size === 0) {
|
|
131
|
+
this.dispose();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
dispose() {
|
|
135
|
+
if (this.disposed) {
|
|
136
|
+
return;
|
|
140
137
|
}
|
|
138
|
+
this.disposed = true;
|
|
139
|
+
this.timers.clear(this.idle);
|
|
140
|
+
this.owners.clear();
|
|
141
|
+
const error = new SnippetTransformError('disposed', 'The project snippet transforms were disposed.');
|
|
142
|
+
this.active?.reject(error);
|
|
143
|
+
this.pending.forEach(job => job.reject(error));
|
|
144
|
+
this.pending = [];
|
|
145
|
+
this.client.dispose();
|
|
146
|
+
}
|
|
141
147
|
}
|
|
142
148
|
const projects = new WeakMap();
|
|
143
149
|
export function acquireSnippetTransforms(project, timers) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const held = entry, lease = held.queue.acquire();
|
|
154
|
-
held.references++;
|
|
155
|
-
let disposed = false;
|
|
156
|
-
return {
|
|
157
|
-
request: (jobs, options) => lease.request(jobs, options),
|
|
158
|
-
dispose: () => {
|
|
159
|
-
if (disposed) {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
disposed = true;
|
|
163
|
-
lease.dispose();
|
|
164
|
-
if (--held.references === 0 && projects.get(project) === held) {
|
|
165
|
-
projects.delete(project);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
150
|
+
const factory = project.host.snippetTransformWorker;
|
|
151
|
+
if (factory === undefined) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
let entry = projects.get(project);
|
|
155
|
+
if (entry === undefined) {
|
|
156
|
+
entry = {
|
|
157
|
+
queue: new SnippetTransforms(factory, timers),
|
|
158
|
+
references: 0
|
|
168
159
|
};
|
|
160
|
+
projects.set(project, entry);
|
|
161
|
+
}
|
|
162
|
+
const held = entry,
|
|
163
|
+
lease = held.queue.acquire();
|
|
164
|
+
held.references++;
|
|
165
|
+
let disposed = false;
|
|
166
|
+
return {
|
|
167
|
+
request: (jobs, options) => lease.request(jobs, options),
|
|
168
|
+
dispose: () => {
|
|
169
|
+
if (disposed) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
disposed = true;
|
|
173
|
+
lease.dispose();
|
|
174
|
+
if (--held.references === 0 && projects.get(project) === held) {
|
|
175
|
+
projects.delete(project);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
169
179
|
}
|
|
170
180
|
export function disposeSnippetTransforms(project) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
181
|
+
projects.get(project)?.queue.dispose();
|
|
182
|
+
projects.delete(project);
|
|
183
|
+
}
|
|
@@ -3,39 +3,46 @@ import { MAX_TRANSFORM_CHARACTERS } from './snippet-transform-protocol.js';
|
|
|
3
3
|
export { createSnippetTransformClient, SnippetTransformError } from './snippet-transform-client.js';
|
|
4
4
|
export { compileSnippetTransformFormat } from './snippet-transform-format.js';
|
|
5
5
|
export function serveSnippetTransforms(endpoint) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
remaining -= value.length;
|
|
25
|
-
return value;
|
|
26
|
-
});
|
|
27
|
-
endpoint.postMessage({ type: 'transformed', id: request.id, values });
|
|
6
|
+
const receive = ({
|
|
7
|
+
data: request
|
|
8
|
+
}) => {
|
|
9
|
+
const id = request !== null && typeof request === 'object' && Number.isSafeInteger(request.id) && request.id > 0 ? request.id : 0;
|
|
10
|
+
try {
|
|
11
|
+
if (id === 0 || request.type !== 'transform') {
|
|
12
|
+
throw new RangeError('Invalid snippet transform request.');
|
|
13
|
+
}
|
|
14
|
+
validateSnippetTransformJobs(request.jobs);
|
|
15
|
+
let remaining = MAX_TRANSFORM_CHARACTERS;
|
|
16
|
+
const budget = createSnippetTransformBudget();
|
|
17
|
+
const patterns = new Map();
|
|
18
|
+
const values = request.jobs.map(job => {
|
|
19
|
+
const key = job.flags + '\0' + job.pattern;
|
|
20
|
+
let expression = patterns.get(key);
|
|
21
|
+
if (expression === undefined) {
|
|
22
|
+
expression = new RegExp(job.pattern, job.flags);
|
|
23
|
+
patterns.set(key, expression);
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
const value = applySnippetTransform(job, remaining, expression, budget);
|
|
26
|
+
remaining -= value.length;
|
|
27
|
+
return value;
|
|
28
|
+
});
|
|
29
|
+
endpoint.postMessage({
|
|
30
|
+
type: 'transformed',
|
|
31
|
+
id: request.id,
|
|
32
|
+
values
|
|
33
|
+
});
|
|
34
|
+
} catch (error) {
|
|
35
|
+
endpoint.postMessage({
|
|
36
|
+
type: 'error',
|
|
37
|
+
id,
|
|
38
|
+
kind: error instanceof SyntaxError ? 'syntax' : error instanceof RangeError ? 'range' : 'error',
|
|
39
|
+
message: error instanceof Error ? error.message : String(error)
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
endpoint.addEventListener('message', receive);
|
|
44
|
+
endpoint.postMessage({
|
|
45
|
+
type: 'ready'
|
|
46
|
+
});
|
|
47
|
+
return () => endpoint.removeEventListener('message', receive);
|
|
48
|
+
}
|
|
@@ -1,36 +1 @@
|
|
|
1
|
-
export const SNIPPET_VARIABLES = new Set([
|
|
2
|
-
'TM_SELECTED_TEXT',
|
|
3
|
-
'TM_CURRENT_LINE',
|
|
4
|
-
'TM_CURRENT_WORD',
|
|
5
|
-
'TM_LINE_INDEX',
|
|
6
|
-
'TM_LINE_NUMBER',
|
|
7
|
-
'TM_FILENAME',
|
|
8
|
-
'TM_FILENAME_BASE',
|
|
9
|
-
'TM_DIRECTORY',
|
|
10
|
-
'TM_FILEPATH',
|
|
11
|
-
'RELATIVE_FILEPATH',
|
|
12
|
-
'WORKSPACE_NAME',
|
|
13
|
-
'WORKSPACE_FOLDER',
|
|
14
|
-
'CURSOR_INDEX',
|
|
15
|
-
'CURSOR_NUMBER',
|
|
16
|
-
'CLIPBOARD',
|
|
17
|
-
'CURRENT_YEAR',
|
|
18
|
-
'CURRENT_YEAR_SHORT',
|
|
19
|
-
'CURRENT_MONTH',
|
|
20
|
-
'CURRENT_MONTH_NAME',
|
|
21
|
-
'CURRENT_MONTH_NAME_SHORT',
|
|
22
|
-
'CURRENT_DATE',
|
|
23
|
-
'CURRENT_DAY_NAME',
|
|
24
|
-
'CURRENT_DAY_NAME_SHORT',
|
|
25
|
-
'CURRENT_HOUR',
|
|
26
|
-
'CURRENT_MINUTE',
|
|
27
|
-
'CURRENT_SECOND',
|
|
28
|
-
'CURRENT_SECONDS_UNIX',
|
|
29
|
-
'CURRENT_TIMEZONE_OFFSET',
|
|
30
|
-
'RANDOM',
|
|
31
|
-
'RANDOM_HEX',
|
|
32
|
-
'UUID',
|
|
33
|
-
'LINE_COMMENT',
|
|
34
|
-
'BLOCK_COMMENT_START',
|
|
35
|
-
'BLOCK_COMMENT_END'
|
|
36
|
-
]);
|
|
1
|
+
export const SNIPPET_VARIABLES = new Set(['TM_SELECTED_TEXT', 'TM_CURRENT_LINE', 'TM_CURRENT_WORD', 'TM_LINE_INDEX', 'TM_LINE_NUMBER', 'TM_FILENAME', 'TM_FILENAME_BASE', 'TM_DIRECTORY', 'TM_FILEPATH', 'RELATIVE_FILEPATH', 'WORKSPACE_NAME', 'WORKSPACE_FOLDER', 'CURSOR_INDEX', 'CURSOR_NUMBER', 'CLIPBOARD', 'CURRENT_YEAR', 'CURRENT_YEAR_SHORT', 'CURRENT_MONTH', 'CURRENT_MONTH_NAME', 'CURRENT_MONTH_NAME_SHORT', 'CURRENT_DATE', 'CURRENT_DAY_NAME', 'CURRENT_DAY_NAME_SHORT', 'CURRENT_HOUR', 'CURRENT_MINUTE', 'CURRENT_SECOND', 'CURRENT_SECONDS_UNIX', 'CURRENT_TIMEZONE_OFFSET', 'RANDOM', 'RANDOM_HEX', 'UUID', 'LINE_COMMENT', 'BLOCK_COMMENT_START', 'BLOCK_COMMENT_END']);
|
|
@@ -1,66 +1,56 @@
|
|
|
1
1
|
const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
2
2
|
const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
3
3
|
export function createSnippetResolver(context, custom, sources = {}) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.toString(16)
|
|
58
|
-
.padStart(6, '0')
|
|
59
|
-
: name === 'UUID'
|
|
60
|
-
? (sources.uuid?.() ?? globalThis.crypto?.randomUUID())
|
|
61
|
-
: builtins.get(name));
|
|
62
|
-
cache.set(name, value);
|
|
63
|
-
}
|
|
64
|
-
return cache.get(name);
|
|
65
|
-
};
|
|
66
|
-
}
|
|
4
|
+
const now = sources.now ?? new Date();
|
|
5
|
+
const random = sources.random ?? Math.random;
|
|
6
|
+
const path = context.path;
|
|
7
|
+
const filename = path?.replace(/\\/g, '/').split('/').at(-1);
|
|
8
|
+
const folder = context.folder?.replace(/\\/g, '/').replace(/\/$/, '');
|
|
9
|
+
const normalized = path?.replace(/\\/g, '/');
|
|
10
|
+
const pad = value => String(value).padStart(2, '0');
|
|
11
|
+
const timezone = -now.getTimezoneOffset();
|
|
12
|
+
const values = {
|
|
13
|
+
TM_SELECTED_TEXT: context.selectedText,
|
|
14
|
+
TM_CURRENT_LINE: context.currentLine,
|
|
15
|
+
TM_CURRENT_WORD: context.currentWord,
|
|
16
|
+
TM_LINE_INDEX: String(context.position.line),
|
|
17
|
+
TM_LINE_NUMBER: String(context.position.line + 1),
|
|
18
|
+
CURSOR_INDEX: String(context.cursorIndex),
|
|
19
|
+
CURSOR_NUMBER: String(context.cursorIndex + 1),
|
|
20
|
+
TM_FILENAME: filename,
|
|
21
|
+
TM_FILENAME_BASE: filename === undefined ? undefined : filename.replace(/(?<=.)\.[^.]*$/, ''),
|
|
22
|
+
TM_DIRECTORY: normalized === undefined ? undefined : normalized.includes('/') ? normalized.slice(0, normalized.lastIndexOf('/')) : '',
|
|
23
|
+
TM_FILEPATH: path,
|
|
24
|
+
RELATIVE_FILEPATH: folder !== undefined && normalized?.startsWith(folder + '/') ? normalized.slice(folder.length + 1) : path,
|
|
25
|
+
WORKSPACE_FOLDER: context.folder,
|
|
26
|
+
WORKSPACE_NAME: folder?.split('/').at(-1),
|
|
27
|
+
CURRENT_YEAR: String(now.getFullYear()),
|
|
28
|
+
CURRENT_YEAR_SHORT: String(now.getFullYear()).slice(-2),
|
|
29
|
+
CURRENT_MONTH: pad(now.getMonth() + 1),
|
|
30
|
+
CURRENT_MONTH_NAME: MONTHS[now.getMonth()],
|
|
31
|
+
CURRENT_MONTH_NAME_SHORT: MONTHS[now.getMonth()].slice(0, 3),
|
|
32
|
+
CURRENT_DATE: pad(now.getDate()),
|
|
33
|
+
CURRENT_DAY_NAME: DAYS[now.getDay()],
|
|
34
|
+
CURRENT_DAY_NAME_SHORT: DAYS[now.getDay()].slice(0, 3),
|
|
35
|
+
CURRENT_HOUR: pad(now.getHours()),
|
|
36
|
+
CURRENT_MINUTE: pad(now.getMinutes()),
|
|
37
|
+
CURRENT_SECOND: pad(now.getSeconds()),
|
|
38
|
+
CURRENT_SECONDS_UNIX: String(Math.floor(now.getTime() / 1000)),
|
|
39
|
+
CURRENT_TIMEZONE_OFFSET: (timezone < 0 ? '-' : '+') + pad(Math.floor(Math.abs(timezone) / 60)) + pad(Math.abs(timezone) % 60)
|
|
40
|
+
};
|
|
41
|
+
const builtins = new Map(Object.entries(values));
|
|
42
|
+
const cache = new Map();
|
|
43
|
+
return name => {
|
|
44
|
+
if (!cache.has(name)) {
|
|
45
|
+
let supplied;
|
|
46
|
+
try {
|
|
47
|
+
supplied = custom?.(name, context);
|
|
48
|
+
} catch {
|
|
49
|
+
// A failed host override leaves the built-in or editable variable available.
|
|
50
|
+
}
|
|
51
|
+
const value = supplied ?? (name === 'RANDOM' ? String(Math.floor(random() * 1_000_000)).padStart(6, '0') : name === 'RANDOM_HEX' ? Math.floor(random() * 0x1000000).toString(16).padStart(6, '0') : name === 'UUID' ? sources.uuid?.() ?? globalThis.crypto?.randomUUID() : builtins.get(name));
|
|
52
|
+
cache.set(name, value);
|
|
53
|
+
}
|
|
54
|
+
return cache.get(name);
|
|
55
|
+
};
|
|
56
|
+
}
|