@adecore/editor-react 0.41.1 → 0.43.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.
Files changed (124) hide show
  1. package/dist/CallHierarchyPanel.js +177 -181
  2. package/dist/EditorContextMenu.js +118 -105
  3. package/dist/EditorView.js +7 -1
  4. package/dist/LanguagePopups.js +7 -0
  5. package/dist/PickPopup.js +190 -70
  6. package/dist/WrapCard.d.ts +8 -0
  7. package/dist/WrapCard.js +172 -0
  8. package/dist/call-hierarchy-model.d.ts +4 -2
  9. package/dist/call-hierarchy-model.js +20 -0
  10. package/dist/call-hierarchy.d.ts +3 -0
  11. package/dist/call-hierarchy.js +54 -22
  12. package/dist/clipboard-history.d.ts +31 -0
  13. package/dist/clipboard-history.js +70 -0
  14. package/dist/code-actions.d.ts +3 -1
  15. package/dist/code-actions.js +50 -10
  16. package/dist/code-vision.js +2 -3
  17. package/dist/completion.js +10 -15
  18. package/dist/context-menu-rows.d.ts +1 -1
  19. package/dist/context-menu-rows.js +4 -0
  20. package/dist/definition-link.js +15 -5
  21. package/dist/document-colors.d.ts +24 -0
  22. package/dist/document-colors.js +194 -0
  23. package/dist/document-links.d.ts +22 -0
  24. package/dist/document-links.js +133 -0
  25. package/dist/document-query.d.ts +15 -0
  26. package/dist/document-query.js +54 -0
  27. package/dist/edit-locations.d.ts +20 -0
  28. package/dist/edit-locations.js +136 -0
  29. package/dist/editor-language.d.ts +19 -1
  30. package/dist/editor-language.js +77 -2
  31. package/dist/emmet.d.ts +13 -0
  32. package/dist/emmet.js +62 -0
  33. package/dist/folding.js +2 -3
  34. package/dist/format-on-type.js +3 -5
  35. package/dist/highlights.js +2 -3
  36. package/dist/history.d.ts +7 -0
  37. package/dist/history.js +79 -1
  38. package/dist/host-types.d.ts +6 -0
  39. package/dist/index.d.ts +11 -2
  40. package/dist/index.js +8 -0
  41. package/dist/inlay-hints.js +2 -2
  42. package/dist/inline-completion.d.ts +39 -0
  43. package/dist/inline-completion.js +221 -0
  44. package/dist/key-priority.d.ts +8 -5
  45. package/dist/key-priority.js +9 -6
  46. package/dist/linked-editing.d.ts +26 -0
  47. package/dist/linked-editing.js +215 -0
  48. package/dist/locales/en.json +31 -2
  49. package/dist/locales/nl.json +31 -2
  50. package/dist/markup-context.d.ts +37 -0
  51. package/dist/markup-context.js +291 -0
  52. package/dist/markup.d.ts +36 -0
  53. package/dist/markup.js +453 -0
  54. package/dist/navigation.js +4 -6
  55. package/dist/paste-history.d.ts +7 -0
  56. package/dist/paste-history.js +104 -0
  57. package/dist/peek.js +3 -4
  58. package/dist/pick.d.ts +20 -2
  59. package/dist/pick.js +141 -18
  60. package/dist/popups.d.ts +9 -0
  61. package/dist/popups.js +2 -1
  62. package/dist/project-language.d.ts +18 -1
  63. package/dist/project-language.js +129 -18
  64. package/dist/rename.js +8 -11
  65. package/dist/rendered-docs.js +1 -2
  66. package/dist/selection-ranges.js +2 -3
  67. package/dist/shortcut-keys.d.ts +27 -0
  68. package/dist/signature.js +3 -6
  69. package/dist/snippet-session.d.ts +2 -2
  70. package/dist/snippet-session.js +3 -3
  71. package/dist/symbol-picker.js +4 -6
  72. package/dist/symbols.js +22 -3
  73. package/dist/testing.d.ts +23 -1
  74. package/dist/testing.js +114 -0
  75. package/package.json +7 -6
  76. package/src/CallHierarchyPanel.tsx +26 -11
  77. package/src/EditorContextMenu.tsx +7 -0
  78. package/src/EditorView.tsx +9 -0
  79. package/src/LanguagePopups.tsx +4 -0
  80. package/src/PickPopup.tsx +40 -5
  81. package/src/WrapCard.tsx +64 -0
  82. package/src/call-hierarchy-model.ts +25 -3
  83. package/src/call-hierarchy.ts +62 -20
  84. package/src/clipboard-history.ts +102 -0
  85. package/src/code-actions.ts +48 -11
  86. package/src/code-vision.ts +3 -3
  87. package/src/completion.ts +15 -15
  88. package/src/context-menu-rows.ts +3 -2
  89. package/src/definition-link.ts +17 -5
  90. package/src/document-colors.ts +189 -0
  91. package/src/document-links.ts +129 -0
  92. package/src/document-query.ts +71 -0
  93. package/src/edit-locations.ts +162 -0
  94. package/src/editor-language.ts +80 -3
  95. package/src/emmet-module.d.ts +44 -0
  96. package/src/emmet.ts +73 -0
  97. package/src/folding.ts +3 -3
  98. package/src/format-on-type.ts +5 -5
  99. package/src/highlights.ts +3 -3
  100. package/src/history.ts +81 -1
  101. package/src/host-types.ts +10 -0
  102. package/src/index.ts +12 -3
  103. package/src/inlay-hints.ts +2 -2
  104. package/src/inline-completion.ts +221 -0
  105. package/src/key-priority.ts +9 -6
  106. package/src/linked-editing.ts +199 -0
  107. package/src/locales/en.json +31 -2
  108. package/src/locales/nl.json +31 -2
  109. package/src/markup-context.ts +262 -0
  110. package/src/markup.ts +367 -0
  111. package/src/navigation.ts +6 -6
  112. package/src/paste-history.ts +111 -0
  113. package/src/peek.ts +4 -4
  114. package/src/pick.ts +201 -19
  115. package/src/popups.ts +19 -1
  116. package/src/project-language.ts +136 -19
  117. package/src/rename.ts +11 -11
  118. package/src/rendered-docs.ts +2 -2
  119. package/src/selection-ranges.ts +3 -3
  120. package/src/signature.ts +6 -6
  121. package/src/snippet-session.ts +9 -4
  122. package/src/symbol-picker.ts +6 -6
  123. package/src/symbols.ts +30 -4
  124. package/src/testing.ts +126 -1
@@ -70,6 +70,12 @@
70
70
  "delete": "Verwijdert"
71
71
  }
72
72
  },
73
+ "markup": {
74
+ "wrap": "Omwikkelen met afkorting",
75
+ "placeholder": "Afkorting, zoals div.card>p",
76
+ "apply": "Omwikkelen",
77
+ "invalid": "Geen geldige afkorting"
78
+ },
73
79
  "navigation": {
74
80
  "unavailable": "Hier niet beschikbaar",
75
81
  "none": "Niets gevonden",
@@ -119,13 +125,30 @@
119
125
  "site": "Aanroep {{current}} van {{total}}",
120
126
  "previousSite": "Vorige aanroep",
121
127
  "nextSite": "Volgende aanroep",
128
+ "typesUnavailable": "Typehiërarchie niet beschikbaar in dit bestand",
129
+ "typesNone": "Hier geen type",
130
+ "typesFailed": "Kon de types niet opzoeken: {{message}}",
131
+ "typesLabel": "Typehiërarchie",
132
+ "supertypes": "Supertypes",
133
+ "subtypes": "Subtypes",
134
+ "noSupertypes": "Geen supertypes",
135
+ "noSubtypes": "Geen subtypes",
122
136
  "announce": {
123
137
  "incoming_one": "{{count}} aanroeper van {{name}}",
124
138
  "incoming_other": "{{count}} aanroepers van {{name}}",
125
139
  "outgoing_one": "{{count}} aangeroepen door {{name}}",
126
- "outgoing_other": "{{count}} aangeroepen door {{name}}"
140
+ "outgoing_other": "{{count}} aangeroepen door {{name}}",
141
+ "supertypes_one": "{{count}} supertype van {{name}}",
142
+ "supertypes_other": "{{count}} supertypes van {{name}}",
143
+ "subtypes_one": "{{count}} subtype van {{name}}",
144
+ "subtypes_other": "{{count}} subtypes van {{name}}"
127
145
  }
128
146
  },
147
+ "colors": {
148
+ "swatch": "Kleur {{color}}",
149
+ "title": "Kleur",
150
+ "other": "Andere kleur kiezen…"
151
+ },
129
152
  "codeVision": {
130
153
  "usagesNone": "Niet gebruikt",
131
154
  "usages_one": "{{formatted}} keer gebruikt",
@@ -192,6 +215,10 @@
192
215
  "history": {
193
216
  "recent": "Recente plekken"
194
217
  },
218
+ "pasteHistory": {
219
+ "title": "Kies wat je plakt",
220
+ "empty": "Er is nog niets gekopieerd"
221
+ },
195
222
  "announce": {
196
223
  "problem": "{{severity}}: {{message}}",
197
224
  "severity": {
@@ -236,10 +263,12 @@
236
263
  "goToTypeDefinition": "Ga naar typedefinitie",
237
264
  "goToImplementation": "Ga naar implementatie",
238
265
  "callHierarchy": "Aanroephiërarchie",
266
+ "typeHierarchy": "Typehiërarchie",
239
267
  "peekReferences": "Bekijk referenties",
240
268
  "renameSymbol": "Symbool hernoemen",
241
269
  "codeActions": "Codeacties",
242
- "formatDocument": "Document formatteren"
270
+ "formatDocument": "Document formatteren",
271
+ "formatSelection": "Selectie formatteren"
243
272
  },
244
273
  "find": {
245
274
  "label": "Zoeken",
@@ -0,0 +1,262 @@
1
+ /* `vue` and `php` are HTML with interpolations or code blocks a markup feature leaves alone. */
2
+ export type MarkupSyntax = 'html' | 'xml' | 'vue' | 'php';
3
+
4
+ export interface OpenElement {
5
+ readonly name: string;
6
+ /* The offset of the first character of the name, after the `<`. */
7
+ readonly nameFrom: number;
8
+ }
9
+
10
+ /* The tag an offset is in, from its `<` up to and including its `>`. */
11
+ export interface TagAt {
12
+ readonly start: number;
13
+ readonly closing: boolean;
14
+ readonly name: string;
15
+ readonly nameFrom: number;
16
+ readonly nameTo: number;
17
+ /* The offset is inside a quoted attribute value. */
18
+ readonly inValue: boolean;
19
+ }
20
+
21
+ export type MarkupPlace =
22
+ | { readonly kind: 'text'; readonly open: readonly OpenElement[] }
23
+ | { readonly kind: 'tag'; readonly tag: TagAt }
24
+ | { readonly kind: 'other' };
25
+
26
+ /* The names of an element that are one start tag and its end tag, which change together. */
27
+ export interface TagPair {
28
+ readonly open: { readonly from: number; readonly to: number };
29
+ readonly close: { readonly from: number; readonly to: number };
30
+ }
31
+
32
+ /* Above this a document is not read on a keystroke; the features then do nothing in it. */
33
+ export const MAX_MARKUP_SCAN = 1_000_000;
34
+
35
+ const VOID_ELEMENTS = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
36
+ const RAW_ELEMENTS = new Set(['script', 'style', 'textarea', 'title']);
37
+ const NAME_START = /[A-Za-z]/;
38
+ const NAME = /[\w:.-]/;
39
+
40
+ export function markupSyntaxOf(languageId: string): MarkupSyntax | null {
41
+ switch (languageId.toLowerCase()) {
42
+ case 'html':
43
+ case 'xhtml':
44
+ return 'html';
45
+ case 'xml':
46
+ case 'svg':
47
+ case 'xsl':
48
+ return 'xml';
49
+ case 'vue':
50
+ return 'vue';
51
+ case 'php':
52
+ return 'php';
53
+ default:
54
+ return null;
55
+ }
56
+ }
57
+
58
+ /* Whether an element of this name has no end tag, which only HTML has. */
59
+ export function isVoidElement(name: string, syntax: MarkupSyntax): boolean {
60
+ return syntax !== 'xml' && VOID_ELEMENTS.has(name.toLowerCase());
61
+ }
62
+
63
+ class Stop {
64
+ readonly place: MarkupPlace;
65
+
66
+ constructor(place: MarkupPlace) {
67
+ this.place = place;
68
+ }
69
+ }
70
+
71
+ /*
72
+ * A reader of markup that is no parser: it follows tags, comments, raw elements and the code blocks of
73
+ * PHP and Vue far enough to tell what an offset is in, and pairs a start tag with the end tag that closes it.
74
+ */
75
+ class MarkupScanner {
76
+ readonly pairs: TagPair[] = [];
77
+ private readonly text: string;
78
+ private readonly syntax: MarkupSyntax;
79
+ private readonly until: number;
80
+ private readonly open: (OpenElement & { readonly nameTo: number })[] = [];
81
+
82
+ constructor(text: string, syntax: MarkupSyntax, until: number) {
83
+ this.text = text;
84
+ this.syntax = syntax;
85
+ this.until = until;
86
+ }
87
+
88
+ run(): MarkupPlace {
89
+ try {
90
+ this.content();
91
+ return this.textPlace();
92
+ } catch (error) {
93
+ if (error instanceof Stop) {
94
+ return error.place;
95
+ }
96
+ throw error;
97
+ }
98
+ }
99
+
100
+ private textPlace(): MarkupPlace {
101
+ return { kind: 'text', open: this.open.map(({ name, nameFrom }) => ({ name, nameFrom })) };
102
+ }
103
+
104
+ /* Leaves the scan with what the offset is in when it lies in `from` to `to`, `to` included where the construct owns its last character. */
105
+ private reached(from: number, to: number, place: () => MarkupPlace): void {
106
+ if (from < this.until && this.until <= to) {
107
+ throw new Stop(place());
108
+ }
109
+ }
110
+
111
+ private content(): void {
112
+ const { text } = this;
113
+ let at = 0;
114
+ while (at < text.length) {
115
+ if (at >= this.until) {
116
+ throw new Stop(this.textPlace());
117
+ }
118
+ const char = text[at]!;
119
+ if (char === '<') {
120
+ at = this.markup(at);
121
+ } else if (this.syntax === 'vue' && char === '{' && text[at + 1] === '{') {
122
+ at = this.skipTo(at, '}}');
123
+ } else {
124
+ at++;
125
+ }
126
+ }
127
+ }
128
+
129
+ /* Skips from `from` past `close`, the whole construct counting as something other than text. */
130
+ private skipTo(from: number, close: string): number {
131
+ const end = this.text.indexOf(close, from + 1);
132
+ const after = end === -1 ? this.text.length : end + close.length;
133
+ this.reached(from, end === -1 ? after : after - 1, () => ({ kind: 'other' }));
134
+ return after;
135
+ }
136
+
137
+ private markup(at: number): number {
138
+ const { text } = this;
139
+ if (text.startsWith('<!--', at)) {
140
+ return this.skipTo(at, '-->');
141
+ }
142
+ if (text.startsWith('<![CDATA[', at)) {
143
+ return this.skipTo(at, ']]>');
144
+ }
145
+ if (text[at + 1] === '?') {
146
+ return this.skipTo(at, this.syntax === 'php' ? '?>' : '>');
147
+ }
148
+ if (text[at + 1] === '!') {
149
+ return this.skipTo(at, '>');
150
+ }
151
+ const closing = text[at + 1] === '/';
152
+ const nameFrom = at + (closing ? 2 : 1);
153
+ if (!NAME_START.test(text[nameFrom] ?? '')) {
154
+ return at + 1;
155
+ }
156
+ let nameTo = nameFrom;
157
+ while (nameTo < text.length && NAME.test(text[nameTo]!)) {
158
+ nameTo++;
159
+ }
160
+ const name = text.slice(nameFrom, nameTo);
161
+ const end = this.tagEnd(at, closing, name, nameFrom, nameTo);
162
+ if (closing) {
163
+ this.close(name, nameFrom, nameTo);
164
+ return end;
165
+ }
166
+ const selfClosing = text[end - 2] === '/' && text[end - 1] === '>';
167
+ if (selfClosing || isVoidElement(name, this.syntax)) {
168
+ return end;
169
+ }
170
+ if (this.syntax !== 'xml' && RAW_ELEMENTS.has(name.toLowerCase())) {
171
+ return this.rawContent(end, name, nameFrom, nameTo);
172
+ }
173
+ this.open.push({ name, nameFrom, nameTo });
174
+ return end;
175
+ }
176
+
177
+ /* Reads the attributes of a tag up to the offset after its `>`, quotes and PHP blocks included. */
178
+ private tagEnd(start: number, closing: boolean, name: string, nameFrom: number, nameTo: number): number {
179
+ const { text } = this;
180
+ let at = nameTo;
181
+ let quote: string | null = null;
182
+ let valueFrom = -1;
183
+ while (at < text.length) {
184
+ const char = text[at]!;
185
+ if (this.syntax === 'php' && char === '<' && text[at + 1] === '?') {
186
+ at = this.skipTo(at, '?>');
187
+ continue;
188
+ }
189
+ if (quote !== null) {
190
+ if (char === quote) {
191
+ this.reached(valueFrom, at, () => ({ kind: 'tag', tag: { start, closing, name, nameFrom, nameTo, inValue: true } }));
192
+ quote = null;
193
+ }
194
+ } else if (char === '"' || char === "'") {
195
+ quote = char;
196
+ valueFrom = at;
197
+ } else if (char === '>') {
198
+ this.reached(start, at, () => ({ kind: 'tag', tag: { start, closing, name, nameFrom, nameTo, inValue: false } }));
199
+ return at + 1;
200
+ } else if (char === '<') {
201
+ // A tag that never closed ends where the next one starts.
202
+ this.reached(start, at, () => ({ kind: 'tag', tag: { start, closing, name, nameFrom, nameTo, inValue: false } }));
203
+ return at;
204
+ }
205
+ at++;
206
+ }
207
+ this.reached(start, text.length, () => ({
208
+ kind: 'tag',
209
+ tag: { start, closing, name, nameFrom, nameTo, inValue: quote !== null && this.until > valueFrom }
210
+ }));
211
+ return text.length;
212
+ }
213
+
214
+ /* The content of `script`, `style` and the like is not markup, up to the end tag of the element. */
215
+ private rawContent(from: number, name: string, nameFrom: number, nameTo: number): number {
216
+ const pattern = new RegExp(`</${name}(?=[\\s/>]|$)`, 'gi');
217
+ pattern.lastIndex = from;
218
+ const match = pattern.exec(this.text);
219
+ const end = match === null ? this.text.length : match.index;
220
+ this.reached(from - 1, end, () => ({ kind: 'other' }));
221
+ if (match === null) {
222
+ return end;
223
+ }
224
+ const closeFrom = end + 2;
225
+ const closeTo = closeFrom + name.length;
226
+ const after = this.tagEnd(end, true, this.text.slice(closeFrom, closeTo), closeFrom, closeTo);
227
+ this.pairs.push({ open: { from: nameFrom, to: nameTo }, close: { from: closeFrom, to: closeTo } });
228
+ return after;
229
+ }
230
+
231
+ /* An end tag closes the nearest open element of its name and every element left open inside it. */
232
+ private close(name: string, nameFrom: number, nameTo: number): void {
233
+ const caseless = this.syntax !== 'xml';
234
+ for (let index = this.open.length - 1; index >= 0; index--) {
235
+ const element = this.open[index]!;
236
+ if (element.name === name || (caseless && element.name.toLowerCase() === name.toLowerCase())) {
237
+ this.pairs.push({ open: { from: element.nameFrom, to: element.nameTo }, close: { from: nameFrom, to: nameTo } });
238
+ this.open.length = index;
239
+ return;
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ /* What `offset` is in; null for a document too large to read on a keystroke. */
246
+ export function markupPlaceAt(text: string, offset: number, syntax: MarkupSyntax): MarkupPlace | null {
247
+ if (text.length > MAX_MARKUP_SCAN) {
248
+ return null;
249
+ }
250
+ return new MarkupScanner(text, syntax, offset).run();
251
+ }
252
+
253
+ /* The start and end tag names of the element whose name holds `offset`, either one, its edges included. */
254
+ export function tagPairAt(text: string, offset: number, syntax: MarkupSyntax): TagPair | null {
255
+ if (text.length > MAX_MARKUP_SCAN) {
256
+ return null;
257
+ }
258
+ const scanner = new MarkupScanner(text, syntax, Infinity);
259
+ scanner.run();
260
+ const holds = (range: { from: number; to: number }): boolean => range.from <= offset && offset <= range.to;
261
+ return scanner.pairs.find((pair) => holds(pair.open) || holds(pair.close)) ?? null;
262
+ }