1 | import { ReadStream, WriteStream } from "fs";
|
2 | import {
|
3 | Disposable,
|
4 | FileSavedEvent,
|
5 | HandleableErrorEvent,
|
6 | HistoryTransactionOptions,
|
7 | HistoryTraversalOptions,
|
8 | TextEditOptions,
|
9 | } from "../../../index";
|
10 | import {
|
11 | FindMarkerOptions,
|
12 | Marker,
|
13 | MarkerLayer,
|
14 | Point,
|
15 | PointCompatible,
|
16 | Range,
|
17 | RangeCompatible,
|
18 | TextChange,
|
19 | } from "./text-buffer";
|
20 |
|
21 | export * from "./display-marker";
|
22 | export * from "./display-marker-layer";
|
23 | export * from "./helpers";
|
24 | export * from "./marker";
|
25 | export * from "./marker-layer";
|
26 | export * from "./point";
|
27 | export * from "./range";
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | export class TextBuffer {
|
34 |
|
35 | readonly id: string;
|
36 |
|
37 |
|
38 | readonly refcount: number;
|
39 |
|
40 |
|
41 | readonly destroyed: boolean;
|
42 |
|
43 |
|
44 | static load(filePath: string | TextBufferFileBackend, params?: BufferLoadOptions): Promise<TextBuffer>;
|
45 |
|
46 | |
47 |
|
48 |
|
49 |
|
50 | static loadSync(filePath: string, params?: BufferLoadOptions): TextBuffer;
|
51 |
|
52 | |
53 |
|
54 |
|
55 |
|
56 | static deserialize(params: object): Promise<TextBuffer>;
|
57 |
|
58 |
|
59 | constructor(text: string);
|
60 | /** Create a new buffer with the given params. */
|
61 | constructor(params?: {
|
62 |
|
63 | text?: string | undefined;
|
64 | |
65 |
|
66 |
|
67 |
|
68 | shouldDestroyOnFileDelete?(): boolean;
|
69 | });
|
70 |
|
71 | /** Returns a plain javascript object representation of the TextBuffer. */
|
72 | serialize(options?: { markerLayers?: boolean | undefined; history?: boolean | undefined }): object;
|
73 |
|
74 | /** Returns the unique identifier for this buffer. */
|
75 | getId(): string;
|
76 |
|
77 | // Event Subscription
|
78 | /**
|
79 | * Invoke the given callback synchronously before the content of the buffer
|
80 | * changes.
|
81 | */
|
82 | onWillChange(callback: (event: BufferChangingEvent) => void): Disposable;
|
83 |
|
84 | /**
|
85 | * Invoke the given callback synchronously when the content of the buffer
|
86 | * changes. You should probably not be using this in packages.
|
87 | */
|
88 | onDidChange(callback: (event: BufferChangedEvent) => void): Disposable;
|
89 |
|
90 | /**
|
91 | * Invoke the given callback synchronously when a transaction finishes with
|
92 | * a list of all the changes in the transaction.
|
93 | */
|
94 | onDidChangeText(callback: (event: BufferStoppedChangingEvent) => void): Disposable;
|
95 |
|
96 | /**
|
97 | * Invoke the given callback asynchronously following one or more changes after
|
98 | * ::getStoppedChangingDelay milliseconds elapse without an additional change.
|
99 | */
|
100 | onDidStopChanging(callback: (event: BufferStoppedChangingEvent) => void): Disposable;
|
101 |
|
102 | /**
|
103 | * Invoke the given callback when the in-memory contents of the buffer become
|
104 | * in conflict with the contents of the file on disk.
|
105 | */
|
106 | onDidConflict(callback: () => void): Disposable;
|
107 |
|
108 | /** Invoke the given callback if the value of ::isModified changes. */
|
109 | onDidChangeModified(callback: (modified: boolean) => void): Disposable;
|
110 |
|
111 | /**
|
112 | * Invoke the given callback when all marker ::onDidChange observers have been
|
113 | * notified following a change to the buffer.
|
114 | */
|
115 | onDidUpdateMarkers(callback: () => void): Disposable;
|
116 |
|
117 | onDidCreateMarker(callback: (marker: Marker) => void): Disposable;
|
118 |
|
119 | /** Invoke the given callback when the value of ::getPath changes. */
|
120 | onDidChangePath(callback: (path: string) => void): Disposable;
|
121 |
|
122 | /** Invoke the given callback when the value of ::getEncoding changes. */
|
123 | onDidChangeEncoding(callback: (encoding: string) => void): Disposable;
|
124 |
|
125 | /**
|
126 | * Invoke the given callback before the buffer is saved to disk. If the
|
127 | * given callback returns a promise, then the buffer will not be saved until
|
128 | * the promise resolves.
|
129 | */
|
130 | onWillSave(callback: () => Promise<void> | void): Disposable;
|
131 |
|
132 | /** Invoke the given callback after the buffer is saved to disk. */
|
133 | onDidSave(callback: (event: FileSavedEvent) => void): Disposable;
|
134 |
|
135 | /** Invoke the given callback after the file backing the buffer is deleted. */
|
136 | onDidDelete(callback: () => void): Disposable;
|
137 |
|
138 | /**
|
139 | * Invoke the given callback before the buffer is reloaded from the contents
|
140 | * of its file on disk.
|
141 | */
|
142 | onWillReload(callback: () => void): Disposable;
|
143 |
|
144 | /**
|
145 | * Invoke the given callback after the buffer is reloaded from the contents
|
146 | * of its file on disk.
|
147 | */
|
148 | onDidReload(callback: () => void): Disposable;
|
149 |
|
150 | /** Invoke the given callback when the buffer is destroyed. */
|
151 | onDidDestroy(callback: () => void): Disposable;
|
152 |
|
153 | /** Invoke the given callback when there is an error in watching the file. */
|
154 | onWillThrowWatchError(callback: (errorObject: HandleableErrorEvent) => void): Disposable;
|
155 |
|
156 | /**
|
157 | * Get the number of milliseconds that will elapse without a change before
|
158 | * ::onDidStopChanging observers are invoked following a change.
|
159 | */
|
160 | getStoppedChangingDelay(): number;
|
161 |
|
162 | // File Details
|
163 | /**
|
164 | * Determine if the in-memory contents of the buffer differ from its contents
|
165 | * on disk.
|
166 | * If the buffer is unsaved, always returns true unless the buffer is empty.
|
167 | */
|
168 | isModified(): boolean;
|
169 |
|
170 | /**
|
171 | * Determine if the in-memory contents of the buffer conflict with the on-disk
|
172 | * contents of its associated file.
|
173 | */
|
174 | isInConflict(): boolean;
|
175 |
|
176 | /** Get the path of the associated file. */
|
177 | getPath(): string | undefined;
|
178 |
|
179 | /** Set the path for the buffer's associated file. */
|
180 | setPath(filePath: string): void;
|
181 |
|
182 | /** Experimental: Set a custom {TextBufferFileBackend} object as the buffer's backing store. */
|
183 | setFile(fileBackend: TextBufferFileBackend): void;
|
184 |
|
185 | /** Sets the character set encoding for this buffer. */
|
186 | setEncoding(encoding: string): void;
|
187 |
|
188 | /** Returns the string encoding of this buffer. */
|
189 | getEncoding(): string;
|
190 |
|
191 | /** Get the path of the associated file. */
|
192 | getUri(): string;
|
193 |
|
194 | // Reading Text
|
195 | /** Determine whether the buffer is empty. */
|
196 | isEmpty(): boolean;
|
197 |
|
198 | /**
|
199 | * Get the entire text of the buffer. Avoid using this unless you know that
|
200 | * the buffer's text is reasonably short.
|
201 | */
|
202 | getText(): string;
|
203 |
|
204 | /** Get the text in a range. */
|
205 | getTextInRange(range: RangeCompatible): string;
|
206 |
|
207 | /** Get the text of all lines in the buffer, without their line endings. */
|
208 | getLines(): string[];
|
209 |
|
210 | /** Get the text of the last line of the buffer, without its line ending. */
|
211 | getLastLine(): string;
|
212 |
|
213 | /**
|
214 | * Get the text of the line at the given 0-indexed row, without its line ending.
|
215 | * @param row A number representing the row.
|
216 | */
|
217 | lineForRow(row: number): string | undefined;
|
218 |
|
219 | /** Get the line ending for the given 0-indexed row. */
|
220 | lineEndingForRow(row: number): string | undefined;
|
221 |
|
222 | /**
|
223 | * Get the length of the line for the given 0-indexed row, without its line
|
224 | * ending.
|
225 | */
|
226 | lineLengthForRow(row: number): number;
|
227 |
|
228 | /** Determine if the given row contains only whitespace. */
|
229 | isRowBlank(row: number): boolean;
|
230 |
|
231 | /**
|
232 | * Given a row, find the first preceding row that's not blank.
|
233 | * Returns a number or null if there's no preceding non-blank row.
|
234 | */
|
235 | previousNonBlankRow(startRow: number): number | null;
|
236 |
|
237 | /**
|
238 | * Given a row, find the next row that's not blank.
|
239 | * Returns a number or null if there's no next non-blank row.
|
240 | */
|
241 | nextNonBlankRow(startRow: number): number | null;
|
242 |
|
243 | /**
|
244 | * Return true if the buffer contains any astral-plane Unicode characters that
|
245 | * are encoded as surrogate pairs.
|
246 | */
|
247 | hasAstral(): boolean;
|
248 |
|
249 | // Mutating Text
|
250 | /** Replace the entire contents of the buffer with the given text. */
|
251 | setText(text: string): Range;
|
252 |
|
253 | /**
|
254 | * Replace the current buffer contents by applying a diff based on the
|
255 | * given text.
|
256 | */
|
257 | setTextViaDiff(text: string): void;
|
258 |
|
259 | /** Set the text in the given range. */
|
260 | setTextInRange(range: RangeCompatible, text: string, options?: TextEditOptions): Range;
|
261 |
|
262 | /** Insert text at the given position. */
|
263 | insert(position: PointCompatible, text: string, options?: TextEditOptions): Range;
|
264 |
|
265 | /** Append text to the end of the buffer. */
|
266 | append(text: string, options?: TextEditOptions): Range;
|
267 |
|
268 | /** Delete the text in the given range. */
|
269 | delete(range: RangeCompatible): Range;
|
270 |
|
271 | /**
|
272 | * Delete the line associated with a specified 0-indexed row.
|
273 | * @param row A number representing the row to delete.
|
274 | */
|
275 | deleteRow(row: number): Range;
|
276 |
|
277 | /**
|
278 | * Delete the lines associated with the specified 0-indexed row range.
|
279 | *
|
280 | * If the row range is out of bounds, it will be clipped. If the `startRow`
|
281 | * is greater than the `endRow`, they will be reordered.
|
282 | */
|
283 | deleteRows(startRow: number, endRow: number): Range;
|
284 |
|
285 | // Markers
|
286 | /** Create a layer to contain a set of related markers. */
|
287 | addMarkerLayer(
|
288 | options?: {
|
289 | maintainHistory?: boolean | undefined;
|
290 | persistent?: boolean | undefined;
|
291 | role?: string | undefined;
|
292 | },
|
293 | ): MarkerLayer;
|
294 |
|
295 | /**
|
296 | * Get a MarkerLayer by id.
|
297 | * Returns a MarkerLayer or undefined if no layer exists with the given id.
|
298 | */
|
299 | getMarkerLayer(id: string): MarkerLayer | undefined;
|
300 |
|
301 | /** Get the default MarkerLayer. */
|
302 | getDefaultMarkerLayer(): MarkerLayer;
|
303 |
|
304 | /** Create a marker with the given range in the default marker layer. */
|
305 | markRange(
|
306 | range: RangeCompatible,
|
307 | properties?: {
|
308 | reversed?: boolean | undefined;
|
309 | invalidate?: "never" | "surround" | "overlap" | "inside" | "touch" | undefined;
|
310 | exclusive?: boolean | undefined;
|
311 | },
|
312 | ): Marker;
|
313 |
|
314 | /** Create a marker at the given position with no tail in the default marker layer. */
|
315 | markPosition(
|
316 | position: PointCompatible,
|
317 | options?: {
|
318 | invalidate?: "never" | "surround" | "overlap" | "inside" | "touch" | undefined;
|
319 | exclusive?: boolean | undefined;
|
320 | },
|
321 | ): Marker;
|
322 |
|
323 | /** Get all existing markers on the default marker layer. */
|
324 | getMarkers(): Marker[];
|
325 |
|
326 | /** Get an existing marker by its id from the default marker layer. */
|
327 | getMarker(id: number): Marker;
|
328 |
|
329 | /** Find markers conforming to the given parameters in the default marker layer. */
|
330 | findMarkers(params: FindMarkerOptions): Marker[];
|
331 |
|
332 | /** Get the number of markers in the default marker layer. */
|
333 | getMarkerCount(): number;
|
334 |
|
335 | // History
|
336 | /**
|
337 | * Undo the last operation. If a transaction is in progress, aborts it.
|
338 | * @return A boolean of whether or not a change was made.
|
339 | */
|
340 | undo(options?: HistoryTraversalOptions): boolean;
|
341 |
|
342 | /**
|
343 | * Redo the last operation.
|
344 | * @return A boolean of whether or not a change was made.
|
345 | */
|
346 | redo(options?: HistoryTraversalOptions): boolean;
|
347 |
|
348 | /** Batch multiple operations as a single undo/redo step. */
|
349 | transact<T>(
|
350 | optionsOrInterval: number | ({ groupingInterval?: number | undefined } & HistoryTransactionOptions),
|
351 | fn: () => T,
|
352 | ): T;
|
353 | /** Batch multiple operations as a single undo/redo step. */
|
354 | transact<T>(fn: () => T): T;
|
355 |
|
356 | /**
|
357 | * Abort the currently running transaction.
|
358 | *
|
359 | * Only intended to be called within the `fn` option to `::transact`.
|
360 | */
|
361 | abortTransaction(): void;
|
362 |
|
363 | /** Clear the undo stack. */
|
364 | clearUndoStack(): void;
|
365 |
|
366 | /**
|
367 | * Create a pointer to the current state of the buffer for use with
|
368 | * `::revertToCheckpoint` and `::groupChangesSinceCheckpoint`.
|
369 | * @return A checkpoint ID value.
|
370 | */
|
371 | createCheckpoint(options?: HistoryTransactionOptions): number;
|
372 |
|
373 | /**
|
374 | * Revert the buffer to the state it was in when the given checkpoint was created.
|
375 | * @return A boolean indicating whether the operation succeeded.
|
376 | */
|
377 | revertToCheckpoint(checkpoint: number, options?: HistoryTraversalOptions): boolean;
|
378 |
|
379 | /**
|
380 | * Group all changes since the given checkpoint into a single transaction for
|
381 | * purposes of undo/redo.
|
382 | * @return A boolean indicating whether the operation succeeded.
|
383 | */
|
384 | groupChangesSinceCheckpoint(checkpoint: number, options?: HistoryTransactionOptions): boolean;
|
385 |
|
386 | /**
|
387 | * Group the last two text changes for purposes of undo/redo.
|
388 | *
|
389 | * This operation will only succeed if there are two changes on the undo stack.
|
390 | * It will not group past the beginning of an open transaction.
|
391 | * @return A boolean indicating whether the operation succeeded.
|
392 | */
|
393 | groupLastChanges(): boolean;
|
394 |
|
395 | /**
|
396 | * Returns a list of changes since the given checkpoint.
|
397 | * If the given checkpoint is no longer present in the undo history, this method
|
398 | * will return an empty Array.
|
399 | */
|
400 | getChangesSinceCheckpoint(
|
401 | checkpoint: number,
|
402 | ): Array<{
|
403 |
|
404 | start: Point;
|
405 |
|
406 |
|
407 | oldExtent: Point;
|
408 |
|
409 |
|
410 | newExtent: Point;
|
411 |
|
412 |
|
413 | newText: string;
|
414 | }>;
|
415 |
|
416 |
|
417 | |
418 |
|
419 |
|
420 |
|
421 | scan(regex: RegExp, iterator: (params: BufferScanResult) => void): void;
|
422 | |
423 |
|
424 |
|
425 |
|
426 | scan(regex: RegExp, options: ScanContextOptions, iterator: (params: ContextualBufferScanResult) => void): void;
|
427 |
|
428 | |
429 |
|
430 |
|
431 |
|
432 | backwardsScan(regex: RegExp, iterator: (params: BufferScanResult) => void): void;
|
433 | |
434 |
|
435 |
|
436 |
|
437 | backwardsScan(
|
438 | regex: RegExp,
|
439 | options: ScanContextOptions,
|
440 | iterator: (params: ContextualBufferScanResult) => void,
|
441 | ): void;
|
442 |
|
443 | |
444 |
|
445 |
|
446 |
|
447 | scanInRange(regex: RegExp, range: RangeCompatible, iterator: (params: BufferScanResult) => void): void;
|
448 | |
449 |
|
450 |
|
451 |
|
452 | scanInRange(
|
453 | regex: RegExp,
|
454 | range: RangeCompatible,
|
455 | options: ScanContextOptions,
|
456 | iterator: (params: ContextualBufferScanResult) => void,
|
457 | ): void;
|
458 |
|
459 | |
460 |
|
461 |
|
462 |
|
463 | backwardsScanInRange(regex: RegExp, range: RangeCompatible, iterator: (params: BufferScanResult) => void): void;
|
464 | |
465 |
|
466 |
|
467 |
|
468 | backwardsScanInRange(
|
469 | regex: RegExp,
|
470 | range: RangeCompatible,
|
471 | options: ScanContextOptions,
|
472 | iterator: (params: ContextualBufferScanResult) => void,
|
473 | ): void;
|
474 |
|
475 |
|
476 | replace(regex: RegExp, replacementText: string): number;
|
477 |
|
478 |
|
479 |
|
480 | getRange(): Range;
|
481 |
|
482 |
|
483 | getLineCount(): number;
|
484 |
|
485 |
|
486 | getLastRow(): number;
|
487 |
|
488 |
|
489 | getFirstPosition(): Point;
|
490 |
|
491 |
|
492 | getEndPosition(): Point;
|
493 |
|
494 |
|
495 | getLength(): number;
|
496 |
|
497 |
|
498 | getMaxCharacterIndex(): number;
|
499 |
|
500 | |
501 |
|
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 | rangeForRow(row: number, includeNewline?: boolean): Range;
|
508 |
|
509 | |
510 |
|
511 |
|
512 |
|
513 | characterIndexForPosition(position: PointCompatible): number;
|
514 |
|
515 | |
516 |
|
517 |
|
518 |
|
519 | positionForCharacterIndex(offset: number): Point;
|
520 |
|
521 |
|
522 | clipRange(range: RangeCompatible): Range;
|
523 |
|
524 |
|
525 | clipPosition(position: PointCompatible): Point;
|
526 |
|
527 |
|
528 |
|
529 | save(): Promise<void>;
|
530 |
|
531 |
|
532 | saveAs(filePath: string): Promise<void>;
|
533 |
|
534 |
|
535 | reload(): void;
|
536 |
|
537 |
|
538 | destroy(): void;
|
539 |
|
540 |
|
541 | isAlive(): boolean;
|
542 |
|
543 |
|
544 | isDestroyed(): boolean;
|
545 |
|
546 |
|
547 | isRetained(): boolean;
|
548 |
|
549 | |
550 |
|
551 |
|
552 |
|
553 | retain(): TextBuffer;
|
554 |
|
555 | |
556 |
|
557 |
|
558 |
|
559 | release(): TextBuffer;
|
560 |
|
561 |
|
562 | hasMultipleEditors(): boolean;
|
563 | }
|
564 |
|
565 | export interface TextBufferFileBackend {
|
566 |
|
567 | getPath(): string;
|
568 |
|
569 | |
570 |
|
571 |
|
572 |
|
573 | createReadStream(): ReadStream;
|
574 |
|
575 | |
576 |
|
577 |
|
578 |
|
579 | createWriteStream(): WriteStream;
|
580 |
|
581 |
|
582 | existsSync(): boolean;
|
583 |
|
584 | |
585 |
|
586 |
|
587 |
|
588 |
|
589 | onDidChange?(callback: () => void): Disposable;
|
590 |
|
591 | /**
|
592 | * A {Function} that invokes its callback argument
|
593 | * when the file is deleted. The method should return a {Disposable} that
|
594 | * can be used to prevent further calls to the callback.
|
595 | */
|
596 | onDidDelete?(callback: () => void): Disposable;
|
597 | /**
|
598 | * A {Function} that invokes its callback argument
|
599 | * when the file is renamed. The method should return a {Disposable} that
|
600 | * can be used to prevent further calls to the callback.
|
601 | */
|
602 | onDidRename?(callback: () => void): Disposable;
|
603 | }
|
604 |
|
605 | export interface BufferChangingEvent {
|
606 | /** Range of the old text. */
|
607 | oldRange: Range;
|
608 | }
|
609 |
|
610 | export interface BufferChangedEvent {
|
611 | /**
|
612 | * An array of objects summarizing the aggregated changes that occurred
|
613 | * during the transaction.
|
614 | */
|
615 | changes: Array<{
|
616 | /**
|
617 | * The Range of the deleted text in the contents of the buffer as it existed
|
618 | * before the batch of changes reported by this event.
|
619 | */
|
620 | oldRange: Range;
|
621 |
|
622 | /** The Range of the inserted text in the current contents of the buffer. */
|
623 | newRange: Range;
|
624 | }>;
|
625 |
|
626 | /** Range of the old text. */
|
627 | oldRange: Range;
|
628 |
|
629 | /** Range of the new text. */
|
630 | newRange: Range;
|
631 |
|
632 | /** String containing the text that was replaced. */
|
633 | oldText: string;
|
634 |
|
635 | /** String containing the text that was inserted. */
|
636 | newText: string;
|
637 | }
|
638 |
|
639 | export interface BufferStoppedChangingEvent {
|
640 | changes: TextChange[];
|
641 | }
|
642 |
|
643 | export interface BufferLoadOptions {
|
644 | /** The file's encoding. */
|
645 | encoding?: string | undefined;
|
646 |
|
647 | /**
|
648 | * A function that returns a boolean indicating whether the buffer should
|
649 | * be destroyed if its file is deleted.
|
650 | */
|
651 | shouldDestroyOnFileDelete?(): boolean;
|
652 | }
|
653 |
|
654 | export interface BufferScanResult {
|
655 | buffer: TextBuffer;
|
656 | lineText: string;
|
657 | match: RegExpExecArray;
|
658 | matchText: string;
|
659 | range: Range;
|
660 | replace(replacementText: string): void;
|
661 | stop(): void;
|
662 | stopped: boolean;
|
663 | }
|
664 |
|
665 | export interface ContextualBufferScanResult extends BufferScanResult {
|
666 | leadingContextLines: string[];
|
667 | trailingContextLines: string[];
|
668 | }
|
669 |
|
670 | export interface ScanContextOptions {
|
671 | /** The number of lines before the matched line to include in the results object. */
|
672 | leadingContextLineCount?: number | undefined;
|
673 |
|
674 | /** The number of lines after the matched line to include in the results object. */
|
675 | trailingContextLineCount?: number | undefined;
|
676 | }
|
677 |
|
\ | No newline at end of file |