@adecore/editor-react 0.31.12 → 0.33.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 (137) hide show
  1. package/dist/AnchoredPopup.js +73 -19
  2. package/dist/AttributionCard.js +162 -4
  3. package/dist/BaselineStatus.js +62 -8
  4. package/dist/CallHierarchyPanel.js +977 -60
  5. package/dist/ChangeReview.js +76 -25
  6. package/dist/CodeAuthorsCard.js +314 -14
  7. package/dist/CompletionPopup.js +490 -83
  8. package/dist/DiffView.js +548 -181
  9. package/dist/EditorContextMenu.js +352 -34
  10. package/dist/EditorView.js +276 -99
  11. package/dist/FindReplace.js +525 -67
  12. package/dist/HoverCard.js +378 -38
  13. package/dist/HoverSections.js +367 -56
  14. package/dist/LanguagePopups.js +95 -34
  15. package/dist/Markdown.js +41 -6
  16. package/dist/PanelResizeHandle.js +199 -66
  17. package/dist/PathText.js +49 -7
  18. package/dist/PeekPanel.js +675 -72
  19. package/dist/PickPopup.js +304 -34
  20. package/dist/RenameCard.js +679 -85
  21. package/dist/RenderedDocs.js +329 -58
  22. package/dist/SignatureCard.js +91 -7
  23. package/dist/SplitDiffView.js +344 -254
  24. package/dist/SymbolPicker.js +440 -85
  25. package/dist/call-hierarchy-model.js +102 -68
  26. package/dist/call-hierarchy.js +458 -359
  27. package/dist/code-actions-model.js +88 -76
  28. package/dist/code-actions.js +372 -283
  29. package/dist/code-authors.js +64 -55
  30. package/dist/code-vision-model.js +134 -127
  31. package/dist/code-vision.js +224 -206
  32. package/dist/completion-call.js +94 -67
  33. package/dist/completion-model.js +334 -244
  34. package/dist/completion.js +840 -649
  35. package/dist/conflict-model.js +35 -29
  36. package/dist/context-menu-rows.js +42 -17
  37. package/dist/context-menu.js +64 -46
  38. package/dist/definition-link.js +88 -85
  39. package/dist/diagnostics-model.js +74 -55
  40. package/dist/diagnostics.js +121 -100
  41. package/dist/diff-expansion.js +38 -35
  42. package/dist/diff-overlays.js +144 -22
  43. package/dist/diff-syntax.js +65 -42
  44. package/dist/diff-wordmarks.js +26 -23
  45. package/dist/doc-comment-model.js +265 -216
  46. package/dist/editor-language.js +177 -152
  47. package/dist/error-message.js +2 -2
  48. package/dist/find-query.js +49 -36
  49. package/dist/folding.js +81 -62
  50. package/dist/format-on-type.js +86 -67
  51. package/dist/highlight-layers.js +19 -20
  52. package/dist/highlights.js +105 -83
  53. package/dist/history.js +44 -38
  54. package/dist/holder.js +18 -18
  55. package/dist/host-types.js +1 -1
  56. package/dist/hover-content.js +167 -129
  57. package/dist/hover.js +285 -245
  58. package/dist/index.js +10 -10
  59. package/dist/inlay-hints.js +369 -324
  60. package/dist/key-priority.js +34 -31
  61. package/dist/language-ids.js +45 -42
  62. package/dist/line-edits.js +74 -28
  63. package/dist/line-text.js +18 -3
  64. package/dist/locales/en.json +38 -38
  65. package/dist/locales/nl.json +41 -41
  66. package/dist/models.js +1 -1
  67. package/dist/navigation-history.js +40 -41
  68. package/dist/navigation.js +141 -123
  69. package/dist/panel-size.js +8 -8
  70. package/dist/patch-decorations.js +236 -160
  71. package/dist/patch-layout.js +331 -262
  72. package/dist/paths.js +3 -3
  73. package/dist/peek-model.js +86 -69
  74. package/dist/peek.js +254 -192
  75. package/dist/pick.js +164 -157
  76. package/dist/popup-focus.js +5 -5
  77. package/dist/popup-placement.js +36 -21
  78. package/dist/popups.js +13 -13
  79. package/dist/project-language.js +228 -211
  80. package/dist/project-problems.js +81 -69
  81. package/dist/proposal-model.js +163 -126
  82. package/dist/recent-choices.js +25 -25
  83. package/dist/refresher.js +44 -49
  84. package/dist/rename-model.js +113 -113
  85. package/dist/rename.js +321 -233
  86. package/dist/rendered-docs.d.ts +4 -2
  87. package/dist/rendered-docs.js +384 -318
  88. package/dist/rendering-context.js +5 -3
  89. package/dist/rendering.js +22 -4
  90. package/dist/review-group.js +42 -39
  91. package/dist/row-host.d.ts +4 -2
  92. package/dist/row-host.js +90 -78
  93. package/dist/selection-ranges.js +21 -17
  94. package/dist/semantic-delta.js +22 -19
  95. package/dist/semantic-model.js +86 -73
  96. package/dist/semantic-tokens.js +201 -162
  97. package/dist/shortcut-keys.js +16 -10
  98. package/dist/signature-model.js +34 -28
  99. package/dist/signature.js +177 -129
  100. package/dist/snippet-field-transforms.js +118 -106
  101. package/dist/snippet-indent.js +48 -43
  102. package/dist/snippet-range-order.js +11 -11
  103. package/dist/snippet-session.js +703 -667
  104. package/dist/snippet-transform-client.js +59 -59
  105. package/dist/snippet-transform-format.js +285 -263
  106. package/dist/snippet-transform-protocol.js +1 -1
  107. package/dist/snippet-transform-queue.js +163 -153
  108. package/dist/snippet-transform-worker.js +42 -35
  109. package/dist/snippet-variable-names.js +1 -36
  110. package/dist/snippet-variables.js +53 -63
  111. package/dist/snippet.js +477 -405
  112. package/dist/split-alignment.js +47 -35
  113. package/dist/split-scroll.js +42 -40
  114. package/dist/symbol-links.js +33 -25
  115. package/dist/symbol-picker-model.js +126 -116
  116. package/dist/symbol-picker.js +98 -59
  117. package/dist/symbols.js +117 -88
  118. package/dist/testing.js +248 -165
  119. package/dist/timers.js +35 -30
  120. package/dist/use-panel-body.js +49 -8
  121. package/dist/use-problem-counts.js +29 -15
  122. package/dist/view-state.js +54 -33
  123. package/dist/word-diff.js +18 -18
  124. package/dist/workspace-edit.js +300 -249
  125. package/package.json +6 -6
  126. package/src/CallHierarchyPanel.tsx +2 -2
  127. package/src/DiffView.tsx +3 -3
  128. package/src/FindReplace.tsx +2 -2
  129. package/src/LanguagePopups.tsx +2 -0
  130. package/src/PeekPanel.tsx +3 -3
  131. package/src/RenderedDocs.tsx +9 -10
  132. package/src/SymbolPicker.tsx +2 -2
  133. package/src/diff-overlays.tsx +6 -4
  134. package/src/locales/en.json +38 -38
  135. package/src/locales/nl.json +41 -41
  136. package/src/rendered-docs.ts +14 -3
  137. package/src/row-host.ts +14 -3
@@ -11,68 +11,107 @@ const TOAST_ID = 'language-symbols';
11
11
  * its own input, so the editor only has to open it.
12
12
  */
13
13
  export class SymbolPickerFeature {
14
- language;
15
- constructor(language) {
16
- this.language = language;
17
- const off = language.onKey((event) => {
18
- if (!isShortcut(this.language.shortcuts.goToSymbol, event)) {
19
- return false;
20
- }
21
- void this.open();
22
- return true;
23
- }, KEY_PRIORITY.symbolPicker);
24
- language.onDispose(() => {
25
- off();
26
- this.close();
27
- });
28
- }
29
- async open() {
30
- const { project, uri, popups } = this.language;
31
- if (!project.service.supports('textDocument/documentSymbol', uri)) {
32
- this.language.project.host.notify?.({ id: TOAST_ID, kind: 'error', title: this.language.project.i18n.t('editor:language.symbols.unavailable') });
33
- return;
34
- }
35
- try {
36
- const entries = entriesOf(await project.service.documentSymbols(uri));
37
- popups.setState({ symbols: { file: basenameOf(this.language.uri), entries } });
38
- }
39
- catch (error) {
40
- if (!(error instanceof StaleResultError)) {
41
- this.language.project.host.notify?.({
42
- id: TOAST_ID,
43
- kind: 'error',
44
- title: this.language.project.i18n.t('editor:language.symbols.failed', { message: messageOf(error) })
45
- });
46
- }
47
- }
14
+ language;
15
+ constructor(language) {
16
+ this.language = language;
17
+ const off = language.onKey(event => {
18
+ if (!isShortcut(this.language.shortcuts.goToSymbol, event)) {
19
+ return false;
20
+ }
21
+ void this.open();
22
+ return true;
23
+ }, KEY_PRIORITY.symbolPicker);
24
+ language.onDispose(() => {
25
+ off();
26
+ this.close();
27
+ });
28
+ }
29
+ async open() {
30
+ const {
31
+ project,
32
+ uri,
33
+ popups
34
+ } = this.language;
35
+ if (!project.service.supports('textDocument/documentSymbol', uri)) {
36
+ this.language.project.host.notify?.({
37
+ id: TOAST_ID,
38
+ kind: 'error',
39
+ title: this.language.project.i18n.t('editor:language.symbols.unavailable')
40
+ });
41
+ return;
48
42
  }
49
- close() {
50
- if (this.language.popups.getState().symbols !== null) {
51
- this.language.popups.setState({ symbols: null });
52
- this.language.editor.focus();
43
+ try {
44
+ const entries = entriesOf(await project.service.documentSymbols(uri));
45
+ popups.setState({
46
+ symbols: {
47
+ file: basenameOf(this.language.uri),
48
+ entries
53
49
  }
50
+ });
51
+ } catch (error) {
52
+ if (!(error instanceof StaleResultError)) {
53
+ this.language.project.host.notify?.({
54
+ id: TOAST_ID,
55
+ kind: 'error',
56
+ title: this.language.project.i18n.t('editor:language.symbols.failed', {
57
+ message: messageOf(error)
58
+ })
59
+ });
60
+ }
54
61
  }
55
- /* Puts the caret on a symbol of the file. */
56
- goTo(entry) {
57
- this.close();
58
- this.language.jump({ line: entry.line, character: entry.character });
62
+ }
63
+ close() {
64
+ if (this.language.popups.getState().symbols !== null) {
65
+ this.language.popups.setState({
66
+ symbols: null
67
+ });
68
+ this.language.editor.focus();
59
69
  }
60
- /* Puts the caret on a one-based line. */
61
- goToLine(line) {
62
- this.close();
63
- this.language.jump({ line: line - 1, character: 0 });
70
+ }
71
+ /* Puts the caret on a symbol of the file. */
72
+ goTo(entry) {
73
+ this.close();
74
+ this.language.jump({
75
+ line: entry.line,
76
+ character: entry.character
77
+ });
78
+ }
79
+ /* Puts the caret on a one-based line. */
80
+ goToLine(line) {
81
+ this.close();
82
+ this.language.jump({
83
+ line: line - 1,
84
+ character: 0
85
+ });
86
+ }
87
+ /* The symbols of the project that answer to a name, which is a request to the server and so waits for a pause in the typing. */
88
+ async search(text, signal) {
89
+ const {
90
+ project,
91
+ uri
92
+ } = this.language;
93
+ if (text === '' || !project.service.supports('workspace/symbol', uri)) {
94
+ return [];
64
95
  }
65
- /* The symbols of the project that answer to a name, which is a request to the server and so waits for a pause in the typing. */
66
- async search(text, signal) {
67
- const { project, uri } = this.language;
68
- if (text === '' || !project.service.supports('workspace/symbol', uri)) {
69
- return [];
96
+ return workspaceEntriesOf(await project.service.workspaceSymbols(uri, text, {
97
+ signal
98
+ }));
99
+ }
100
+ goToWorkspace(entry) {
101
+ this.close();
102
+ const location = {
103
+ uri: entry.uri,
104
+ range: {
105
+ start: {
106
+ line: entry.line,
107
+ character: 0
108
+ },
109
+ end: {
110
+ line: entry.line,
111
+ character: 0
70
112
  }
71
- return workspaceEntriesOf(await project.service.workspaceSymbols(uri, text, { signal }));
72
- }
73
- goToWorkspace(entry) {
74
- this.close();
75
- const location = { uri: entry.uri, range: { start: { line: entry.line, character: 0 }, end: { line: entry.line, character: 0 } } };
76
- this.language.goTo(location);
77
- }
78
- }
113
+ }
114
+ };
115
+ this.language.goTo(location);
116
+ }
117
+ }
package/dist/symbols.js CHANGED
@@ -4,36 +4,45 @@ const METHOD = 'textDocument/documentSymbol';
4
4
  const PAUSE_MS = 500;
5
5
  /* The names a breadcrumb and a sticky header know a symbol kind by; a kind left out is not a block worth pinning. */
6
6
  const KINDS = {
7
- 2: 'module',
8
- 3: 'namespace',
9
- 4: 'package',
10
- 5: 'class',
11
- 6: 'method',
12
- 9: 'constructor',
13
- 10: 'enum',
14
- 11: 'interface',
15
- 12: 'function',
16
- 13: 'variable',
17
- 14: 'constant',
18
- 23: 'struct'
7
+ 2: 'module',
8
+ 3: 'namespace',
9
+ 4: 'package',
10
+ 5: 'class',
11
+ 6: 'method',
12
+ 9: 'constructor',
13
+ 10: 'enum',
14
+ 11: 'interface',
15
+ 12: 'function',
16
+ 13: 'variable',
17
+ 14: 'constant',
18
+ 23: 'struct'
19
19
  };
20
20
  function walk(symbols, spans) {
21
- for (const symbol of symbols) {
22
- spans.push({ name: symbol.name, kind: symbol.kind, range: symbol.range, nameLine: symbol.selectionRange?.start.line });
23
- walk(symbol.children ?? [], spans);
24
- }
21
+ for (const symbol of symbols) {
22
+ spans.push({
23
+ name: symbol.name,
24
+ kind: symbol.kind,
25
+ range: symbol.range,
26
+ nameLine: symbol.selectionRange?.start.line
27
+ });
28
+ walk(symbol.children ?? [], spans);
29
+ }
25
30
  }
26
31
  /* Every symbol of an answer, a parent before its children, whether the server sent a tree or a flat list. */
27
32
  export function symbolSpansOf(result) {
28
- const spans = [];
29
- if (result === null || result.length === 0) {
30
- return spans;
31
- }
32
- if ('range' in result[0]) {
33
- walk(result, spans);
34
- return spans;
35
- }
36
- return result.map((symbol) => ({ name: symbol.name, kind: symbol.kind, range: symbol.location.range }));
33
+ const spans = [];
34
+ if (result === null || result.length === 0) {
35
+ return spans;
36
+ }
37
+ if ('range' in result[0]) {
38
+ walk(result, spans);
39
+ return spans;
40
+ }
41
+ return result.map(symbol => ({
42
+ name: symbol.name,
43
+ kind: symbol.kind,
44
+ range: symbol.location.range
45
+ }));
37
46
  }
38
47
  /* A line a declaration can have above it: blank, a comment, or an attribute. A bare `#` is no comment, since it heads a Markdown section. */
39
48
  const PRELUDE = /^\s*(?:$|\/\/|\/\*|\*|#\[)/;
@@ -41,81 +50,101 @@ const PRELUDE = /^\s*(?:$|\/\/|\/\*|\*|#\[)/;
41
50
  * The line a block is pinned by. A range may begin at the doc comment or the attributes of a declaration, so the
42
51
  * line of the name wins, and without it the first line below the comment that holds the name.
43
52
  */
44
- function headerLineOf({ name, range, nameLine }, lines) {
45
- const { start, end } = range;
46
- if (nameLine !== undefined && nameLine >= start.line && nameLine <= end.line) {
47
- return nameLine;
53
+ function headerLineOf({
54
+ name,
55
+ range,
56
+ nameLine
57
+ }, lines) {
58
+ const {
59
+ start,
60
+ end
61
+ } = range;
62
+ if (nameLine !== undefined && nameLine >= start.line && nameLine <= end.line) {
63
+ return nameLine;
64
+ }
65
+ if (lines === undefined) {
66
+ return start.line;
67
+ }
68
+ const last = Math.min(end.line, lines.length - 1);
69
+ let first = start.line;
70
+ while (first < last && PRELUDE.test(lines[first] ?? '')) {
71
+ first++;
72
+ }
73
+ const short = name.slice(name.lastIndexOf('\\') + 1);
74
+ for (let line = first; line <= last; line++) {
75
+ if (!PRELUDE.test(lines[line] ?? '') && (lines[line] ?? '').includes(short)) {
76
+ return line;
48
77
  }
49
- if (lines === undefined) {
50
- return start.line;
51
- }
52
- const last = Math.min(end.line, lines.length - 1);
53
- let first = start.line;
54
- while (first < last && PRELUDE.test(lines[first] ?? '')) {
55
- first++;
56
- }
57
- const short = name.slice(name.lastIndexOf('\\') + 1);
58
- for (let line = first; line <= last; line++) {
59
- if (!PRELUDE.test(lines[line] ?? '') && (lines[line] ?? '').includes(short)) {
60
- return line;
61
- }
62
- }
63
- return first;
78
+ }
79
+ return first;
64
80
  }
65
81
  function blockOf(span, lines) {
66
- const { name, kind, range } = span;
67
- const label = KINDS[kind];
68
- // A one-line symbol has no body to pin, and a property or an enum member is part of the block around it.
69
- return label === undefined || range.end.line <= range.start.line
70
- ? null
71
- : { startLine: headerLineOf(span, lines) + 1, endLine: range.end.line + 1, name, kind: label };
82
+ const {
83
+ name,
84
+ kind,
85
+ range
86
+ } = span;
87
+ const label = KINDS[kind];
88
+ // A one-line symbol has no body to pin, and a property or an enum member is part of the block around it.
89
+ return label === undefined || range.end.line <= range.start.line ? null : {
90
+ startLine: headerLineOf(span, lines) + 1,
91
+ endLine: range.end.line + 1,
92
+ name,
93
+ kind: label
94
+ };
72
95
  }
73
96
  /*
74
97
  * The multi-line symbols of a file as blocks, outermost first, in one-based lines. The text of the document
75
98
  * lets a block start at its declaration rather than at the comment a server counts into the symbol.
76
99
  */
77
100
  export function blocksOf(result, text) {
78
- const lines = text?.split('\n');
79
- const blocks = symbolSpansOf(result).flatMap((span) => blockOf(span, lines) ?? []);
80
- return blocks.sort((left, right) => left.startLine - right.startLine || right.endLine - left.endLine);
101
+ const lines = text?.split('\n');
102
+ const blocks = symbolSpansOf(result).flatMap(span => blockOf(span, lines) ?? []);
103
+ return blocks.sort((left, right) => left.startLine - right.startLine || right.endLine - left.endLine);
81
104
  }
82
105
  /*
83
106
  * The symbols of the file as the blocks sticky scroll and the breadcrumb go by, with their real names. Until
84
107
  * the first answer, and wherever no server has symbols, the editor reads blocks off the text itself.
85
108
  */
86
109
  export class SymbolsFeature {
87
- refresher;
88
- listeners = new Set();
89
- constructor(language, timers = realTimers) {
90
- const { editor, project, uri } = language;
91
- this.refresher = new Refresher(async (signal) => {
92
- if (!project.service.supports(METHOD, uri)) {
93
- return;
94
- }
95
- const result = await project.service.documentSymbols(uri, { signal });
96
- if (!signal.aborted) {
97
- editor.setBlocks(result === null ? null : blocksOf(result, editor.getText()));
98
- for (const listener of [...this.listeners]) {
99
- listener(result);
100
- }
101
- }
102
- }, PAUSE_MS, timers);
103
- const edits = editor.onTextChange(() => this.refresher.later());
104
- const providers = language.onProvidersChanged(() => {
105
- this.refresher.now();
106
- });
107
- language.onDispose(() => {
108
- edits();
109
- providers();
110
- this.refresher.dispose();
111
- editor.setBlocks(null);
112
- });
113
- }
114
- /* Called with every answer that was not replaced before it came. */
115
- onResult(listener) {
116
- this.listeners.add(listener);
117
- return () => {
118
- this.listeners.delete(listener);
119
- };
120
- }
121
- }
110
+ refresher;
111
+ listeners = new Set();
112
+ constructor(language, timers = realTimers) {
113
+ const {
114
+ editor,
115
+ project,
116
+ uri
117
+ } = language;
118
+ this.refresher = new Refresher(async signal => {
119
+ if (!project.service.supports(METHOD, uri)) {
120
+ return;
121
+ }
122
+ const result = await project.service.documentSymbols(uri, {
123
+ signal
124
+ });
125
+ if (!signal.aborted) {
126
+ editor.setBlocks(result === null ? null : blocksOf(result, editor.getText()));
127
+ for (const listener of [...this.listeners]) {
128
+ listener(result);
129
+ }
130
+ }
131
+ }, PAUSE_MS, timers);
132
+ const edits = editor.onTextChange(() => this.refresher.later());
133
+ const providers = language.onProvidersChanged(() => {
134
+ this.refresher.now();
135
+ });
136
+ language.onDispose(() => {
137
+ edits();
138
+ providers();
139
+ this.refresher.dispose();
140
+ editor.setBlocks(null);
141
+ });
142
+ }
143
+ /* Called with every answer that was not replaced before it came. */
144
+ onResult(listener) {
145
+ this.listeners.add(listener);
146
+ return () => {
147
+ this.listeners.delete(listener);
148
+ };
149
+ }
150
+ }