@adecore/editor-react 0.31.11 → 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
package/dist/proposal-model.js
CHANGED
|
@@ -1,48 +1,64 @@
|
|
|
1
1
|
import { diffLines } from '@adecore/merge';
|
|
2
2
|
import { replacedWords } from './word-diff.js';
|
|
3
3
|
export function lineSpanOf(range) {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const endsOnBreak = range.end.character === 0 && range.end.line > range.start.line;
|
|
5
|
+
return {
|
|
6
|
+
startLine: range.start.line + 1,
|
|
7
|
+
endLine: endsOnBreak ? range.end.line : range.end.line + 1
|
|
8
|
+
};
|
|
6
9
|
}
|
|
7
10
|
export function isEmptyRange(range) {
|
|
8
|
-
|
|
11
|
+
return range.start.line === range.end.line && range.start.character === range.end.character;
|
|
9
12
|
}
|
|
10
13
|
/* The selection, or the whole line under the caret while nothing is selected. */
|
|
11
14
|
export function inlineRangeOf(selection, lineLength) {
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
if (!isEmptyRange(selection)) {
|
|
16
|
+
return selection;
|
|
17
|
+
}
|
|
18
|
+
const {
|
|
19
|
+
line
|
|
20
|
+
} = selection.start;
|
|
21
|
+
return {
|
|
22
|
+
start: {
|
|
23
|
+
line,
|
|
24
|
+
character: 0
|
|
25
|
+
},
|
|
26
|
+
end: {
|
|
27
|
+
line,
|
|
28
|
+
character: lineLength(line)
|
|
14
29
|
}
|
|
15
|
-
|
|
16
|
-
return { start: { line, character: 0 }, end: { line, character: lineLength(line) } };
|
|
30
|
+
};
|
|
17
31
|
}
|
|
18
32
|
export function problemsOnLines(diagnostics, span, describe) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
return diagnostics.filter(diagnostic => diagnostic.range.start.line + 1 <= span.endLine && diagnostic.range.end.line + 1 >= span.startLine).map(diagnostic => ({
|
|
34
|
+
line: Math.max(diagnostic.range.start.line + 1, span.startLine),
|
|
35
|
+
...describe(diagnostic)
|
|
36
|
+
})).sort((left, right) => left.line - right.line);
|
|
23
37
|
}
|
|
24
38
|
const OPENING = /^( {0,3})(`{3,}|~{3,})(.*)$/;
|
|
25
39
|
function openingOf(line) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
const match = OPENING.exec(line);
|
|
41
|
+
if (match === null) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const [, indent = '', marks = '', info = ''] = match;
|
|
45
|
+
// The info string of a backtick fence holds no backtick, which is what keeps a line of inline code from opening one.
|
|
46
|
+
if (marks.startsWith('`') && info.includes('`')) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
char: marks[0],
|
|
51
|
+
length: marks.length,
|
|
52
|
+
indent: indent.length,
|
|
53
|
+
info: info.trim()
|
|
54
|
+
};
|
|
36
55
|
}
|
|
37
56
|
function closes(line, start) {
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
const match = /^ {0,3}(`+|~+)\s*$/.exec(line);
|
|
58
|
+
return match !== null && match[1][0] === start.char && match[1].length >= start.length;
|
|
40
59
|
}
|
|
41
60
|
function isReplacement(info) {
|
|
42
|
-
|
|
43
|
-
.toLowerCase()
|
|
44
|
-
.split(/[\s,:=]+/)
|
|
45
|
-
.includes('replacement');
|
|
61
|
+
return info.toLowerCase().split(/[\s,:=]+/).includes('replacement');
|
|
46
62
|
}
|
|
47
63
|
/*
|
|
48
64
|
* Reads the answer the way a markdown reader does: a fence closes at a line of at least as many marks,
|
|
@@ -50,53 +66,60 @@ function isReplacement(info) {
|
|
|
50
66
|
* applying half of it would be worse than showing the answer as text, so it counts as no block.
|
|
51
67
|
*/
|
|
52
68
|
export function parseAnswer(text) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
open = null;
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
open.body.push(line.replace(new RegExp(`^ {0,${open.start.indent}}`), ''));
|
|
69
|
+
const lines = text.replace(/\r\n/g, '\n').split('\n');
|
|
70
|
+
let open = null;
|
|
71
|
+
let found = null;
|
|
72
|
+
for (const [index, line] of lines.entries()) {
|
|
73
|
+
if (open === null) {
|
|
74
|
+
const start = openingOf(line);
|
|
75
|
+
if (start !== null) {
|
|
76
|
+
open = {
|
|
77
|
+
start,
|
|
78
|
+
from: index,
|
|
79
|
+
body: []
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
72
83
|
}
|
|
73
|
-
if (
|
|
74
|
-
|
|
84
|
+
if (closes(line, open.start)) {
|
|
85
|
+
if (isReplacement(open.start.info)) {
|
|
86
|
+
found = {
|
|
87
|
+
from: open.from,
|
|
88
|
+
to: index,
|
|
89
|
+
body: open.body
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
open = null;
|
|
93
|
+
continue;
|
|
75
94
|
}
|
|
95
|
+
open.body.push(line.replace(new RegExp(`^ {0,${open.start.indent}}`), ''));
|
|
96
|
+
}
|
|
97
|
+
if (found === null) {
|
|
76
98
|
return {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
.join('\n')
|
|
80
|
-
.replace(/\n{3,}/g, '\n\n')
|
|
81
|
-
.trim()
|
|
99
|
+
replacement: null,
|
|
100
|
+
rest: text.trim()
|
|
82
101
|
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
replacement: found.body.join('\n'),
|
|
105
|
+
rest: [...lines.slice(0, found.from), ...lines.slice(found.to + 1)].join('\n').replace(/\n{3,}/g, '\n\n').trim()
|
|
106
|
+
};
|
|
83
107
|
}
|
|
84
108
|
/* The proposal in the shape of the text it replaces: its line breaks and whether it ends on one. */
|
|
85
109
|
export function fitReplacement(selected, replacement) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return breaks === '\n' ? fitted : fitted.replace(/\n/g, breaks);
|
|
110
|
+
const breaks = selected.includes('\r\n') ? '\r\n' : '\n';
|
|
111
|
+
let fitted = replacement.replace(/\r\n/g, '\n');
|
|
112
|
+
const endsOnBreak = selected.endsWith('\n');
|
|
113
|
+
if (fitted !== '' && endsOnBreak && !fitted.endsWith('\n')) {
|
|
114
|
+
fitted += '\n';
|
|
115
|
+
} else if (!endsOnBreak && fitted.endsWith('\n')) {
|
|
116
|
+
fitted = fitted.slice(0, -1);
|
|
117
|
+
}
|
|
118
|
+
return breaks === '\n' ? fitted : fitted.replace(/\n/g, breaks);
|
|
96
119
|
}
|
|
97
120
|
function linesOf(text) {
|
|
98
|
-
|
|
99
|
-
|
|
121
|
+
const lines = text.replace(/\r\n/g, '\n').split('\n');
|
|
122
|
+
return lines.length > 1 && lines.at(-1) === '' ? lines.slice(0, -1) : lines;
|
|
100
123
|
}
|
|
101
124
|
/*
|
|
102
125
|
* The proposal against the selection, line by line. Lines the proposal changes show as added, since
|
|
@@ -104,86 +127,100 @@ function linesOf(text) {
|
|
|
104
127
|
* only removed ones, because nothing in the proposal would show them gone.
|
|
105
128
|
*/
|
|
106
129
|
export function diffSegments(selected, proposal, startLine) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
const base = linesOf(selected);
|
|
131
|
+
const other = linesOf(proposal);
|
|
132
|
+
const segments = [];
|
|
133
|
+
let cursor = 0;
|
|
134
|
+
const same = until => {
|
|
135
|
+
if (until > cursor) {
|
|
136
|
+
segments.push({
|
|
137
|
+
kind: 'same',
|
|
138
|
+
text: other.slice(cursor, until).join('\n'),
|
|
139
|
+
firstLine: startLine + cursor
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
for (const change of diffLines(base, other)) {
|
|
144
|
+
same(change.otherStart);
|
|
145
|
+
if (change.otherEnd > change.otherStart) {
|
|
146
|
+
segments.push({
|
|
147
|
+
kind: 'added',
|
|
148
|
+
text: other.slice(change.otherStart, change.otherEnd).join('\n'),
|
|
149
|
+
firstLine: startLine + change.otherStart,
|
|
150
|
+
...(change.baseEnd > change.baseStart ? {
|
|
151
|
+
replaces: base.slice(change.baseStart, change.baseEnd).join('\n')
|
|
152
|
+
} : {})
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
segments.push({
|
|
156
|
+
kind: 'removed',
|
|
157
|
+
text: base.slice(change.baseStart, change.baseEnd).join('\n')
|
|
158
|
+
});
|
|
130
159
|
}
|
|
131
|
-
|
|
132
|
-
|
|
160
|
+
cursor = change.otherEnd;
|
|
161
|
+
}
|
|
162
|
+
same(other.length);
|
|
163
|
+
return segments;
|
|
133
164
|
}
|
|
134
165
|
/* Per line of an added stretch, the character ranges of the words that differ from the line it replaces, for the stronger tint; undefined when none do. */
|
|
135
166
|
export function emphasisOf(segment) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
if (segment.kind !== 'added' || segment.replaces === undefined) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
const ranges = replacedWords(linesOf(segment.text), linesOf(segment.replaces));
|
|
171
|
+
return ranges.some(line => line.length > 0) ? ranges : undefined;
|
|
141
172
|
}
|
|
142
173
|
/* The offset of a position in a text whose lines end in `\n` or `\r\n`; null when the text is not that long. */
|
|
143
174
|
export function offsetOf(text, position) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
offset = end + 1;
|
|
175
|
+
let offset = 0;
|
|
176
|
+
for (let line = 0; line < position.line; line++) {
|
|
177
|
+
const end = text.indexOf('\n', offset);
|
|
178
|
+
if (end === -1) {
|
|
179
|
+
return null;
|
|
151
180
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
181
|
+
offset = end + 1;
|
|
182
|
+
}
|
|
183
|
+
const lineEnd = text.indexOf('\n', offset);
|
|
184
|
+
const length = (lineEnd === -1 ? text.length : lineEnd) - offset;
|
|
185
|
+
return position.character > length ? null : offset + position.character;
|
|
155
186
|
}
|
|
156
187
|
/* The text in a range of `text`, or null when the range is not in it. */
|
|
157
188
|
export function textInRange(text, range) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
189
|
+
const from = offsetOf(text, range.start);
|
|
190
|
+
const to = offsetOf(text, range.end);
|
|
191
|
+
return from === null || to === null || to < from ? null : text.slice(from, to);
|
|
161
192
|
}
|
|
162
193
|
/* `text` with the range replaced; null when the range is not in it. */
|
|
163
194
|
export function replaceRange(text, range, replacement) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
195
|
+
const from = offsetOf(text, range.start);
|
|
196
|
+
const to = offsetOf(text, range.end);
|
|
197
|
+
return from === null || to === null || to < from ? null : `${text.slice(0, from)}${replacement}${text.slice(to)}`;
|
|
167
198
|
}
|
|
168
199
|
/*
|
|
169
200
|
* Where `selected` stands in `text` now: its own range while it still holds, and otherwise the one
|
|
170
201
|
* place it occurs when lines moved. Null when it is gone or ambiguous, which is a selection that changed.
|
|
171
202
|
*/
|
|
172
203
|
export function locateSelection(text, range, selected) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
204
|
+
if (textInRange(text, range) === selected) {
|
|
205
|
+
return range;
|
|
206
|
+
}
|
|
207
|
+
if (selected === '') {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
const first = text.indexOf(selected);
|
|
211
|
+
if (first === -1 || text.indexOf(selected, first + 1) !== -1) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
start: positionAt(text, first),
|
|
216
|
+
end: positionAt(text, first + selected.length)
|
|
217
|
+
};
|
|
184
218
|
}
|
|
185
219
|
function positionAt(text, offset) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
220
|
+
const before = text.slice(0, offset);
|
|
221
|
+
const line = before.split('\n').length - 1;
|
|
222
|
+
return {
|
|
223
|
+
line,
|
|
224
|
+
character: offset - (before.lastIndexOf('\n') + 1)
|
|
225
|
+
};
|
|
226
|
+
}
|
package/dist/recent-choices.js
CHANGED
|
@@ -5,35 +5,35 @@ const LIMIT = 200;
|
|
|
5
5
|
* memory only, one per language, and forgets the oldest choice past a few hundred.
|
|
6
6
|
*/
|
|
7
7
|
export class RecentChoices {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/* Higher for a later choice, 0 for an item never chosen. */
|
|
23
|
-
recency(item) {
|
|
24
|
-
return this.order.get(RecentChoices.keyOf(item)) ?? 0;
|
|
8
|
+
order = new Map();
|
|
9
|
+
tick = 0;
|
|
10
|
+
/* An item is told by its label, its kind and where it comes from, so two `Property` of two namespaces are two choices. */
|
|
11
|
+
static keyOf(item) {
|
|
12
|
+
return `${item.label}\0${item.kind ?? ''}\0${qualifierOf(item)}`;
|
|
13
|
+
}
|
|
14
|
+
record(item) {
|
|
15
|
+
const key = RecentChoices.keyOf(item);
|
|
16
|
+
this.order.delete(key);
|
|
17
|
+
this.order.set(key, ++this.tick);
|
|
18
|
+
if (this.order.size > LIMIT) {
|
|
19
|
+
this.order.delete(this.order.keys().next().value);
|
|
25
20
|
}
|
|
21
|
+
}
|
|
22
|
+
/* Higher for a later choice, 0 for an item never chosen. */
|
|
23
|
+
recency(item) {
|
|
24
|
+
return this.order.get(RecentChoices.keyOf(item)) ?? 0;
|
|
25
|
+
}
|
|
26
26
|
}
|
|
27
27
|
const stores = new Map();
|
|
28
28
|
export function recentChoicesOf(languageId) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
let store = stores.get(languageId);
|
|
30
|
+
if (store === undefined) {
|
|
31
|
+
store = new RecentChoices();
|
|
32
|
+
stores.set(languageId, store);
|
|
33
|
+
}
|
|
34
|
+
return store;
|
|
35
35
|
}
|
|
36
36
|
/* For a test that must not hear the choices an earlier one made. */
|
|
37
37
|
export function forgetRecentChoices() {
|
|
38
|
-
|
|
39
|
-
}
|
|
38
|
+
stores.clear();
|
|
39
|
+
}
|
package/dist/refresher.js
CHANGED
|
@@ -5,56 +5,51 @@ import { realTimers } from './timers.js';
|
|
|
5
5
|
* A newer ask aborts the one before it, and an answer for a text that moved on is dropped.
|
|
6
6
|
*/
|
|
7
7
|
export class Refresher {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
this.timers.clear(this.timer);
|
|
29
|
-
this.controller?.abort();
|
|
30
|
-
const controller = new AbortController();
|
|
31
|
-
this.controller = controller;
|
|
32
|
-
this.run(controller.signal).catch((error) => {
|
|
33
|
-
// A server that cannot answer yet is asked again when it says it can; a stale text is asked again by its own change.
|
|
34
|
-
if (!(error instanceof StaleResultError) && !controller.signal.aborted && !isQuiet(error)) {
|
|
35
|
-
console.warn('Language request failed', error);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
/* Drops the wait and the ask in flight, and keeps the refresher usable. */
|
|
40
|
-
cancel() {
|
|
41
|
-
this.timers.clear(this.timer);
|
|
42
|
-
this.controller?.abort();
|
|
43
|
-
}
|
|
44
|
-
dispose() {
|
|
45
|
-
this.disposed = true;
|
|
46
|
-
this.timers.clear(this.timer);
|
|
47
|
-
this.controller?.abort();
|
|
8
|
+
timer;
|
|
9
|
+
controller = null;
|
|
10
|
+
disposed = false;
|
|
11
|
+
timers;
|
|
12
|
+
delay;
|
|
13
|
+
run;
|
|
14
|
+
constructor(run, delay, timers = realTimers) {
|
|
15
|
+
this.run = run;
|
|
16
|
+
this.delay = delay;
|
|
17
|
+
this.timers = timers;
|
|
18
|
+
}
|
|
19
|
+
/* After a pause: every call starts the wait again. */
|
|
20
|
+
later() {
|
|
21
|
+
this.timers.clear(this.timer);
|
|
22
|
+
this.timer = this.timers.set(() => this.now(), this.delay);
|
|
23
|
+
}
|
|
24
|
+
now() {
|
|
25
|
+
if (this.disposed) {
|
|
26
|
+
return;
|
|
48
27
|
}
|
|
28
|
+
this.timers.clear(this.timer);
|
|
29
|
+
this.controller?.abort();
|
|
30
|
+
const controller = new AbortController();
|
|
31
|
+
this.controller = controller;
|
|
32
|
+
this.run(controller.signal).catch(error => {
|
|
33
|
+
// A server that cannot answer yet is asked again when it says it can; a stale text is asked again by its own change.
|
|
34
|
+
if (!(error instanceof StaleResultError) && !controller.signal.aborted && !isQuiet(error)) {
|
|
35
|
+
console.warn('Language request failed', error);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/* Drops the wait and the ask in flight, and keeps the refresher usable. */
|
|
40
|
+
cancel() {
|
|
41
|
+
this.timers.clear(this.timer);
|
|
42
|
+
this.controller?.abort();
|
|
43
|
+
}
|
|
44
|
+
dispose() {
|
|
45
|
+
this.disposed = true;
|
|
46
|
+
this.timers.clear(this.timer);
|
|
47
|
+
this.controller?.abort();
|
|
48
|
+
}
|
|
49
49
|
}
|
|
50
|
-
const QUIET_CODES = new Set([
|
|
51
|
-
ErrorCodes.ServerNotInitialized,
|
|
52
|
-
ErrorCodes.MethodNotFound,
|
|
53
|
-
ErrorCodes.RequestCancelled,
|
|
54
|
-
ErrorCodes.ContentModified
|
|
55
|
-
]);
|
|
50
|
+
const QUIET_CODES = new Set([ErrorCodes.ServerNotInitialized, ErrorCodes.MethodNotFound, ErrorCodes.RequestCancelled, ErrorCodes.ContentModified]);
|
|
56
51
|
/* A server that is not up, does not offer the feature or was asked to stop is not worth a line in the console. */
|
|
57
52
|
function isQuiet(error) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
53
|
+
const code = error?.code;
|
|
54
|
+
return code !== undefined && QUIET_CODES.has(code);
|
|
55
|
+
}
|