@adecore/editor-core 0.0.1 → 0.17.0-beta.2

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 (80) hide show
  1. package/LICENSE +110 -0
  2. package/LICENSE.apache-2.0.txt +201 -0
  3. package/NOTICE +11 -0
  4. package/README.md +40 -0
  5. package/dist/block-folds.d.ts +3 -0
  6. package/dist/block-folds.js +112 -0
  7. package/dist/brackets.d.ts +5 -0
  8. package/dist/brackets.js +136 -0
  9. package/dist/closer-tracker.d.ts +9 -0
  10. package/dist/closer-tracker.js +46 -0
  11. package/dist/comments.d.ts +14 -0
  12. package/dist/comments.js +344 -0
  13. package/dist/document.d.ts +148 -0
  14. package/dist/document.js +1729 -0
  15. package/dist/edit-source.d.ts +19 -0
  16. package/dist/edit-source.js +1 -0
  17. package/dist/enter.d.ts +17 -0
  18. package/dist/enter.js +387 -0
  19. package/dist/fold-roles.d.ts +6 -0
  20. package/dist/fold-roles.js +142 -0
  21. package/dist/index.d.ts +10 -0
  22. package/dist/index.js +7 -0
  23. package/dist/languages.d.ts +12 -0
  24. package/dist/languages.js +51 -0
  25. package/dist/lexical-folds.d.ts +10 -0
  26. package/dist/lexical-folds.js +116 -0
  27. package/dist/lexical.d.ts +16 -0
  28. package/dist/lexical.js +74 -0
  29. package/dist/line-commands.d.ts +9 -0
  30. package/dist/line-commands.js +306 -0
  31. package/dist/markup-regions.d.ts +8 -0
  32. package/dist/markup-regions.js +331 -0
  33. package/dist/offsets.d.ts +2 -0
  34. package/dist/offsets.js +14 -0
  35. package/dist/paste.d.ts +9 -0
  36. package/dist/paste.js +108 -0
  37. package/dist/preserve-case.d.ts +1 -0
  38. package/dist/preserve-case.js +61 -0
  39. package/dist/rope.d.ts +22 -0
  40. package/dist/rope.js +246 -0
  41. package/dist/search.d.ts +26 -0
  42. package/dist/search.js +85 -0
  43. package/dist/structure.d.ts +50 -0
  44. package/dist/structure.js +124 -0
  45. package/dist/text-span.d.ts +7 -0
  46. package/dist/text-span.js +211 -0
  47. package/dist/types.d.ts +70 -0
  48. package/dist/types.js +1 -0
  49. package/dist/typing-context.d.ts +30 -0
  50. package/dist/typing-context.js +270 -0
  51. package/dist/typing-handlers.d.ts +15 -0
  52. package/dist/typing-handlers.js +125 -0
  53. package/dist/words.d.ts +7 -0
  54. package/dist/words.js +72 -0
  55. package/package.json +34 -3
  56. package/src/block-folds.ts +117 -0
  57. package/src/brackets.ts +159 -0
  58. package/src/closer-tracker.ts +60 -0
  59. package/src/comments.ts +411 -0
  60. package/src/document.ts +2021 -0
  61. package/src/edit-source.ts +25 -0
  62. package/src/enter.ts +452 -0
  63. package/src/fold-roles.ts +166 -0
  64. package/src/index.ts +22 -0
  65. package/src/languages.ts +77 -0
  66. package/src/lexical-folds.ts +138 -0
  67. package/src/lexical.ts +113 -0
  68. package/src/line-commands.ts +356 -0
  69. package/src/markup-regions.ts +333 -0
  70. package/src/offsets.ts +16 -0
  71. package/src/paste.ts +126 -0
  72. package/src/preserve-case.ts +62 -0
  73. package/src/rope.ts +278 -0
  74. package/src/search.ts +119 -0
  75. package/src/structure.ts +223 -0
  76. package/src/text-span.ts +230 -0
  77. package/src/types.ts +141 -0
  78. package/src/typing-context.ts +329 -0
  79. package/src/typing-handlers.ts +143 -0
  80. package/src/words.ts +83 -0
@@ -0,0 +1,46 @@
1
+ const limit = 64;
2
+ /*
3
+ * The closers the editor inserted by itself and the caret has not left yet, which Tab steps over. A
4
+ * mark follows its opener and closer through edits and goes as soon as an edit replaces either one
5
+ * or no caret sits inside the pair any more.
6
+ */
7
+ export class CloserTracker {
8
+ marks = [];
9
+ add(open, close) {
10
+ this.marks.push({ open, close });
11
+ if (this.marks.length > limit) {
12
+ this.marks.shift();
13
+ }
14
+ }
15
+ /* The closer that sits at `offset`, which a Tab there steps over. */
16
+ isCloserAt(offset) {
17
+ return this.marks.some((mark) => mark.close === offset);
18
+ }
19
+ map(edits) {
20
+ this.marks = this.marks.flatMap((mark) => {
21
+ const open = mapThrough(mark.open, edits);
22
+ const close = mapThrough(mark.close, edits);
23
+ return open === null || close === null ? [] : [{ open, close }];
24
+ });
25
+ }
26
+ prune(selections) {
27
+ this.marks = this.marks.filter((mark) => selections.some((selection) => selection.head > mark.open && selection.head <= mark.close));
28
+ }
29
+ clear() {
30
+ this.marks = [];
31
+ }
32
+ }
33
+ /* Null when an edit replaced the character at `offset`. */
34
+ function mapThrough(offset, edits) {
35
+ let delta = 0;
36
+ for (const edit of edits) {
37
+ if (offset < edit.from) {
38
+ break;
39
+ }
40
+ if (offset < edit.to) {
41
+ return null;
42
+ }
43
+ delta += edit.text.length - (edit.to - edit.from);
44
+ }
45
+ return offset + delta;
46
+ }
@@ -0,0 +1,14 @@
1
+ import type { EditPlan, EditSource } from './edit-source.ts';
2
+ import type { Selection } from './types.ts';
3
+ export interface CommentOptions {
4
+ language: string;
5
+ tabSize: number;
6
+ insertSpaces: boolean;
7
+ lineToken?: string;
8
+ lineSpan?: (line: number) => {
9
+ first: number;
10
+ last: number;
11
+ };
12
+ }
13
+ export declare function planLineComments(source: EditSource, selections: readonly Selection[], options: CommentOptions): EditPlan | null;
14
+ export declare function planBlockComment(source: EditSource, selections: readonly Selection[], options: CommentOptions): EditPlan | null;
@@ -0,0 +1,344 @@
1
+ import { commentSyntax } from './languages.js';
2
+ import { mapOffset } from './offsets.js';
3
+ import { indentationColumn } from './structure.js';
4
+ function whitespaceOf(text) {
5
+ return /^[\t ]*/.exec(text)[0];
6
+ }
7
+ function isBlank(text) {
8
+ return text.trim() === '';
9
+ }
10
+ function syntaxOf(source, options, line) {
11
+ const syntax = commentSyntax(options.language, source.region(line));
12
+ return options.lineToken === undefined ? syntax : { ...syntax, line: options.lineToken };
13
+ }
14
+ function rangeOf(selection) {
15
+ return { from: Math.min(selection.anchor, selection.head), to: Math.max(selection.anchor, selection.head) };
16
+ }
17
+ /* The runs of adjacent lines the selections touch. A selection that ends at the start of a line does not touch it. */
18
+ function blocksOf(source, selections, span) {
19
+ const blocks = [];
20
+ const ordered = selections.map((selection, index) => ({ ...rangeOf(selection), index })).sort((left, right) => left.from - right.from);
21
+ for (const { from, to, index } of ordered) {
22
+ let first = source.lineAt(from);
23
+ let last = source.lineAt(to);
24
+ if (last > first && source.line(last).start === to) {
25
+ last--;
26
+ }
27
+ if (span) {
28
+ first = span(first).first;
29
+ last = Math.max(last, span(last).last);
30
+ }
31
+ const previous = blocks.at(-1);
32
+ if (previous && first <= previous.last + 1) {
33
+ previous.last = Math.max(previous.last, last);
34
+ previous.carets.push(index);
35
+ }
36
+ else {
37
+ blocks.push({ first, last, carets: [index] });
38
+ }
39
+ }
40
+ return blocks;
41
+ }
42
+ function isCommented(text, syntax, multiline) {
43
+ const trimmed = text.trim();
44
+ if (syntax.line !== null) {
45
+ return trimmed.startsWith(syntax.line.trimEnd());
46
+ }
47
+ const block = syntax.block;
48
+ if (trimmed === '') {
49
+ return multiline;
50
+ }
51
+ return trimmed.length >= block.open.length + block.close.length && trimmed.startsWith(block.open) && trimmed.endsWith(block.close);
52
+ }
53
+ function indentText(width, options) {
54
+ if (options.insertSpaces) {
55
+ return ' '.repeat(width);
56
+ }
57
+ return '\t'.repeat(Math.floor(width / options.tabSize)) + ' '.repeat(width % options.tabSize);
58
+ }
59
+ /* The new place of a line after the edits, which never cross a line break. */
60
+ function geometryOf(source, edits, index) {
61
+ const bounds = source.line(index);
62
+ const result = { start: bounds.start, length: bounds.end - bounds.start };
63
+ for (const edit of edits) {
64
+ const delta = edit.text.length - (edit.to - edit.from);
65
+ if (edit.from < bounds.start) {
66
+ result.start += delta;
67
+ }
68
+ else if (edit.to <= bounds.end) {
69
+ result.length += delta;
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ /*
75
+ * Comments the lines the selections touch, or takes the comment off when every non-blank one has it.
76
+ * The markers go in at the smallest indentation of the lines, and a lone caret moves to the next line.
77
+ */
78
+ export function planLineComments(source, selections, options) {
79
+ const blocks = blocksOf(source, selections, options.lineSpan);
80
+ const syntaxes = blocks.map((block) => syntaxOf(source, options, block.first));
81
+ if (syntaxes.some((syntax) => syntax.line === null && syntax.block === null)) {
82
+ return null;
83
+ }
84
+ const lineBased = syntaxes.map((syntax) => (syntax.line === null ? syntax : { ...syntax, block: null }));
85
+ let allCommented = true;
86
+ let anyCommented = false;
87
+ for (const [position, block] of blocks.entries()) {
88
+ const single = block.first === block.last;
89
+ for (let line = block.first; line <= block.last; line++) {
90
+ const text = source.line(line).text;
91
+ const commented = isCommented(text, lineBased[position], !single);
92
+ if (commented && !isBlank(text)) {
93
+ anyCommented = true;
94
+ }
95
+ if (!commented && (single || !isBlank(text))) {
96
+ allCommented = false;
97
+ }
98
+ }
99
+ if (allCommented && !single && !anyCommented) {
100
+ allCommented = false;
101
+ }
102
+ }
103
+ const edits = [];
104
+ const placed = new Set();
105
+ for (const [position, block] of blocks.entries()) {
106
+ const syntax = lineBased[position];
107
+ const multiline = block.first !== block.last;
108
+ const startingNewLine = !multiline &&
109
+ block.carets.length === 1 &&
110
+ isBlank(source.line(block.first).text) &&
111
+ selections[block.carets[0]].anchor === selections[block.carets[0]].head;
112
+ const minimum = allCommented ? 0 : minimumIndent(source, block, syntax, options);
113
+ for (let line = block.first; line <= block.last; line++) {
114
+ const bounds = source.line(line);
115
+ const edit = allCommented
116
+ ? uncommentLine(bounds.start, bounds.text, syntax)
117
+ : commentLine(bounds.start, bounds.text, syntax, minimum, multiline, startingNewLine, options);
118
+ if (edit) {
119
+ edits.push(edit);
120
+ if (startingNewLine && !allCommented) {
121
+ placed.add(line);
122
+ }
123
+ }
124
+ }
125
+ }
126
+ if (edits.length === 0) {
127
+ return null;
128
+ }
129
+ return { edits, selections: finalSelections(source, selections, blocks, edits, allCommented, placed, lineBased, options.lineSpan) };
130
+ }
131
+ function minimumIndent(source, block, syntax, options) {
132
+ let minimum = Number.POSITIVE_INFINITY;
133
+ for (let line = block.first; line <= block.last; line++) {
134
+ const text = source.line(line).text;
135
+ if (!isBlank(text)) {
136
+ minimum = Math.min(minimum, indentationColumn(whitespaceOf(text), options.tabSize));
137
+ }
138
+ }
139
+ if (block.first > 0) {
140
+ const previous = source.line(block.first - 1).text;
141
+ const marker = syntax.line ?? syntax.block?.open;
142
+ if (marker && previous.trimStart().startsWith(marker)) {
143
+ minimum = Math.min(minimum, indentationColumn(whitespaceOf(previous), options.tabSize));
144
+ }
145
+ }
146
+ return Number.isFinite(minimum) ? minimum : 0;
147
+ }
148
+ function commentLine(start, text, syntax, minimum, multiline, startingNewLine, options) {
149
+ const blank = isBlank(text);
150
+ if (syntax.line === null && blank && multiline) {
151
+ return null;
152
+ }
153
+ const leading = whitespaceOf(text);
154
+ let kept = 0;
155
+ let width = 0;
156
+ while (kept < leading.length && width < minimum) {
157
+ width += leading[kept] === '\t' ? options.tabSize - (width % options.tabSize) : 1;
158
+ kept++;
159
+ }
160
+ // A line whose whitespace ends before the indent does is padded out to it.
161
+ const short = width < minimum;
162
+ const padding = short ? indentText(minimum, options) : '';
163
+ const markerAt = start + (short ? leading.length : kept);
164
+ if (syntax.line !== null) {
165
+ const space = !blank || startingNewLine ? ' ' : '';
166
+ return { from: short ? start : markerAt, to: markerAt, text: padding + syntax.line + space };
167
+ }
168
+ const { open, close } = syntax.block;
169
+ const end = start + text.trimEnd().length;
170
+ const body = blank ? '' : text.slice(markerAt - start, end - start);
171
+ return { from: short ? start : markerAt, to: blank ? start + text.length : end, text: padding + open + (blank ? ' ' : ` ${body} `) + close };
172
+ }
173
+ function uncommentLine(start, text, syntax) {
174
+ const trimmed = text.trim();
175
+ if (trimmed === '') {
176
+ return null;
177
+ }
178
+ const leading = whitespaceOf(text);
179
+ let rest;
180
+ if (syntax.line !== null) {
181
+ const marker = syntax.line.trimEnd();
182
+ if (!trimmed.startsWith(marker)) {
183
+ return null;
184
+ }
185
+ const body = text.slice(leading.length + marker.length);
186
+ rest = body.startsWith(' ') ? body.slice(1) : body;
187
+ }
188
+ else {
189
+ const { open, close } = syntax.block;
190
+ if (!trimmed.startsWith(open) || !trimmed.endsWith(close)) {
191
+ return null;
192
+ }
193
+ const inner = text.trimEnd().slice(leading.length + open.length, -close.length);
194
+ rest = (inner.startsWith(' ') ? inner.slice(1) : inner).replace(/ $/, '');
195
+ rest += text.slice(text.trimEnd().length);
196
+ }
197
+ const kept = leading + rest;
198
+ if (kept.trim() === '') {
199
+ return { from: start, to: start + text.length, text: '' };
200
+ }
201
+ return { from: start + leading.length, to: start + text.length, text: rest };
202
+ }
203
+ function finalSelections(source, selections, blocks, edits, allCommented, placed, syntaxes, span) {
204
+ const sorted = [...edits].sort((left, right) => left.from - right.from);
205
+ const result = selections.map((selection) => ({
206
+ anchor: mapOffset(selection.anchor, sorted, true),
207
+ head: mapOffset(selection.head, sorted, true)
208
+ }));
209
+ const moveCarets = blocks.every((block) => block.carets.length === 1 || block.first === block.last);
210
+ if (!moveCarets) {
211
+ return result;
212
+ }
213
+ for (const [position, block] of blocks.entries()) {
214
+ for (const index of block.carets) {
215
+ const selection = selections[index];
216
+ const { from, to } = rangeOf(selection);
217
+ const line = source.lineAt(from);
218
+ if (from === to) {
219
+ result[index] = caretAfter(source, sorted, line, span?.(line).last ?? line, selection.head, allCommented, placed, syntaxes[position]);
220
+ continue;
221
+ }
222
+ const lastLine = source.lineAt(to - 1);
223
+ const whole = source.line(line).start === from && source.line(lastLine).next === to;
224
+ if (whole) {
225
+ const start = geometryOf(source, sorted, line).start;
226
+ result[index] =
227
+ selection.anchor <= selection.head ? { anchor: start, head: result[index].head } : { anchor: result[index].anchor, head: start };
228
+ }
229
+ }
230
+ }
231
+ return result;
232
+ }
233
+ function caretAfter(source, edits, line, lastLine, offset, allCommented, placed, syntax) {
234
+ const geometry = geometryOf(source, edits, line);
235
+ if (placed.has(line) && !allCommented) {
236
+ const caret = syntax.line === null ? geometry.start + geometry.length - syntax.block.close.length - 1 : geometry.start + geometry.length;
237
+ return { anchor: caret, head: caret };
238
+ }
239
+ const mapped = mapOffset(offset, edits);
240
+ if (lastLine >= source.lineCount - 1) {
241
+ return { anchor: mapped, head: mapped };
242
+ }
243
+ const next = geometryOf(source, edits, lastLine + 1);
244
+ const column = Math.min(mapped - geometry.start, next.length);
245
+ return { anchor: next.start + column, head: next.start + column };
246
+ }
247
+ /* Where the comment that holds `offset` runs, for the markers the lexer knows. Null outside a comment. */
248
+ function commentAround(source, offset, block) {
249
+ const context = source.context(offset);
250
+ if ((context.mode !== 'block-comment' && context.mode !== 'html-comment') || context.commentStart === undefined) {
251
+ return null;
252
+ }
253
+ const from = context.commentStart;
254
+ if (source.slice(from, from + block.open.length) !== block.open) {
255
+ return null;
256
+ }
257
+ const close = source.slice(from + block.open.length, from + block.open.length + 200_000).indexOf(block.close);
258
+ return close < 0 ? null : { from, to: from + block.open.length + close + block.close.length };
259
+ }
260
+ /* The comment a selection is, markers and all, or null. */
261
+ function commentOf(source, from, to, block) {
262
+ const text = source.slice(from, to);
263
+ const start = text.length - text.trimStart().length;
264
+ const end = text.trimEnd().length;
265
+ const body = text.slice(start, end);
266
+ if (body.length >= block.open.length + block.close.length && body.startsWith(block.open) && body.endsWith(block.close)) {
267
+ return { from: from + start, to: from + end };
268
+ }
269
+ return null;
270
+ }
271
+ /*
272
+ * Wraps each selection in the block markers, or takes them off a comment the selection is or sits in.
273
+ * With nothing selected it opens an empty comment around the caret.
274
+ */
275
+ export function planBlockComment(source, selections, options) {
276
+ const edits = [];
277
+ const result = [];
278
+ let offsetDelta = 0;
279
+ for (const selection of selections) {
280
+ const { from, to } = rangeOf(selection);
281
+ const block = syntaxOf(source, options, source.lineAt(from)).block;
282
+ if (!block) {
283
+ return null;
284
+ }
285
+ const found = commentOf(source, from, to, block) ?? commentAround(source, from, block);
286
+ if (found && from !== to && !(found.from >= from && found.to <= to)) {
287
+ return null;
288
+ }
289
+ if (found) {
290
+ const innerStart = found.from + block.open.length + (source.charAt(found.from + block.open.length) === ' ' ? 1 : 0);
291
+ const closeAt = found.to - block.close.length;
292
+ const innerEnd = closeAt - (source.charAt(closeAt - 1) === ' ' && closeAt - 1 >= innerStart ? 1 : 0);
293
+ edits.push({ from: found.from, to: innerStart, text: '' }, { from: innerEnd, to: found.to, text: '' });
294
+ const head = Math.min(Math.max(selection.head, innerStart), innerEnd);
295
+ const anchor = Math.min(Math.max(selection.anchor, innerStart), innerEnd);
296
+ const removedBefore = innerStart - found.from;
297
+ result.push({ anchor: anchor - removedBefore + offsetDelta, head: head - removedBefore + offsetDelta });
298
+ offsetDelta -= innerStart - found.from + (found.to - innerEnd);
299
+ continue;
300
+ }
301
+ if (source.slice(from, to).includes(block.close)) {
302
+ return null;
303
+ }
304
+ if (from === to) {
305
+ const text = `${block.open} ${block.close}`;
306
+ edits.push({ from, to, text });
307
+ const caret = from + offsetDelta + block.open.length + 1;
308
+ result.push({ anchor: caret, head: caret });
309
+ offsetDelta += text.length;
310
+ continue;
311
+ }
312
+ const wrapped = wrapRange(source, from, to, block, options);
313
+ edits.push(...wrapped);
314
+ const added = wrapped.reduce((sum, edit) => sum + edit.text.length, 0);
315
+ result.push({ anchor: from + offsetDelta, head: to + added + offsetDelta });
316
+ offsetDelta += added;
317
+ }
318
+ return { edits, selections: result };
319
+ }
320
+ function wrapRange(source, from, to, block, options) {
321
+ const first = source.lineAt(from);
322
+ const last = source.lineAt(to - 1);
323
+ const endsLine = source.charAt(to - 1) === '\n' || to === source.line(source.lineCount - 1).end;
324
+ if (from !== source.line(first).start || !endsLine) {
325
+ return [
326
+ { from, to: from, text: `${block.open} ` },
327
+ { from: to, to, text: ` ${block.close}` }
328
+ ];
329
+ }
330
+ let minimum = Number.POSITIVE_INFINITY;
331
+ for (let line = first; line <= last; line++) {
332
+ const text = source.line(line).text;
333
+ if (!isBlank(text)) {
334
+ minimum = Math.min(minimum, indentationColumn(whitespaceOf(text), options.tabSize));
335
+ }
336
+ }
337
+ const space = indentText(Number.isFinite(minimum) ? minimum : 0, options);
338
+ const newline = source.newline(first);
339
+ const closing = source.charAt(to - 1) === '\n' ? `${space}${block.close}${newline}` : `${newline}${space}${block.close}`;
340
+ return [
341
+ { from, to: from, text: `${space}${block.open}${newline}` },
342
+ { from: to, to, text: closing }
343
+ ];
344
+ }
@@ -0,0 +1,148 @@
1
+ import type { DocumentLine } from './rope.ts';
2
+ import type { FindMatch, FindNextOptions, FindOptions } from './search.ts';
3
+ import type { FoldingOptions, FoldingRange } from './structure.ts';
4
+ import type { CommandOptions, Disposable, EditOptions, EditorCommand, EditorSnapshot, Position, Selection, TextEdit } from './types.ts';
5
+ export type { DocumentLine, FindMatch, FindNextOptions, FindOptions, FoldingOptions, FoldingRange };
6
+ export interface OffsetRange {
7
+ readonly from: number;
8
+ readonly to: number;
9
+ }
10
+ export interface DocumentEditOptions extends EditOptions {
11
+ expectedRevision?: number;
12
+ }
13
+ export interface TypeTextOptions extends CommandOptions {
14
+ historyGroup?: string;
15
+ expectedRevision?: number;
16
+ }
17
+ export interface ReplaceOptions extends DocumentEditOptions {
18
+ literal?: boolean;
19
+ preserveCase?: boolean;
20
+ }
21
+ export interface ReplaceAllOptions extends FindOptions, ReplaceOptions {
22
+ }
23
+ export type VisualLineOf = (offset: number) => {
24
+ start: number;
25
+ end: number;
26
+ };
27
+ export declare class DocumentModel {
28
+ private rope;
29
+ private selections;
30
+ private revision;
31
+ private undoStack;
32
+ private redoStack;
33
+ private listeners;
34
+ private groupOpen;
35
+ private textCache;
36
+ private structureCache?;
37
+ private selectionHistory;
38
+ private typingContexts;
39
+ private statementClosers;
40
+ private cloneSession;
41
+ private occurrenceSession;
42
+ occurrencesExhausted: boolean;
43
+ private closers;
44
+ private bracketCache?;
45
+ constructor(text?: string);
46
+ getText(): string;
47
+ getLength(): number;
48
+ getRevision(): number;
49
+ getLineCount(): number;
50
+ getLine(line: number): DocumentLine;
51
+ slice(from: number, to: number): string;
52
+ getSelections(): readonly Selection[];
53
+ getSelectionCount(): number;
54
+ getPrimary(): Selection;
55
+ getSnapshot(): EditorSnapshot;
56
+ setSelections(selections: readonly Selection[]): void;
57
+ subscribe(listener: (snapshot: EditorSnapshot) => void): Disposable;
58
+ applyEdits(edits: readonly TextEdit[], options?: DocumentEditOptions): boolean;
59
+ setText(text: string): void;
60
+ undo(): boolean;
61
+ redo(): boolean;
62
+ positionAt(offset: number): Position;
63
+ offsetAt(position: Position): number;
64
+ find(query: string, options?: FindOptions): FindMatch[];
65
+ findNext(query: string, from?: number, options?: FindNextOptions): FindMatch | null;
66
+ replace(match: FindMatch, replacement: string, options?: ReplaceOptions): boolean;
67
+ replaceAll(query: string, replacement: string, options?: ReplaceAllOptions): number;
68
+ getFoldingRanges(options?: FoldingOptions): FoldingRange[];
69
+ typeText(text: string, options?: TypeTextOptions): boolean;
70
+ paste(text: string, options?: CommandOptions & {
71
+ wholeLines?: boolean;
72
+ }): boolean;
73
+ execute(command: EditorCommand, options?: CommandOptions): boolean;
74
+ private validateEdits;
75
+ private planTyping;
76
+ private surroundSelection;
77
+ private dedentCloser;
78
+ private shouldClosePair;
79
+ private completesTripleQuote;
80
+ private hasMatch;
81
+ private rememberStatementClosers;
82
+ private rememberPairs;
83
+ private insertTab;
84
+ private columnOf;
85
+ private moveToLineEdge;
86
+ private firstNonSpace;
87
+ private homeOffset;
88
+ private smartIndentColumn;
89
+ private offsetAtColumn;
90
+ private endOffset;
91
+ private moveByWord;
92
+ private caretStop;
93
+ private foldedStop;
94
+ private nextLineStop;
95
+ private previousLineStop;
96
+ private addCaret;
97
+ private cloneSource;
98
+ private cloneOnto;
99
+ private changeLineIndentation;
100
+ private toggleComment;
101
+ private selectedLines;
102
+ private duplicate;
103
+ private deleteLines;
104
+ private moveLines;
105
+ private insertNewline;
106
+ private startNewLineBefore;
107
+ private editLines;
108
+ private editSource;
109
+ private bracketIndex;
110
+ private deleteCharacter;
111
+ private isEmptyPair;
112
+ private backspaceStart;
113
+ private deleteRanges;
114
+ private applySelectionEdits;
115
+ private newlineAt;
116
+ private escaped;
117
+ private typingContext;
118
+ private isInterpolation;
119
+ private semicolonTarget;
120
+ wordSelectionAt(offset: number, camel?: boolean): {
121
+ from: number;
122
+ to: number;
123
+ } | null;
124
+ private identifierRunAt;
125
+ wordStartBefore(offset: number, camel?: boolean): number;
126
+ wordEndAfter(offset: number, camel?: boolean): number;
127
+ private isBetweenBrackets;
128
+ private wordRange;
129
+ private expandSelection;
130
+ expandSelectionTo(ranges: readonly (OffsetRange | null)[]): boolean;
131
+ private largerRange;
132
+ private lexicalExpansion;
133
+ private shrinkSelection;
134
+ private occurrenceSignature;
135
+ private repeatedOccurrence;
136
+ private rememberOccurrence;
137
+ private overlapsSelection;
138
+ private selectNextOccurrence;
139
+ private unselectOccurrence;
140
+ private selectAllOccurrences;
141
+ private addCaretPerSelectedLine;
142
+ private changeSelections;
143
+ private structure;
144
+ private state;
145
+ private invalidate;
146
+ private restore;
147
+ private emit;
148
+ }