lineEdit.ts ×27

Frontier kind: Code frontier

unlabeled · c_80f039aece05

866 tests · 6708 LOC · 38 files · introduces 0 tests · 95 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
27 ranges95 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1098 ranges6708 lines · 38 files · Browse complete extent
All tests (intent)
866 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 95 introduced LOC across 27 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/editor/common/core/edits/lineEdit.ts 95 introduced LOC · 27 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- lineEdit.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { compareBy, groupAdjacentBy, numberComparator } from '../../../../base/common/arrays.js';
7 > import { assert, checkAdjacentItems } from '../../../../base/common/assert.js';
8 > import { splitLines } from '../../../../base/common/strings.js';
9 > import { LineRange } from '../ranges/lineRange.js';
10 > import { BaseStringEdit, StringEdit, StringReplacement } from './stringEdit.js';
11 > import { Position } from '../position.js';
12 > import { Range } from '../range.js';
13 > import { TextReplacement, TextEdit } from './textEdit.js';
14 > import { AbstractText } from '../text/abstractText.js';
15 >
16 > export class LineEdit {
17 > public static readonly empty = new LineEdit([]);
18 >
19 > public static deserialize(data: SerializedLineEdit): LineEdit {
20 return new LineEdit(data.map(e => LineReplacement.deserialize(e)));
21 }
23 > public static fromStringEdit(edit: BaseStringEdit, initialValue: AbstractText): LineEdit {
24 const textEdit = TextEdit.fromStringEdit(edit, initialValue);
25 return LineEdit.fromTextEdit(textEdit, initialValue);
26 }
28 > public static fromTextEdit(edit: TextEdit, initialValue: AbstractText): LineEdit {
29 const edits = edit.replacements;
30
49 return new LineEdit(result);
50 }
52 > public static createFromUnsorted(edits: readonly LineReplacement[]): LineEdit {
53 const result = edits.slice();
54 result.sort(compareBy(i => i.lineRange.startLineNumber, numberComparator));
55 return new LineEdit(result);
56 }
58 > constructor(
59 > /**
60 > * Have to be sorted by start line number and non-intersecting.
61 > */
62 > public readonly replacements: readonly LineReplacement[]
63 > ) {
64 > assert(checkAdjacentItems(replacements, (i1, i2) => i1.lineRange.endLineNumberExclusive <= i2.lineRange.startLineNumber));
65 > }
66 >
67 > public isEmpty(): boolean {
68 return this.replacements.length === 0;
69 }
71 > public toEdit(initialValue: AbstractText): StringEdit {
72 const edits: StringReplacement[] = [];
73 for (const edit of this.replacements) {
77 return new StringEdit(edits);
78 }
80 > public toString(): string {
81 return this.replacements.map(e => e.toString()).join(',');
82 }
84 > public serialize(): SerializedLineEdit {
85 return this.replacements.map(e => e.serialize());
86 }
88 > public getNewLineRanges(): LineRange[] {
89 const ranges: LineRange[] = [];
90 let offset = 0;
95 return ranges;
96 }
98 > public mapLineNumber(lineNumber: number): number {
99 let lineDelta = 0;
100 for (const e of this.replacements) {
107 return lineNumber + lineDelta;
108 }
109 > lineEdit.ts
110 > public mapLineRange(lineRange: LineRange): LineRange {
111 return new LineRange(
112 this.mapLineNumber(lineRange.startLineNumber),
114 );
115 }
116 > lineEdit.ts
117 >
118 > /** TODO improve, dont require originalLines */
119 > public mapBackLineRange(lineRange: LineRange, originalLines: string[]): LineRange {
120 const i = this.inverse(originalLines);
121 return i.mapLineRange(lineRange);
122 }
123 > lineEdit.ts
124 > public touches(other: LineEdit): boolean {
125 return this.replacements.some(e1 => other.replacements.some(e2 => e1.lineRange.intersect(e2.lineRange)));
126 }
127 > lineEdit.ts
128 > public rebase(base: LineEdit): LineEdit {
129 return new LineEdit(
130 this.replacements.map(e => new LineReplacement(base.mapLineRange(e.lineRange), e.newLines)),
131 );
132 }
133 > lineEdit.ts
134 > public humanReadablePatch(originalLines: string[]): string {
135 const result: string[] = [];
136
192 return result.join('\n');
193 }
194 > lineEdit.ts
195 > public apply(lines: string[]): string[] {
196 const result: string[] = [];
197
218 return result;
219 }
220 > lineEdit.ts
221 > public inverse(originalLines: string[]): LineEdit {
222 const newRanges = this.getNewLineRanges();
223 return new LineEdit(this.replacements.map((e, idx) => new LineReplacement(
226 )));
227 }
228 > } lineEdit.ts
229 >
230 > export class LineReplacement {
231 > public static deserialize(e: SerializedLineReplacement): LineReplacement {
232 > return new LineReplacement(
233 > LineRange.ofLength(e[0], e[1] - e[0]),
234 > e[2],
235 > );
236 > }
237 >
238 > public static fromSingleTextEdit(edit: TextReplacement, initialValue: AbstractText): LineReplacement {
239 // 1: ab[cde
240 // 2: fghijk
284 return new LineReplacement(new LineRange(startLineNumber, endLineNumberEx), newLines);
285 }
286 > lineEdit.ts
287 > constructor(
288 public readonly lineRange: LineRange,
289 public readonly newLines: readonly string[],
290 ) { }
291 > lineEdit.ts
292 > public toSingleTextEdit(initialValue: AbstractText): TextReplacement {
293 if (this.newLines.length === 0) {
294 // Deletion
344 }
345 }
346 > lineEdit.ts
347 > public toSingleEdit(initialValue: AbstractText): StringReplacement {
348 const textEdit = this.toSingleTextEdit(initialValue);
349 const range = initialValue.getTransformer().getOffsetRange(textEdit.range);
350 return new StringReplacement(range, textEdit.text);
351 }
352 > lineEdit.ts
353 > public toString(): string {
354 return `${this.lineRange}->${JSON.stringify(this.newLines)}`;
355 }
356 > lineEdit.ts
357 > public serialize(): SerializedLineReplacement {
358 return [
359 this.lineRange.startLineNumber,
362 ];
363 }
364 > lineEdit.ts
365 > public removeCommonSuffixPrefixLines(initialValue: AbstractText): LineReplacement {
366 let startLineNumber = this.lineRange.startLineNumber;
367 let endLineNumberEx = this.lineRange.endLineNumberExclusive;
390 return new LineReplacement(new LineRange(startLineNumber, endLineNumberEx), this.newLines.slice(trimStartCount, this.newLines.length - trimEndCount));
391 }
392 > lineEdit.ts
393 > public toLineEdit(): LineEdit {
394 return new LineEdit([this]);
395 }
396 > } lineEdit.ts
397 >
398 > export type SerializedLineEdit = SerializedLineReplacement[];
399 > export type SerializedLineReplacement = [startLineNumber: number, endLineNumber: number, newLines: readonly string[]];
400 >
401 > export namespace SerializedLineReplacement {
402 > export function is(thing: unknown): thing is SerializedLineReplacement {
403 return (
404 Array.isArray(thing)