@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
@@ -8,109 +8,130 @@ import { comparePositions, markerOf, neighborProblem, problemCountsOf, problemsA
8
8
  * before the server reports again, so what is under a squiggle is still what it was about.
9
9
  */
10
10
  export class DiagnosticsFeature {
11
- language;
12
- reports = new Map();
13
- listeners = new Set();
14
- list = [];
15
- constructor(language) {
16
- this.language = language;
17
- const { editor, project, uri } = language;
18
- const reports = project.service.onDiagnostics((report) => {
19
- if (report.uri === uri) {
20
- this.reports.set(report.source, report.diagnostics);
21
- this.rebuild();
22
- }
23
- });
24
- const edits = editor.onTextChange((change) => this.shift(change.changes));
25
- // These keys are the editor's while it has the keyboard; elsewhere the menu's commands answer.
26
- const keys = language.onKey((event) => {
27
- const next = isShortcut(this.language.shortcuts.nextProblem, event);
28
- if (!next && !isShortcut(this.language.shortcuts.previousProblem, event)) {
29
- return false;
30
- }
31
- this.step(next ? 1 : -1);
32
- return true;
33
- }, KEY_PRIORITY.diagnostics);
34
- language.onDispose(() => {
35
- keys();
36
- reports.dispose();
37
- edits();
38
- this.listeners.clear();
39
- editor.setMarkers([]);
40
- });
11
+ language;
12
+ reports = new Map();
13
+ listeners = new Set();
14
+ list = [];
15
+ constructor(language) {
16
+ this.language = language;
17
+ const {
18
+ editor,
19
+ project,
20
+ uri
21
+ } = language;
22
+ const reports = project.service.onDiagnostics(report => {
23
+ if (report.uri === uri) {
24
+ this.reports.set(report.source, report.diagnostics);
25
+ this.rebuild();
26
+ }
27
+ });
28
+ const edits = editor.onTextChange(change => this.shift(change.changes));
29
+ // These keys are the editor's while it has the keyboard; elsewhere the menu's commands answer.
30
+ const keys = language.onKey(event => {
31
+ const next = isShortcut(this.language.shortcuts.nextProblem, event);
32
+ if (!next && !isShortcut(this.language.shortcuts.previousProblem, event)) {
33
+ return false;
34
+ }
35
+ this.step(next ? 1 : -1);
36
+ return true;
37
+ }, KEY_PRIORITY.diagnostics);
38
+ language.onDispose(() => {
39
+ keys();
40
+ reports.dispose();
41
+ edits();
42
+ this.listeners.clear();
43
+ editor.setMarkers([]);
44
+ });
45
+ }
46
+ get problems() {
47
+ return this.list;
48
+ }
49
+ counts() {
50
+ return problemCountsOf(this.list.map(problem => problem.diagnostic));
51
+ }
52
+ at(position) {
53
+ return problemsAt(this.list, position);
54
+ }
55
+ /* Puts the caret on the next problem, or the one before; false when there is none. */
56
+ step(direction) {
57
+ const caret = this.language.editor.getCaret();
58
+ const target = neighborProblem(this.list, caret, direction);
59
+ if (target === null) {
60
+ return false;
41
61
  }
42
- get problems() {
43
- return this.list;
62
+ const {
63
+ start
64
+ } = target.diagnostic.range;
65
+ this.reveal(target, comparePositions(start, caret) > 0 ? 'centerDown' : 'centerUp');
66
+ return true;
67
+ }
68
+ /* Puts the caret on the first problem of the file. */
69
+ goToFirst() {
70
+ const target = neighborProblem(this.list, {
71
+ line: -1,
72
+ character: 0
73
+ }, 1);
74
+ if (target === null) {
75
+ return false;
44
76
  }
45
- counts() {
46
- return problemCountsOf(this.list.map((problem) => problem.diagnostic));
47
- }
48
- at(position) {
49
- return problemsAt(this.list, position);
50
- }
51
- /* Puts the caret on the next problem, or the one before; false when there is none. */
52
- step(direction) {
53
- const caret = this.language.editor.getCaret();
54
- const target = neighborProblem(this.list, caret, direction);
55
- if (target === null) {
56
- return false;
57
- }
58
- const { start } = target.diagnostic.range;
59
- this.reveal(target, comparePositions(start, caret) > 0 ? 'centerDown' : 'centerUp');
60
- return true;
61
- }
62
- /* Puts the caret on the first problem of the file. */
63
- goToFirst() {
64
- const target = neighborProblem(this.list, { line: -1, character: 0 }, 1);
65
- if (target === null) {
66
- return false;
67
- }
68
- this.reveal(target, 'center');
69
- return true;
70
- }
71
- onChange(listener) {
72
- this.listeners.add(listener);
73
- return () => {
74
- this.listeners.delete(listener);
75
- };
76
- }
77
- reveal(problem, reveal) {
78
- const { editor, project } = this.language;
79
- editor.setCaret(problem.diagnostic.range.start, reveal);
80
- editor.focus();
81
- this.language.hover.showProblemsAt(editor.getCaret());
82
- const severity = project.i18n.t(`editor:language.announce.severity.${severityOf(problem.diagnostic)}`);
83
- editor.announce(project.i18n.t('editor:language.announce.problem', { severity, message: problem.diagnostic.message }));
84
- }
85
- /* The problems follow the edit as the markers do. Their number does not change, so nobody is told. */
86
- shift(changes) {
87
- let moved = false;
88
- for (const [server, diagnostics] of this.reports) {
89
- let shifted = null;
90
- for (const [index, diagnostic] of diagnostics.entries()) {
91
- const range = shiftRange(diagnostic.range, changes);
92
- if (!sameRange(range, diagnostic.range)) {
93
- shifted ??= [...diagnostics];
94
- shifted[index] = { ...diagnostic, range };
95
- }
96
- }
97
- if (shifted !== null) {
98
- this.reports.set(server, shifted);
99
- moved = true;
100
- }
101
- }
102
- if (moved) {
103
- this.collect();
77
+ this.reveal(target, 'center');
78
+ return true;
79
+ }
80
+ onChange(listener) {
81
+ this.listeners.add(listener);
82
+ return () => {
83
+ this.listeners.delete(listener);
84
+ };
85
+ }
86
+ reveal(problem, reveal) {
87
+ const {
88
+ editor,
89
+ project
90
+ } = this.language;
91
+ editor.setCaret(problem.diagnostic.range.start, reveal);
92
+ editor.focus();
93
+ this.language.hover.showProblemsAt(editor.getCaret());
94
+ const severity = project.i18n.t(`editor:language.announce.severity.${severityOf(problem.diagnostic)}`);
95
+ editor.announce(project.i18n.t('editor:language.announce.problem', {
96
+ severity,
97
+ message: problem.diagnostic.message
98
+ }));
99
+ }
100
+ /* The problems follow the edit as the markers do. Their number does not change, so nobody is told. */
101
+ shift(changes) {
102
+ let moved = false;
103
+ for (const [server, diagnostics] of this.reports) {
104
+ let shifted = null;
105
+ for (const [index, diagnostic] of diagnostics.entries()) {
106
+ const range = shiftRange(diagnostic.range, changes);
107
+ if (!sameRange(range, diagnostic.range)) {
108
+ shifted ??= [...diagnostics];
109
+ shifted[index] = {
110
+ ...diagnostic,
111
+ range
112
+ };
104
113
  }
114
+ }
115
+ if (shifted !== null) {
116
+ this.reports.set(server, shifted);
117
+ moved = true;
118
+ }
105
119
  }
106
- rebuild() {
107
- this.collect();
108
- this.language.editor.setMarkers(this.list.map((problem) => markerOf(problem.diagnostic)));
109
- for (const listener of [...this.listeners]) {
110
- listener();
111
- }
120
+ if (moved) {
121
+ this.collect();
112
122
  }
113
- collect() {
114
- this.list = [...this.reports].flatMap(([server, diagnostics]) => diagnostics.map((diagnostic) => ({ diagnostic, server })));
123
+ }
124
+ rebuild() {
125
+ this.collect();
126
+ this.language.editor.setMarkers(this.list.map(problem => markerOf(problem.diagnostic)));
127
+ for (const listener of [...this.listeners]) {
128
+ listener();
115
129
  }
116
- }
130
+ }
131
+ collect() {
132
+ this.list = [...this.reports].flatMap(([server, diagnostics]) => diagnostics.map(diagnostic => ({
133
+ diagnostic,
134
+ server
135
+ })));
136
+ }
137
+ }
@@ -1,41 +1,44 @@
1
1
  import { diffRows } from '@adecore/merge';
2
- export const DEFAULT_UNFOLD_LIMITS = { rows: 20000, characters: 2000000, lineLength: 10000 };
2
+ export const DEFAULT_UNFOLD_LIMITS = {
3
+ rows: 20000,
4
+ characters: 2000000,
5
+ lineLength: 10000
6
+ };
3
7
  export function fitsDiff(document, unfolded, limits, maxRows = limits.rows) {
4
- let rows = 0;
5
- let characters = 0;
6
- for (const row of diffRows(document, 'unified', unfolded)) {
7
- if (row.kind === 'gap') {
8
- continue;
9
- }
10
- const text = row.new === undefined ? document.sides.old[row.old.index] : document.sides.new[row.new.index];
11
- characters += text.length + (rows > 0 ? 1 : 0);
12
- if (++rows > maxRows || characters > limits.characters || text.length > limits.lineLength) {
13
- return false;
14
- }
8
+ let rows = 0;
9
+ let characters = 0;
10
+ for (const row of diffRows(document, 'unified', unfolded)) {
11
+ if (row.kind === 'gap') {
12
+ continue;
15
13
  }
16
- return true;
14
+ const text = row.new === undefined ? document.sides.old[row.old.index] : document.sides.new[row.new.index];
15
+ characters += text.length + (rows > 0 ? 1 : 0);
16
+ if (++rows > maxRows || characters > limits.characters || text.length > limits.lineLength) {
17
+ return false;
18
+ }
19
+ }
20
+ return true;
17
21
  }
18
22
  export function expandDiff(document, unfolded, id, limits) {
19
- const rows = diffRows(document, 'unified', unfolded);
20
- const gap = rows.find((row) => row.kind === 'gap' && row.id === id);
21
- if (gap?.kind !== 'gap' || !gap.unfoldable) {
22
- return unfolded;
23
- }
24
- const visible = rows.filter((row) => row.kind === 'line').length;
25
- const maxRows = Math.min(limits.rows, visible + 500);
26
- const previous = unfolded.get(id) ?? 0;
27
- let low = 0;
28
- let high = Math.min(500, gap.oldCount);
29
- // Between-hunk gaps reveal from both ends; search the per-end count within the shared row budget.
30
- while (low < high) {
31
- const count = Math.ceil((low + high) / 2);
32
- const candidate = new Map(unfolded).set(id, previous + count);
33
- if (fitsDiff(document, candidate, limits, maxRows)) {
34
- low = count;
35
- }
36
- else {
37
- high = count - 1;
38
- }
23
+ const rows = diffRows(document, 'unified', unfolded);
24
+ const gap = rows.find(row => row.kind === 'gap' && row.id === id);
25
+ if (gap?.kind !== 'gap' || !gap.unfoldable) {
26
+ return unfolded;
27
+ }
28
+ const visible = rows.filter(row => row.kind === 'line').length;
29
+ const maxRows = Math.min(limits.rows, visible + 500);
30
+ const previous = unfolded.get(id) ?? 0;
31
+ let low = 0;
32
+ let high = Math.min(500, gap.oldCount);
33
+ // Between-hunk gaps reveal from both ends; search the per-end count within the shared row budget.
34
+ while (low < high) {
35
+ const count = Math.ceil((low + high) / 2);
36
+ const candidate = new Map(unfolded).set(id, previous + count);
37
+ if (fitsDiff(document, candidate, limits, maxRows)) {
38
+ low = count;
39
+ } else {
40
+ high = count - 1;
39
41
  }
40
- return low === 0 ? unfolded : new Map(unfolded).set(id, previous + low);
41
- }
42
+ }
43
+ return low === 0 ? unfolded : new Map(unfolded).set(id, previous + low);
44
+ }
@@ -1,28 +1,150 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { c as _c } from "react/compiler-runtime";
2
2
  import { useSyncExternalStore } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Button, Tooltip } from '@adecore/ui';
6
6
  import { formatNumber } from '@adecore/ui/format';
7
7
  import { RowHost, LineActionHost } from './row-host.js';
8
- export function DiffOverlays({ mounted, display, unfold, blocked }) {
9
- const { t } = useTranslation('editor');
10
- useSyncExternalStore(mounted.rows.subscribe, mounted.rows.getVersion, mounted.rows.getVersion);
11
- useSyncExternalStore(mounted.actions.subscribe, mounted.actions.getVersion, mounted.actions.getVersion);
12
- return (_jsxs(_Fragment, { children: [display.gaps.map(({ row }) => {
13
- const container = mounted.rows.container(`gap-${row.id}`);
14
- if (container === undefined) {
15
- return null;
16
- }
17
- const text = t('diff.hidden', { count: formatNumber(Math.max(row.oldCount, row.newCount)) });
18
- return createPortal(_jsx("div", { className: "adecore-editor-diff-gap", children: row.unfoldable && blocked?.has(row.id) === true ? (_jsx(Tooltip, { label: t('diff.contextLimit'), children: _jsx("span", { className: "inline-flex", children: _jsx(Button, { size: "xs", disabled: true, children: text }) }) })) : row.unfoldable ? (_jsx(Button, { size: "xs", onClick: () => unfold(row.id), children: text })) : (_jsx("span", { children: text })) }), container, `gap-${row.id}`);
19
- }), display.rows.map((row, index) => {
20
- if (row.noNewline === undefined) {
21
- return null;
22
- }
23
- const container = mounted.actions.container(`no-newline-${index}`);
24
- return container === undefined
25
- ? null
26
- : createPortal(_jsx("span", { className: "adecore-editor-diff-no-newline", children: t('diff.noNewline') }), container, `no-newline-${index}`);
27
- })] }));
28
- }
8
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
9
+ export function DiffOverlays(t0) {
10
+ const $ = _c(29);
11
+ const {
12
+ mounted,
13
+ display,
14
+ unfold,
15
+ blocked
16
+ } = t0;
17
+ const {
18
+ t
19
+ } = useTranslation("editor");
20
+ let t1;
21
+ if ($[0] !== mounted.rows) {
22
+ t1 = () => mounted.rows.getContainers();
23
+ $[0] = mounted.rows;
24
+ $[1] = t1;
25
+ } else {
26
+ t1 = $[1];
27
+ }
28
+ const getRows = t1;
29
+ let t2;
30
+ if ($[2] !== mounted.actions) {
31
+ t2 = () => mounted.actions.getContainers();
32
+ $[2] = mounted.actions;
33
+ $[3] = t2;
34
+ } else {
35
+ t2 = $[3];
36
+ }
37
+ const getActions = t2;
38
+ let t3;
39
+ if ($[4] !== mounted.rows) {
40
+ t3 = listener => mounted.rows.subscribe(listener);
41
+ $[4] = mounted.rows;
42
+ $[5] = t3;
43
+ } else {
44
+ t3 = $[5];
45
+ }
46
+ const rows = useSyncExternalStore(t3, getRows, getRows);
47
+ let t4;
48
+ if ($[6] !== mounted.actions) {
49
+ t4 = listener_0 => mounted.actions.subscribe(listener_0);
50
+ $[6] = mounted.actions;
51
+ $[7] = t4;
52
+ } else {
53
+ t4 = $[7];
54
+ }
55
+ const actions = useSyncExternalStore(t4, getActions, getActions);
56
+ let t5;
57
+ if ($[8] !== blocked || $[9] !== display.gaps || $[10] !== rows || $[11] !== t || $[12] !== unfold) {
58
+ let t6;
59
+ if ($[14] !== blocked || $[15] !== rows || $[16] !== t || $[17] !== unfold) {
60
+ t6 = t7 => {
61
+ const {
62
+ row
63
+ } = t7;
64
+ const container = rows.get(`gap-${row.id}`);
65
+ if (container === undefined) {
66
+ return null;
67
+ }
68
+ const text = t("diff.hidden", {
69
+ count: formatNumber(Math.max(row.oldCount, row.newCount))
70
+ });
71
+ return createPortal(/*#__PURE__*/_jsx("div", {
72
+ className: "adecore-editor-diff-gap",
73
+ children: row.unfoldable && blocked?.has(row.id) === true ? /*#__PURE__*/_jsx(Tooltip, {
74
+ label: t("diff.contextLimit"),
75
+ children: /*#__PURE__*/_jsx("span", {
76
+ className: "inline-flex",
77
+ children: /*#__PURE__*/_jsx(Button, {
78
+ size: "xs",
79
+ disabled: true,
80
+ children: text
81
+ })
82
+ })
83
+ }) : row.unfoldable ? /*#__PURE__*/_jsx(Button, {
84
+ size: "xs",
85
+ onClick: () => unfold(row.id),
86
+ children: text
87
+ }) : /*#__PURE__*/_jsx("span", {
88
+ children: text
89
+ })
90
+ }), container, `gap-${row.id}`);
91
+ };
92
+ $[14] = blocked;
93
+ $[15] = rows;
94
+ $[16] = t;
95
+ $[17] = unfold;
96
+ $[18] = t6;
97
+ } else {
98
+ t6 = $[18];
99
+ }
100
+ t5 = display.gaps.map(t6);
101
+ $[8] = blocked;
102
+ $[9] = display.gaps;
103
+ $[10] = rows;
104
+ $[11] = t;
105
+ $[12] = unfold;
106
+ $[13] = t5;
107
+ } else {
108
+ t5 = $[13];
109
+ }
110
+ let t6;
111
+ if ($[19] !== actions || $[20] !== display.rows || $[21] !== t) {
112
+ let t7;
113
+ if ($[23] !== actions || $[24] !== t) {
114
+ t7 = (row_0, index) => {
115
+ if (row_0.noNewline === undefined) {
116
+ return null;
117
+ }
118
+ const container_0 = actions.get(`no-newline-${index}`);
119
+ return container_0 === undefined ? null : createPortal(/*#__PURE__*/_jsx("span", {
120
+ className: "adecore-editor-diff-no-newline",
121
+ children: t("diff.noNewline")
122
+ }), container_0, `no-newline-${index}`);
123
+ };
124
+ $[23] = actions;
125
+ $[24] = t;
126
+ $[25] = t7;
127
+ } else {
128
+ t7 = $[25];
129
+ }
130
+ t6 = display.rows.map(t7);
131
+ $[19] = actions;
132
+ $[20] = display.rows;
133
+ $[21] = t;
134
+ $[22] = t6;
135
+ } else {
136
+ t6 = $[22];
137
+ }
138
+ let t7;
139
+ if ($[26] !== t5 || $[27] !== t6) {
140
+ t7 = /*#__PURE__*/_jsxs(_Fragment, {
141
+ children: [t5, t6]
142
+ });
143
+ $[26] = t5;
144
+ $[27] = t6;
145
+ $[28] = t7;
146
+ } else {
147
+ t7 = $[28];
148
+ }
149
+ return t7;
150
+ }
@@ -1,49 +1,72 @@
1
1
  function canTokenize(source) {
2
- if (source.length > 20000) {
3
- return false;
2
+ if (source.length > 20000) {
3
+ return false;
4
+ }
5
+ let characters = Math.max(0, source.length - 1);
6
+ for (const line of source) {
7
+ characters += line.length;
8
+ if (line.length > 10000 || characters > 2000000) {
9
+ return false;
4
10
  }
5
- let characters = Math.max(0, source.length - 1);
6
- for (const line of source) {
7
- characters += line.length;
8
- if (line.length > 10000 || characters > 2000000) {
9
- return false;
10
- }
11
- }
12
- return true;
11
+ }
12
+ return true;
13
13
  }
14
14
  export function diffSyntaxDocument(document, language, theme) {
15
- const locations = { old: [], new: [] };
16
- const build = (side) => {
17
- const source = document.sides[side];
18
- // Skipping a long hidden line loses grammar state; keep the entire side plain instead.
19
- if (!canTokenize(source)) {
20
- return { language, theme, blocks: [], resets: [] };
21
- }
22
- const blocks = [];
23
- const resets = [];
24
- const ranges = document.snapshots
25
- ? [{ from: 0, to: source.length }]
26
- : document.offsets.map((offset, index) => ({ from: offset[side], to: document.offsets[index + 1]?.[side] ?? source.length }));
27
- for (const range of ranges) {
28
- if (!document.snapshots && range.from < range.to) {
29
- resets.push(blocks.length);
30
- }
31
- for (let from = range.from; from < range.to; from += 200) {
32
- const to = Math.min(from + 200, range.to);
33
- const block = blocks.length;
34
- blocks.push(source.slice(from, to).join('\n'));
35
- for (let index = from; index < to; index++) {
36
- locations[side][index] = { block, line: index - from };
37
- }
38
- }
15
+ const locations = {
16
+ old: [],
17
+ new: []
18
+ };
19
+ const build = side => {
20
+ const source = document.sides[side];
21
+ // Skipping a long hidden line loses grammar state; keep the entire side plain instead.
22
+ if (!canTokenize(source)) {
23
+ return {
24
+ language,
25
+ theme,
26
+ blocks: [],
27
+ resets: []
28
+ };
29
+ }
30
+ const blocks = [];
31
+ const resets = [];
32
+ const ranges = document.snapshots ? [{
33
+ from: 0,
34
+ to: source.length
35
+ }] : document.offsets.map((offset, index) => ({
36
+ from: offset[side],
37
+ to: document.offsets[index + 1]?.[side] ?? source.length
38
+ }));
39
+ for (const range of ranges) {
40
+ if (!document.snapshots && range.from < range.to) {
41
+ resets.push(blocks.length);
42
+ }
43
+ for (let from = range.from; from < range.to; from += 200) {
44
+ const to = Math.min(from + 200, range.to);
45
+ const block = blocks.length;
46
+ blocks.push(source.slice(from, to).join('\n'));
47
+ for (let index = from; index < to; index++) {
48
+ locations[side][index] = {
49
+ block,
50
+ line: index - from
51
+ };
39
52
  }
40
- return { language, theme, blocks, resets };
41
- };
42
- const documents = { old: build('old'), new: build('new') };
53
+ }
54
+ }
43
55
  return {
44
- documents,
45
- locate(side, index) {
46
- return Number.isInteger(index) && index >= 0 ? locations[side][index] : undefined;
47
- }
56
+ language,
57
+ theme,
58
+ blocks,
59
+ resets
48
60
  };
49
- }
61
+ };
62
+ const documents = {
63
+ old: build('old'),
64
+ new: build('new')
65
+ };
66
+ return {
67
+ documents,
68
+ locate(side, index) {
69
+ return Number.isInteger(index) && index >= 0 ? locations[side][index] : undefined;
70
+ }
71
+ };
72
+ }
@@ -1,26 +1,29 @@
1
1
  import { diffRows, wordChanges } from '@adecore/merge';
2
2
  export function wordMarks(document) {
3
- const marks = { old: new Map(), new: new Map() };
4
- let pairs = 0;
5
- let characters = 0;
6
- for (const row of diffRows(document, 'split')) {
7
- if (row.kind !== 'line' || row.change !== 'pair' || document.hunks[row.hunk].coarse) {
8
- continue;
9
- }
10
- const old = document.sides.old[row.old.index];
11
- const fresh = document.sides.new[row.new.index];
12
- characters += old.length + fresh.length;
13
- // Per-pair limits alone still allow thousands of expensive word diffs during one mount.
14
- if (++pairs > 1000 || characters > 100000) {
15
- break;
16
- }
17
- const words = wordChanges(old, fresh);
18
- if (words === null) {
19
- continue;
20
- }
21
- const ranges = (text, ranges) => ranges.filter((range) => !document.ignoreWhitespace || /\S/.test(text.slice(range.from, range.to))).map((range) => [range.from, range.to]);
22
- marks.old.set(row.old.index, ranges(old, words.old));
23
- marks.new.set(row.new.index, ranges(fresh, words.new));
3
+ const marks = {
4
+ old: new Map(),
5
+ new: new Map()
6
+ };
7
+ let pairs = 0;
8
+ let characters = 0;
9
+ for (const row of diffRows(document, 'split')) {
10
+ if (row.kind !== 'line' || row.change !== 'pair' || document.hunks[row.hunk].coarse) {
11
+ continue;
24
12
  }
25
- return marks;
26
- }
13
+ const old = document.sides.old[row.old.index];
14
+ const fresh = document.sides.new[row.new.index];
15
+ characters += old.length + fresh.length;
16
+ // Per-pair limits alone still allow thousands of expensive word diffs during one mount.
17
+ if (++pairs > 1000 || characters > 100000) {
18
+ break;
19
+ }
20
+ const words = wordChanges(old, fresh);
21
+ if (words === null) {
22
+ continue;
23
+ }
24
+ const ranges = (text, ranges) => ranges.filter(range => !document.ignoreWhitespace || /\S/.test(text.slice(range.from, range.to))).map(range => [range.from, range.to]);
25
+ marks.old.set(row.old.index, ranges(old, words.old));
26
+ marks.new.set(row.new.index, ranges(fresh, words.new));
27
+ }
28
+ return marks;
29
+ }