@adecore/editor-react 0.22.1 → 0.23.1

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 (209) hide show
  1. package/dist/CallHierarchyPanel.d.ts +6 -0
  2. package/dist/CallHierarchyPanel.js +92 -0
  3. package/dist/CompletionPopup.js +11 -3
  4. package/dist/DiffView.d.ts +22 -0
  5. package/dist/DiffView.js +203 -0
  6. package/dist/EditorContextMenu.js +1 -0
  7. package/dist/EditorView.js +18 -1
  8. package/dist/FindReplace.d.ts +1 -1
  9. package/dist/FindReplace.js +41 -11
  10. package/dist/HoverCard.js +2 -2
  11. package/dist/LanguagePopups.js +4 -1
  12. package/dist/Markdown.d.ts +2 -1
  13. package/dist/Markdown.js +8 -4
  14. package/dist/PanelResizeHandle.d.ts +8 -0
  15. package/dist/PanelResizeHandle.js +71 -0
  16. package/dist/PeekPanel.d.ts +3 -0
  17. package/dist/PeekPanel.js +7 -4
  18. package/dist/PickPopup.js +15 -2
  19. package/dist/RenameCard.js +10 -5
  20. package/dist/RenderedDocs.d.ts +9 -0
  21. package/dist/RenderedDocs.js +84 -0
  22. package/dist/SplitDiffView.d.ts +9 -0
  23. package/dist/SplitDiffView.js +276 -0
  24. package/dist/SymbolPicker.d.ts +3 -0
  25. package/dist/SymbolPicker.js +4 -3
  26. package/dist/call-hierarchy-model.d.ts +52 -0
  27. package/dist/call-hierarchy-model.js +93 -0
  28. package/dist/call-hierarchy.d.ts +42 -0
  29. package/dist/call-hierarchy.js +398 -0
  30. package/dist/code-actions-model.d.ts +2 -0
  31. package/dist/code-actions-model.js +12 -10
  32. package/dist/code-actions.js +3 -1
  33. package/dist/completion-model.d.ts +14 -4
  34. package/dist/completion-model.js +40 -33
  35. package/dist/completion.d.ts +4 -0
  36. package/dist/completion.js +257 -42
  37. package/dist/diagnostics.js +8 -6
  38. package/dist/diff-expansion.d.ts +9 -0
  39. package/dist/diff-expansion.js +41 -0
  40. package/dist/diff-overlays.d.ts +15 -0
  41. package/dist/diff-overlays.js +28 -0
  42. package/dist/diff-syntax.d.ts +16 -0
  43. package/dist/diff-syntax.js +49 -0
  44. package/dist/diff-wordmarks.d.ts +5 -0
  45. package/dist/diff-wordmarks.js +26 -0
  46. package/dist/doc-comment-model.d.ts +23 -0
  47. package/dist/doc-comment-model.js +291 -0
  48. package/dist/editor-language.d.ts +13 -1
  49. package/dist/editor-language.js +15 -5
  50. package/dist/editor-react.css +79 -0
  51. package/dist/format-on-type.d.ts +14 -0
  52. package/dist/format-on-type.js +96 -0
  53. package/dist/host-types.d.ts +19 -0
  54. package/dist/hover.d.ts +4 -0
  55. package/dist/hover.js +15 -2
  56. package/dist/index.d.ts +19 -5
  57. package/dist/index.js +9 -1
  58. package/dist/inlay-hints.d.ts +47 -2
  59. package/dist/inlay-hints.js +353 -16
  60. package/dist/language-ids.js +4 -2
  61. package/dist/locales/en.json +117 -3
  62. package/dist/locales/nl.json +117 -3
  63. package/dist/models.d.ts +6 -2
  64. package/dist/models.js +5 -1
  65. package/dist/panel-size.d.ts +6 -0
  66. package/dist/panel-size.js +25 -0
  67. package/dist/patch-decorations.d.ts +27 -0
  68. package/dist/patch-decorations.js +182 -0
  69. package/dist/patch-layout.d.ts +40 -0
  70. package/dist/patch-layout.js +304 -0
  71. package/dist/peek.d.ts +3 -1
  72. package/dist/peek.js +6 -1
  73. package/dist/pick.d.ts +1 -0
  74. package/dist/pick.js +11 -1
  75. package/dist/popups.d.ts +17 -0
  76. package/dist/popups.js +1 -0
  77. package/dist/project-language.d.ts +12 -0
  78. package/dist/project-language.js +52 -2
  79. package/dist/refresher.d.ts +1 -0
  80. package/dist/refresher.js +5 -0
  81. package/dist/rename-model.d.ts +1 -1
  82. package/dist/rename-model.js +3 -7
  83. package/dist/rename.js +5 -8
  84. package/dist/rendered-docs.d.ts +64 -0
  85. package/dist/rendered-docs.js +374 -0
  86. package/dist/row-host.d.ts +2 -0
  87. package/dist/row-host.js +11 -3
  88. package/dist/semantic-delta.d.ts +2 -0
  89. package/dist/semantic-delta.js +27 -0
  90. package/dist/semantic-model.js +16 -0
  91. package/dist/semantic-tokens.d.ts +26 -1
  92. package/dist/semantic-tokens.js +174 -14
  93. package/dist/shortcut-keys.d.ts +2 -0
  94. package/dist/shortcut-keys.js +6 -2
  95. package/dist/signature.js +1 -1
  96. package/dist/snippet-field-transforms.d.ts +30 -0
  97. package/dist/snippet-field-transforms.js +116 -0
  98. package/dist/snippet-indent.d.ts +2 -0
  99. package/dist/snippet-indent.js +49 -0
  100. package/dist/snippet-range-order.d.ts +3 -0
  101. package/dist/snippet-range-order.js +19 -0
  102. package/dist/snippet-session.d.ts +42 -6
  103. package/dist/snippet-session.js +650 -53
  104. package/dist/snippet-transform-client.d.ts +19 -0
  105. package/dist/snippet-transform-client.js +66 -0
  106. package/dist/snippet-transform-format.d.ts +15 -0
  107. package/dist/snippet-transform-format.js +302 -0
  108. package/dist/snippet-transform-protocol.d.ts +45 -0
  109. package/dist/snippet-transform-protocol.js +8 -0
  110. package/dist/snippet-transform-queue.d.ts +32 -0
  111. package/dist/snippet-transform-queue.js +173 -0
  112. package/dist/snippet-transform-worker.d.ts +10 -0
  113. package/dist/snippet-transform-worker.js +41 -0
  114. package/dist/snippet-variable-names.d.ts +1 -0
  115. package/dist/snippet-variable-names.js +36 -0
  116. package/dist/snippet-variables.d.ts +7 -0
  117. package/dist/snippet-variables.js +66 -0
  118. package/dist/snippet.d.ts +30 -3
  119. package/dist/snippet.js +402 -87
  120. package/dist/split-alignment.d.ts +6 -0
  121. package/dist/split-alignment.js +38 -0
  122. package/dist/split-scroll.d.ts +14 -0
  123. package/dist/split-scroll.js +45 -0
  124. package/dist/symbols.d.ts +2 -1
  125. package/dist/symbols.js +39 -7
  126. package/dist/testing.d.ts +5 -1
  127. package/dist/testing.js +12 -0
  128. package/dist/timers.d.ts +1 -0
  129. package/dist/timers.js +4 -0
  130. package/dist/use-panel-body.d.ts +6 -0
  131. package/dist/use-panel-body.js +13 -0
  132. package/dist/workspace-edit.d.ts +25 -3
  133. package/dist/workspace-edit.js +282 -143
  134. package/package.json +10 -5
  135. package/src/CallHierarchyPanel.tsx +244 -0
  136. package/src/CompletionPopup.tsx +12 -1
  137. package/src/DiffView.tsx +262 -0
  138. package/src/EditorContextMenu.tsx +1 -0
  139. package/src/EditorView.tsx +21 -2
  140. package/src/FindReplace.tsx +51 -13
  141. package/src/HoverCard.tsx +23 -21
  142. package/src/LanguagePopups.tsx +5 -0
  143. package/src/Markdown.tsx +10 -3
  144. package/src/PanelResizeHandle.tsx +104 -0
  145. package/src/PeekPanel.tsx +11 -6
  146. package/src/PickPopup.tsx +18 -2
  147. package/src/RenameCard.tsx +18 -0
  148. package/src/RenderedDocs.tsx +155 -0
  149. package/src/SplitDiffView.tsx +337 -0
  150. package/src/SymbolPicker.tsx +4 -3
  151. package/src/call-hierarchy-model.ts +151 -0
  152. package/src/call-hierarchy.ts +440 -0
  153. package/src/code-actions-model.ts +17 -11
  154. package/src/code-actions.ts +3 -1
  155. package/src/completion-model.ts +61 -35
  156. package/src/completion.ts +302 -42
  157. package/src/diagnostics.ts +8 -6
  158. package/src/diff-expansion.ts +49 -0
  159. package/src/diff-overlays.tsx +69 -0
  160. package/src/diff-syntax.ts +67 -0
  161. package/src/diff-wordmarks.ts +31 -0
  162. package/src/doc-comment-model.ts +336 -0
  163. package/src/editor-language.ts +22 -6
  164. package/src/editor-react.css +79 -0
  165. package/src/format-on-type.ts +111 -0
  166. package/src/host-types.ts +23 -0
  167. package/src/hover.ts +18 -3
  168. package/src/index.ts +27 -4
  169. package/src/inlay-hints.ts +394 -18
  170. package/src/language-ids.ts +4 -2
  171. package/src/locales/en.json +117 -3
  172. package/src/locales/nl.json +117 -3
  173. package/src/models.ts +40 -1
  174. package/src/panel-size.ts +28 -0
  175. package/src/patch-decorations.ts +224 -0
  176. package/src/patch-layout.ts +388 -0
  177. package/src/peek.ts +6 -1
  178. package/src/pick.ts +12 -1
  179. package/src/popups.ts +24 -0
  180. package/src/project-language.ts +63 -2
  181. package/src/refresher.ts +6 -0
  182. package/src/rename-model.ts +4 -8
  183. package/src/rename.ts +5 -8
  184. package/src/rendered-docs.ts +430 -0
  185. package/src/row-host.ts +12 -3
  186. package/src/semantic-delta.ts +29 -0
  187. package/src/semantic-model.ts +17 -0
  188. package/src/semantic-tokens.ts +202 -19
  189. package/src/shortcut-keys.ts +6 -2
  190. package/src/signature.ts +1 -1
  191. package/src/snippet-field-transforms.ts +144 -0
  192. package/src/snippet-indent.ts +53 -0
  193. package/src/snippet-range-order.ts +19 -0
  194. package/src/snippet-session.ts +797 -56
  195. package/src/snippet-transform-client.ts +84 -0
  196. package/src/snippet-transform-format.ts +325 -0
  197. package/src/snippet-transform-protocol.ts +24 -0
  198. package/src/snippet-transform-queue.ts +199 -0
  199. package/src/snippet-transform-worker.ts +58 -0
  200. package/src/snippet-variable-names.ts +36 -0
  201. package/src/snippet-variables.ts +74 -0
  202. package/src/snippet.ts +452 -89
  203. package/src/split-alignment.ts +45 -0
  204. package/src/split-scroll.ts +54 -0
  205. package/src/symbols.ts +43 -7
  206. package/src/testing.ts +25 -0
  207. package/src/timers.ts +5 -0
  208. package/src/use-panel-body.ts +17 -0
  209. package/src/workspace-edit.ts +347 -169
@@ -0,0 +1,54 @@
1
+ import type { Editor } from '@adecore/editor';
2
+ import type { DiffSourceSide } from './diff-syntax.ts';
3
+
4
+ type ScrollEditor = Pick<Editor, 'getScrollTop' | 'setScrollTop'>;
5
+
6
+ export class SplitScroll {
7
+ private leader: DiffSourceSide = 'new';
8
+ private syncing = false;
9
+ private readonly expected: Record<DiffSourceSide, number>;
10
+
11
+ private readonly editors: Record<DiffSourceSide, ScrollEditor>;
12
+
13
+ constructor(editors: Record<DiffSourceSide, ScrollEditor>) {
14
+ this.editors = editors;
15
+ this.expected = { old: editors.old.getScrollTop(), new: editors.new.getScrollTop() };
16
+ }
17
+
18
+ drive(side: DiffSourceSide): void {
19
+ this.leader = side;
20
+ }
21
+
22
+ changed(side: DiffSourceSide): void {
23
+ if (this.syncing) {
24
+ return;
25
+ }
26
+ const top = this.editors[side].getScrollTop();
27
+ if (side !== this.leader) {
28
+ // Native scroll echoes arrive after setScrollTop returns, including a clamped follower position.
29
+ if (Math.abs(top - this.expected[side]) < 1) {
30
+ return;
31
+ }
32
+ this.leader = side;
33
+ }
34
+ this.sync();
35
+ }
36
+
37
+ sync(): void {
38
+ const side = this.leader;
39
+ const other = side === 'old' ? 'new' : 'old';
40
+ const top = this.editors[side].getScrollTop();
41
+ this.expected[side] = top;
42
+ if (Math.abs(this.editors[other].getScrollTop() - top) < 1) {
43
+ this.expected[other] = this.editors[other].getScrollTop();
44
+ return;
45
+ }
46
+ this.syncing = true;
47
+ try {
48
+ this.editors[other].setScrollTop(top);
49
+ } finally {
50
+ this.expected[other] = this.editors[other].getScrollTop();
51
+ this.syncing = false;
52
+ }
53
+ }
54
+ }
package/src/symbols.ts CHANGED
@@ -27,11 +27,13 @@ export interface SymbolSpan {
27
27
  readonly name: string;
28
28
  readonly kind: number;
29
29
  readonly range: Range;
30
+ /* The line of the name, when the server says where the name is. */
31
+ readonly nameLine?: number;
30
32
  }
31
33
 
32
34
  function walk(symbols: readonly DocumentSymbol[], spans: SymbolSpan[]): void {
33
35
  for (const symbol of symbols) {
34
- spans.push({ name: symbol.name, kind: symbol.kind, range: symbol.range });
36
+ spans.push({ name: symbol.name, kind: symbol.kind, range: symbol.range, nameLine: symbol.selectionRange?.start.line });
35
37
  walk(symbol.children ?? [], spans);
36
38
  }
37
39
  }
@@ -49,17 +51,51 @@ export function symbolSpansOf(result: DocumentSymbolResult): SymbolSpan[] {
49
51
  return (result as SymbolInformation[]).map((symbol) => ({ name: symbol.name, kind: symbol.kind, range: symbol.location.range }));
50
52
  }
51
53
 
52
- function blockOf({ name, kind, range }: SymbolSpan): EditorBlock | null {
54
+ /* 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. */
55
+ const PRELUDE = /^\s*(?:$|\/\/|\/\*|\*|#\[)/;
56
+
57
+ /*
58
+ * The line a block is pinned by. A range may begin at the doc comment or the attributes of a declaration, so the
59
+ * line of the name wins, and without it the first line below the comment that holds the name.
60
+ */
61
+ function headerLineOf({ name, range, nameLine }: SymbolSpan, lines: readonly string[] | undefined): number {
62
+ const { start, end } = range;
63
+ if (nameLine !== undefined && nameLine >= start.line && nameLine <= end.line) {
64
+ return nameLine;
65
+ }
66
+ if (lines === undefined) {
67
+ return start.line;
68
+ }
69
+ const last = Math.min(end.line, lines.length - 1);
70
+ let first = start.line;
71
+ while (first < last && PRELUDE.test(lines[first] ?? '')) {
72
+ first++;
73
+ }
74
+ const short = name.slice(name.lastIndexOf('\\') + 1);
75
+ for (let line = first; line <= last; line++) {
76
+ if (!PRELUDE.test(lines[line] ?? '') && (lines[line] ?? '').includes(short)) {
77
+ return line;
78
+ }
79
+ }
80
+ return first;
81
+ }
82
+
83
+ function blockOf(span: SymbolSpan, lines: readonly string[] | undefined): EditorBlock | null {
84
+ const { name, kind, range } = span;
53
85
  const label = KINDS[kind];
54
86
  // A one-line symbol has no body to pin, and a property or an enum member is part of the block around it.
55
87
  return label === undefined || range.end.line <= range.start.line
56
88
  ? null
57
- : { startLine: range.start.line + 1, endLine: range.end.line + 1, name, kind: label };
89
+ : { startLine: headerLineOf(span, lines) + 1, endLine: range.end.line + 1, name, kind: label };
58
90
  }
59
91
 
60
- /* The multi-line symbols of a file as blocks, outermost first, in one-based lines. */
61
- export function blocksOf(result: DocumentSymbolResult): EditorBlock[] {
62
- const blocks = symbolSpansOf(result).flatMap((span) => blockOf(span) ?? []);
92
+ /*
93
+ * The multi-line symbols of a file as blocks, outermost first, in one-based lines. The text of the document
94
+ * lets a block start at its declaration rather than at the comment a server counts into the symbol.
95
+ */
96
+ export function blocksOf(result: DocumentSymbolResult, text?: string): EditorBlock[] {
97
+ const lines = text?.split('\n');
98
+ const blocks = symbolSpansOf(result).flatMap((span) => blockOf(span, lines) ?? []);
63
99
  return blocks.sort((left, right) => left.startLine - right.startLine || right.endLine - left.endLine);
64
100
  }
65
101
 
@@ -80,7 +116,7 @@ export class SymbolsFeature {
80
116
  }
81
117
  const result = await project.service.documentSymbols(uri, { signal });
82
118
  if (!signal.aborted) {
83
- editor.setBlocks(result === null ? null : blocksOf(result));
119
+ editor.setBlocks(result === null ? null : blocksOf(result, editor.getText()));
84
120
  for (const listener of [...this.listeners]) {
85
121
  listener(result);
86
122
  }
package/src/testing.ts CHANGED
@@ -10,6 +10,9 @@ import {
10
10
  type ContentChange,
11
11
  type Disposable,
12
12
  type ProviderOptions,
13
+ type CallHierarchyIncomingCall,
14
+ type CallHierarchyItem,
15
+ type CallHierarchyOutgoingCall,
13
16
  type CodeAction,
14
17
  type CodeActionContext,
15
18
  type CodeLens,
@@ -200,6 +203,16 @@ export class FakeLanguageService implements LanguageService {
200
203
  return this.request<TextEdit[] | null>('textDocument/rangeFormatting', uri, { range, options: formatting }, options);
201
204
  }
202
205
 
206
+ onTypeFormatting(
207
+ uri: string,
208
+ position: Position,
209
+ ch: string,
210
+ formatting: FormattingOptions,
211
+ options: LanguageRequestOptions = {}
212
+ ): Promise<TextEdit[] | null> {
213
+ return this.request<TextEdit[] | null>('textDocument/onTypeFormatting', uri, { position, ch, options: formatting }, options);
214
+ }
215
+
203
216
  semanticTokens(uri: string, options: LanguageRequestOptions = {}): Promise<SemanticTokens | null> {
204
217
  return this.request<SemanticTokens | null>('textDocument/semanticTokens/full', uri, {}, options);
205
218
  }
@@ -232,6 +245,18 @@ export class FakeLanguageService implements LanguageService {
232
245
  return this.request<SelectionRange[] | null>('textDocument/selectionRange', uri, { positions }, options);
233
246
  }
234
247
 
248
+ prepareCallHierarchy(uri: string, position: Position, options: LanguageRequestOptions = {}): Promise<CallHierarchyItem[] | null> {
249
+ return this.request<CallHierarchyItem[] | null>('textDocument/prepareCallHierarchy', uri, { position }, options);
250
+ }
251
+
252
+ incomingCalls(uri: string, item: CallHierarchyItem, options: LanguageRequestOptions = {}): Promise<CallHierarchyIncomingCall[] | null> {
253
+ return this.request<CallHierarchyIncomingCall[] | null>('callHierarchy/incomingCalls', uri, { item }, options);
254
+ }
255
+
256
+ outgoingCalls(uri: string, item: CallHierarchyItem, options: LanguageRequestOptions = {}): Promise<CallHierarchyOutgoingCall[] | null> {
257
+ return this.request<CallHierarchyOutgoingCall[] | null>('callHierarchy/outgoingCalls', uri, { item }, options);
258
+ }
259
+
235
260
  codeLenses(uri: string, options: LanguageRequestOptions = {}): Promise<CodeLens[] | null> {
236
261
  return this.request<CodeLens[] | null>('textDocument/codeLens', uri, {}, options);
237
262
  }
package/src/timers.ts CHANGED
@@ -43,3 +43,8 @@ export class ManualTimers implements Timers {
43
43
  return this.pending.size;
44
44
  }
45
45
  }
46
+
47
+ /* Scrolls a row the editor opened under the caret line into view, which may sit at the bottom of the view with the row below the fold. The element is in the page a turn later. */
48
+ export function revealRow(timers: Timers, container: HTMLElement): void {
49
+ timers.set(() => container.scrollIntoView?.({ block: 'nearest' }), 0);
50
+ }
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from 'react';
2
+ import type { EditorLanguage } from './editor-language.ts';
3
+ import { clampPanelBody } from './panel-size.ts';
4
+
5
+ /* The body height of a panel, from the project that remembers it for the next one; `commit` hands it to the host. */
6
+ export function usePanelBody(language: EditorLanguage): { height: number; set(height: number): void; commit(height: number): void } {
7
+ const { project } = language;
8
+ const [height, set] = useState(() => clampPanelBody(project.panelBodyHeight));
9
+
10
+ useEffect(() => project.onPanelBodyChange((value) => set(clampPanelBody(value))), [project]);
11
+
12
+ return {
13
+ height,
14
+ set,
15
+ commit: (value) => project.resizePanelBody(value)
16
+ };
17
+ }