@adecore/editor-react 0.31.12 → 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.
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
@@ -4,33 +4,39 @@ import { splitBlocks, splitLines } from '@adecore/merge';
4
4
  * are ours to take without asking; only a stretch both sides changed needs a person.
5
5
  */
6
6
  export function planConflict(base, ours, theirs) {
7
- const blocks = splitBlocks(splitLines(base), splitLines(ours), splitLines(theirs));
8
- const merges = [];
9
- const conflicts = [];
10
- let oursAt = 0;
11
- let theirsAt = 0;
12
- let mergedAt = 0;
13
- for (const block of blocks) {
14
- if (block.kind === 'theirs') {
15
- merges.push({ from: oursAt, to: oursAt + block.ours.length, lines: block.theirs });
16
- mergedAt += block.theirs.length;
17
- }
18
- else {
19
- if (block.kind === 'conflict') {
20
- conflicts.push({
21
- base: block.base,
22
- ours: block.ours,
23
- theirs: block.theirs,
24
- from: mergedAt,
25
- to: mergedAt + block.ours.length,
26
- theirsStart: theirsAt + 1,
27
- theirsEnd: theirsAt + block.theirs.length
28
- });
29
- }
30
- mergedAt += block.ours.length;
31
- }
32
- oursAt += block.ours.length;
33
- theirsAt += block.theirs.length;
7
+ const blocks = splitBlocks(splitLines(base), splitLines(ours), splitLines(theirs));
8
+ const merges = [];
9
+ const conflicts = [];
10
+ let oursAt = 0;
11
+ let theirsAt = 0;
12
+ let mergedAt = 0;
13
+ for (const block of blocks) {
14
+ if (block.kind === 'theirs') {
15
+ merges.push({
16
+ from: oursAt,
17
+ to: oursAt + block.ours.length,
18
+ lines: block.theirs
19
+ });
20
+ mergedAt += block.theirs.length;
21
+ } else {
22
+ if (block.kind === 'conflict') {
23
+ conflicts.push({
24
+ base: block.base,
25
+ ours: block.ours,
26
+ theirs: block.theirs,
27
+ from: mergedAt,
28
+ to: mergedAt + block.ours.length,
29
+ theirsStart: theirsAt + 1,
30
+ theirsEnd: theirsAt + block.theirs.length
31
+ });
32
+ }
33
+ mergedAt += block.ours.length;
34
34
  }
35
- return { merges, conflicts };
36
- }
35
+ oursAt += block.ours.length;
36
+ theirsAt += block.theirs.length;
37
+ }
38
+ return {
39
+ merges,
40
+ conflicts
41
+ };
42
+ }
@@ -1,20 +1,45 @@
1
1
  /* The rows of the Go to submenu. Declaration has no key of its own in the table. */
2
- const GO_TO = [
3
- { id: 'definition', method: 'textDocument/definition', shortcut: 'goToDefinition' },
4
- { id: 'declaration', method: 'textDocument/declaration', shortcut: null },
5
- { id: 'typeDefinition', method: 'textDocument/typeDefinition', shortcut: 'goToTypeDefinition' },
6
- { id: 'implementation', method: 'textDocument/implementation', shortcut: 'goToImplementation' }
7
- ];
8
- const REFERENCES = [
9
- { id: 'peekReferences', method: 'textDocument/references', shortcut: 'peekReferences' },
10
- { id: 'callHierarchy', method: 'textDocument/prepareCallHierarchy', shortcut: 'callHierarchy' }
11
- ];
12
- const CHANGES = [
13
- { id: 'renameSymbol', method: 'textDocument/rename', shortcut: 'renameSymbol' },
14
- { id: 'codeActions', method: 'textDocument/codeAction', shortcut: 'codeActions' }
15
- ];
2
+ const GO_TO = [{
3
+ id: 'definition',
4
+ method: 'textDocument/definition',
5
+ shortcut: 'goToDefinition'
6
+ }, {
7
+ id: 'declaration',
8
+ method: 'textDocument/declaration',
9
+ shortcut: null
10
+ }, {
11
+ id: 'typeDefinition',
12
+ method: 'textDocument/typeDefinition',
13
+ shortcut: 'goToTypeDefinition'
14
+ }, {
15
+ id: 'implementation',
16
+ method: 'textDocument/implementation',
17
+ shortcut: 'goToImplementation'
18
+ }];
19
+ const REFERENCES = [{
20
+ id: 'peekReferences',
21
+ method: 'textDocument/references',
22
+ shortcut: 'peekReferences'
23
+ }, {
24
+ id: 'callHierarchy',
25
+ method: 'textDocument/prepareCallHierarchy',
26
+ shortcut: 'callHierarchy'
27
+ }];
28
+ const CHANGES = [{
29
+ id: 'renameSymbol',
30
+ method: 'textDocument/rename',
31
+ shortcut: 'renameSymbol'
32
+ }, {
33
+ id: 'codeActions',
34
+ method: 'textDocument/codeAction',
35
+ shortcut: 'codeActions'
36
+ }];
16
37
  /* The language rows of the context menu in their groups, each holding only the rows a server answers. */
17
38
  export function menuGroupsOf(supports) {
18
- const supported = (rows) => rows.filter((row) => supports(row.method));
19
- return { goTo: supported(GO_TO), references: supported(REFERENCES), changes: supported(CHANGES) };
20
- }
39
+ const supported = rows => rows.filter(row => supports(row.method));
40
+ return {
41
+ goTo: supported(GO_TO),
42
+ references: supported(REFERENCES),
43
+ changes: supported(CHANGES)
44
+ };
45
+ }
@@ -3,52 +3,70 @@
3
3
  * servers support at the caret. The refactors are asked for while it opens, so it never waits for them.
4
4
  */
5
5
  export class ContextMenuFeature {
6
- language;
7
- request = 0;
8
- constructor(language) {
9
- this.language = language;
10
- const off = language.editor.onContextMenu((menu) => {
11
- // A right click outside the selection moves the caret first, so the menu is about what was clicked.
12
- if (!menu.inSelection) {
13
- language.editor.setCaret(menu.position);
14
- }
15
- this.open(menu.x, menu.y);
16
- });
17
- language.onDispose(() => {
18
- off();
19
- this.close();
20
- });
6
+ language;
7
+ request = 0;
8
+ constructor(language) {
9
+ this.language = language;
10
+ const off = language.editor.onContextMenu(menu => {
11
+ // A right click outside the selection moves the caret first, so the menu is about what was clicked.
12
+ if (!menu.inSelection) {
13
+ language.editor.setCaret(menu.position);
14
+ }
15
+ this.open(menu.x, menu.y);
16
+ });
17
+ language.onDispose(() => {
18
+ off();
19
+ this.close();
20
+ });
21
+ }
22
+ close() {
23
+ this.request++;
24
+ if (this.language.popups.getState().menu !== null) {
25
+ this.language.popups.setState({
26
+ menu: null
27
+ });
21
28
  }
22
- close() {
23
- this.request++;
24
- if (this.language.popups.getState().menu !== null) {
25
- this.language.popups.setState({ menu: null });
26
- }
29
+ }
30
+ /* The browser's own commands on the editor's input, which keep the clipboard and the undo history one thing. */
31
+ clipboard(action) {
32
+ const {
33
+ editor
34
+ } = this.language;
35
+ editor.focus();
36
+ const done = document.execCommand(action);
37
+ if (!done && action === 'paste') {
38
+ void navigator.clipboard?.readText().then(text => {
39
+ const range = editor.getSelection();
40
+ editor.applyEdits([{
41
+ range,
42
+ text
43
+ }]);
44
+ }).catch(() => undefined);
27
45
  }
28
- /* The browser's own commands on the editor's input, which keep the clipboard and the undo history one thing. */
29
- clipboard(action) {
30
- const { editor } = this.language;
31
- editor.focus();
32
- const done = document.execCommand(action);
33
- if (!done && action === 'paste') {
34
- void navigator.clipboard
35
- ?.readText()
36
- .then((text) => {
37
- const range = editor.getSelection();
38
- editor.applyEdits([{ range, text }]);
39
- })
40
- .catch(() => undefined);
41
- }
42
- }
43
- open(x, y) {
44
- const request = ++this.request;
45
- const { popups, codeActions } = this.language;
46
- popups.setState({ menu: { x, y, refactors: [] } });
47
- void codeActions.list(['refactor']).then((entries) => {
48
- const shown = popups.getState().menu;
49
- if (request === this.request && shown !== null && entries !== null) {
50
- popups.setState({ menu: { ...shown, refactors: entries } });
51
- }
46
+ }
47
+ open(x, y) {
48
+ const request = ++this.request;
49
+ const {
50
+ popups,
51
+ codeActions
52
+ } = this.language;
53
+ popups.setState({
54
+ menu: {
55
+ x,
56
+ y,
57
+ refactors: []
58
+ }
59
+ });
60
+ void codeActions.list(['refactor']).then(entries => {
61
+ const shown = popups.getState().menu;
62
+ if (request === this.request && shown !== null && entries !== null) {
63
+ popups.setState({
64
+ menu: {
65
+ ...shown,
66
+ refactors: entries
67
+ }
52
68
  });
53
- }
54
- }
69
+ }
70
+ });
71
+ }
72
+ }
@@ -8,93 +8,96 @@ import { wordRangeAt } from './rename-model.js';
8
8
  * key comes from the window.
9
9
  */
10
10
  export class DefinitionLinkFeature {
11
- language;
12
- held = false;
13
- pointer = null;
14
- shownKey = '';
15
- drawn = false;
16
- request = 0;
17
- lookup = null;
18
- constructor(language) {
19
- this.language = language;
20
- const { editor } = language;
21
- const offs = [
22
- editor.onHover((hover) => {
23
- this.pointer = hover?.position ?? null;
24
- this.update();
25
- }),
26
- editor.onTextChange(() => this.clear()),
27
- editor.onViewChange(() => this.clear())
28
- ];
29
- if (typeof window !== 'undefined') {
30
- const modKey = language.apple ? 'Meta' : 'Control';
31
- const keys = (event) => {
32
- if (event.key === modKey) {
33
- this.setModHeld(event.type === 'keydown');
34
- }
35
- };
36
- const lost = () => this.setModHeld(false);
37
- window.addEventListener('keydown', keys);
38
- window.addEventListener('keyup', keys);
39
- window.addEventListener('blur', lost);
40
- offs.push(() => {
41
- window.removeEventListener('keydown', keys);
42
- window.removeEventListener('keyup', keys);
43
- window.removeEventListener('blur', lost);
44
- });
11
+ language;
12
+ held = false;
13
+ pointer = null;
14
+ shownKey = '';
15
+ drawn = false;
16
+ request = 0;
17
+ lookup = null;
18
+ constructor(language) {
19
+ this.language = language;
20
+ const {
21
+ editor
22
+ } = language;
23
+ const offs = [editor.onHover(hover => {
24
+ this.pointer = hover?.position ?? null;
25
+ this.update();
26
+ }), editor.onTextChange(() => this.clear()), editor.onViewChange(() => this.clear())];
27
+ if (typeof window !== 'undefined') {
28
+ const modKey = language.apple ? 'Meta' : 'Control';
29
+ const keys = event => {
30
+ if (event.key === modKey) {
31
+ this.setModHeld(event.type === 'keydown');
45
32
  }
46
- language.onDispose(() => {
47
- for (const off of offs) {
48
- off();
49
- }
50
- this.clear();
51
- });
33
+ };
34
+ const lost = () => this.setModHeld(false);
35
+ window.addEventListener('keydown', keys);
36
+ window.addEventListener('keyup', keys);
37
+ window.addEventListener('blur', lost);
38
+ offs.push(() => {
39
+ window.removeEventListener('keydown', keys);
40
+ window.removeEventListener('keyup', keys);
41
+ window.removeEventListener('blur', lost);
42
+ });
52
43
  }
53
- setModHeld(held) {
54
- if (held !== this.held) {
55
- this.held = held;
56
- this.update();
57
- }
44
+ language.onDispose(() => {
45
+ for (const off of offs) {
46
+ off();
47
+ }
48
+ this.clear();
49
+ });
50
+ }
51
+ setModHeld(held) {
52
+ if (held !== this.held) {
53
+ this.held = held;
54
+ this.update();
58
55
  }
59
- clear() {
60
- this.request++;
61
- this.lookup?.abort();
62
- this.shownKey = '';
63
- if (this.drawn) {
64
- this.drawn = false;
65
- this.language.editor.setLink(null);
66
- }
56
+ }
57
+ clear() {
58
+ this.request++;
59
+ this.lookup?.abort();
60
+ this.shownKey = '';
61
+ if (this.drawn) {
62
+ this.drawn = false;
63
+ this.language.editor.setLink(null);
67
64
  }
68
- update() {
69
- const { pointer } = this;
70
- if (!this.held || pointer === null || !this.language.project.service.supports('textDocument/definition', this.language.uri)) {
71
- this.clear();
72
- return;
73
- }
74
- const { editor, project, uri } = this.language;
75
- const line = lineTextOf(editor, pointer.line);
76
- const word = isIdentifierCharacter(line[pointer.character] ?? '') ? wordRangeAt(line, pointer) : null;
77
- if (word === null) {
78
- this.clear();
79
- return;
80
- }
81
- const key = `${word.start.line}:${word.start.character}`;
82
- if (key === this.shownKey) {
83
- return;
84
- }
85
- this.clear();
86
- this.shownKey = key;
87
- const request = ++this.request;
88
- const controller = new AbortController();
89
- this.lookup = controller;
90
- project.service
91
- .definition(uri, pointer, { signal: controller.signal })
92
- .then((result) => {
93
- if (request === this.request && locationsOf(result).length > 0) {
94
- this.drawn = true;
95
- editor.setLink(word);
96
- }
97
- })
98
- .catch(() => undefined);
65
+ }
66
+ update() {
67
+ const {
68
+ pointer
69
+ } = this;
70
+ if (!this.held || pointer === null || !this.language.project.service.supports('textDocument/definition', this.language.uri)) {
71
+ this.clear();
72
+ return;
73
+ }
74
+ const {
75
+ editor,
76
+ project,
77
+ uri
78
+ } = this.language;
79
+ const line = lineTextOf(editor, pointer.line);
80
+ const word = isIdentifierCharacter(line[pointer.character] ?? '') ? wordRangeAt(line, pointer) : null;
81
+ if (word === null) {
82
+ this.clear();
83
+ return;
84
+ }
85
+ const key = `${word.start.line}:${word.start.character}`;
86
+ if (key === this.shownKey) {
87
+ return;
99
88
  }
100
- }
89
+ this.clear();
90
+ this.shownKey = key;
91
+ const request = ++this.request;
92
+ const controller = new AbortController();
93
+ this.lookup = controller;
94
+ project.service.definition(uri, pointer, {
95
+ signal: controller.signal
96
+ }).then(result => {
97
+ if (request === this.request && locationsOf(result).length > 0) {
98
+ this.drawn = true;
99
+ editor.setLink(word);
100
+ }
101
+ }).catch(() => undefined);
102
+ }
103
+ }
@@ -1,4 +1,9 @@
1
- const SEVERITIES = { 1: 'error', 2: 'warning', 3: 'info', 4: 'hint' };
1
+ const SEVERITIES = {
2
+ 1: 'error',
3
+ 2: 'warning',
4
+ 3: 'info',
5
+ 4: 'hint'
6
+ };
2
7
  const HINT = 4;
3
8
  const UNNECESSARY = 1;
4
9
  const DEPRECATED = 2;
@@ -6,84 +11,98 @@ const DEPRECATED = 2;
6
11
  const TICK_MESSAGE_LENGTH = 300;
7
12
  /* A report that names no severity is an error, which is the safer side to be wrong on. */
8
13
  export function severityOf(diagnostic) {
9
- return SEVERITIES[diagnostic.severity ?? 1] ?? 'error';
14
+ return SEVERITIES[diagnostic.severity ?? 1] ?? 'error';
10
15
  }
11
16
  export function markerOf(diagnostic) {
12
- return {
13
- range: diagnostic.range,
14
- severity: severityOf(diagnostic),
15
- unnecessary: diagnostic.tags?.includes(UNNECESSARY) === true,
16
- deprecated: diagnostic.tags?.includes(DEPRECATED) === true,
17
- message: diagnostic.message.length > TICK_MESSAGE_LENGTH ? `${diagnostic.message.slice(0, TICK_MESSAGE_LENGTH)}…` : diagnostic.message
18
- };
17
+ return {
18
+ range: diagnostic.range,
19
+ severity: severityOf(diagnostic),
20
+ unnecessary: diagnostic.tags?.includes(UNNECESSARY) === true,
21
+ deprecated: diagnostic.tags?.includes(DEPRECATED) === true,
22
+ message: diagnostic.message.length > TICK_MESSAGE_LENGTH ? `${diagnostic.message.slice(0, TICK_MESSAGE_LENGTH)}…` : diagnostic.message
23
+ };
19
24
  }
20
25
  /* A diagnostic that names no severity counts as an error. */
21
26
  export function problemCountsOf(diagnostics) {
22
- const count = (severity) => diagnostics.filter((diagnostic) => (diagnostic.severity ?? 1) === severity).length;
23
- return { error: count(1), warning: count(2), info: count(3) };
27
+ const count = severity => diagnostics.filter(diagnostic => (diagnostic.severity ?? 1) === severity).length;
28
+ return {
29
+ error: count(1),
30
+ warning: count(2),
31
+ info: count(3)
32
+ };
24
33
  }
25
34
  export function comparePositions(left, right) {
26
- return left.line === right.line ? left.character - right.character : left.line - right.line;
35
+ return left.line === right.line ? left.character - right.character : left.line - right.line;
27
36
  }
28
37
  /* Where an insertion of `text` at `start` ends, counting a line break of any kind once. */
29
38
  export function endOfInsertion(start, text) {
30
- const lines = text.split(/\r\n|\r|\n/);
31
- return lines.length === 1
32
- ? { line: start.line, character: start.character + text.length }
33
- : { line: start.line + lines.length - 1, character: lines[lines.length - 1].length };
39
+ const lines = text.split(/\r\n|\r|\n/);
40
+ return lines.length === 1 ? {
41
+ line: start.line,
42
+ character: start.character + text.length
43
+ } : {
44
+ line: start.line + lines.length - 1,
45
+ character: lines[lines.length - 1].length
46
+ };
34
47
  }
35
48
  /* Where a position is once one change is applied to the text it was in. One inside the replaced range lands after the new text. */
36
49
  export function shiftPosition(position, change) {
37
- const { start, end } = change.range;
38
- if (comparePositions(position, start) < 0) {
39
- return position;
40
- }
41
- const inserted = endOfInsertion(start, change.text);
42
- if (comparePositions(position, end) < 0) {
43
- return inserted;
44
- }
45
- return position.line === end.line
46
- ? { line: inserted.line, character: inserted.character + (position.character - end.character) }
47
- : { line: position.line + (inserted.line - end.line), character: position.character };
50
+ const {
51
+ start,
52
+ end
53
+ } = change.range;
54
+ if (comparePositions(position, start) < 0) {
55
+ return position;
56
+ }
57
+ const inserted = endOfInsertion(start, change.text);
58
+ if (comparePositions(position, end) < 0) {
59
+ return inserted;
60
+ }
61
+ return position.line === end.line ? {
62
+ line: inserted.line,
63
+ character: inserted.character + (position.character - end.character)
64
+ } : {
65
+ line: position.line + (inserted.line - end.line),
66
+ character: position.character
67
+ };
48
68
  }
49
69
  export function shiftRange(range, changes) {
50
- let start = range.start;
51
- let end = range.end;
52
- for (const change of changes) {
53
- start = shiftPosition(start, change);
54
- end = shiftPosition(end, change);
55
- }
56
- return { start, end };
70
+ let start = range.start;
71
+ let end = range.end;
72
+ for (const change of changes) {
73
+ start = shiftPosition(start, change);
74
+ end = shiftPosition(end, change);
75
+ }
76
+ return {
77
+ start,
78
+ end
79
+ };
57
80
  }
58
81
  /* A range holds a position from its start up to and including its end, so a caret at either edge of a word is on it. An empty range holds only its own place. */
59
82
  export function rangeHolds(range, position) {
60
- return comparePositions(range.start, position) <= 0 && comparePositions(position, range.end) <= 0;
83
+ return comparePositions(range.start, position) <= 0 && comparePositions(position, range.end) <= 0;
61
84
  }
62
85
  /* The problems under a position, worst first. A hint is not a problem, so it is left to the colors and the faded text. */
63
86
  export function problemsAt(problems, position) {
64
- const rank = (problem) => problem.diagnostic.severity ?? 1;
65
- return problems
66
- .filter((problem) => (problem.diagnostic.severity ?? 1) < HINT && rangeHolds(problem.diagnostic.range, position))
67
- .sort((left, right) => rank(left) - rank(right));
87
+ const rank = problem => problem.diagnostic.severity ?? 1;
88
+ return problems.filter(problem => (problem.diagnostic.severity ?? 1) < HINT && rangeHolds(problem.diagnostic.range, position)).sort((left, right) => rank(left) - rank(right));
68
89
  }
69
90
  /* The start of the first problem after the position, or the last one before it when `direction` is back; it wraps round the document. */
70
91
  export function neighborProblem(problems, from, direction) {
71
- const candidates = problems
72
- .filter((problem) => (problem.diagnostic.severity ?? 1) < HINT)
73
- .sort((left, right) => comparePositions(left.diagnostic.range.start, right.diagnostic.range.start));
74
- if (candidates.length === 0) {
75
- return null;
76
- }
77
- if (direction === 1) {
78
- return candidates.find((problem) => comparePositions(problem.diagnostic.range.start, from) > 0) ?? candidates[0];
79
- }
80
- return [...candidates].reverse().find((problem) => comparePositions(problem.diagnostic.range.start, from) < 0) ?? candidates[candidates.length - 1];
92
+ const candidates = problems.filter(problem => (problem.diagnostic.severity ?? 1) < HINT).sort((left, right) => comparePositions(left.diagnostic.range.start, right.diagnostic.range.start));
93
+ if (candidates.length === 0) {
94
+ return null;
95
+ }
96
+ if (direction === 1) {
97
+ return candidates.find(problem => comparePositions(problem.diagnostic.range.start, from) > 0) ?? candidates[0];
98
+ }
99
+ return [...candidates].reverse().find(problem => comparePositions(problem.diagnostic.range.start, from) < 0) ?? candidates[candidates.length - 1];
81
100
  }
82
101
  /* `ts(2551)`, or the code alone, or the source alone, whichever the server gave. */
83
102
  export function codeLabelOf(diagnostic) {
84
- const code = diagnostic.code === undefined ? '' : String(diagnostic.code);
85
- if (diagnostic.source !== undefined && code !== '') {
86
- return `${diagnostic.source}(${code})`;
87
- }
88
- return code !== '' ? code : (diagnostic.source ?? '');
89
- }
103
+ const code = diagnostic.code === undefined ? '' : String(diagnostic.code);
104
+ if (diagnostic.source !== undefined && code !== '') {
105
+ return `${diagnostic.source}(${code})`;
106
+ }
107
+ return code !== '' ? code : diagnostic.source ?? '';
108
+ }