Skip to content

Commit 9caab0b

Browse files
authored
Merge pull request microsoft#90950 from bolinfest/patch-1
Define IIdentifiedSingleEditOperation.range as IRange instead of Range
2 parents 618db14 + 89eb9fe commit 9caab0b

14 files changed

Lines changed: 158 additions & 76 deletions

File tree

src/vs/editor/common/controller/cursor.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import { DeleteOperations } from 'vs/editor/common/controller/cursorDeleteOperat
1212
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
1313
import { TypeOperations, TypeWithAutoClosingCommand } from 'vs/editor/common/controller/cursorTypeOperations';
1414
import { Position } from 'vs/editor/common/core/position';
15-
import { Range } from 'vs/editor/common/core/range';
15+
import { Range, IRange } from 'vs/editor/common/core/range';
1616
import { ISelection, Selection, SelectionDirection } from 'vs/editor/common/core/selection';
1717
import * as editorCommon from 'vs/editor/common/editorCommon';
18-
import { IIdentifiedSingleEditOperation, ITextModel, TrackedRangeStickiness, IModelDeltaDecoration, ICursorStateComputer } from 'vs/editor/common/model';
18+
import { ITextModel, TrackedRangeStickiness, IModelDeltaDecoration, ICursorStateComputer, IIdentifiedSingleEditOperation, IValidEditOperation } from 'vs/editor/common/model';
1919
import { RawContentChangedType } from 'vs/editor/common/model/textModelEvents';
2020
import * as viewEvents from 'vs/editor/common/view/viewEvents';
2121
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
@@ -903,8 +903,8 @@ class CommandExecutor {
903903
if (commandsData.hadTrackedEditOperation && filteredOperations.length > 0) {
904904
filteredOperations[0]._isTracked = true;
905905
}
906-
let selectionsAfter = ctx.model.pushEditOperations(ctx.selectionsBefore, filteredOperations, (inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] => {
907-
let groupedInverseEditOperations: IIdentifiedSingleEditOperation[][] = [];
906+
let selectionsAfter = ctx.model.pushEditOperations(ctx.selectionsBefore, filteredOperations, (inverseEditOperations: IValidEditOperation[]): Selection[] => {
907+
let groupedInverseEditOperations: IValidEditOperation[][] = [];
908908
for (let i = 0; i < ctx.selectionsBefore.length; i++) {
909909
groupedInverseEditOperations[i] = [];
910910
}
@@ -915,7 +915,7 @@ class CommandExecutor {
915915
}
916916
groupedInverseEditOperations[op.identifier.major].push(op);
917917
}
918-
const minorBasedSorter = (a: IIdentifiedSingleEditOperation, b: IIdentifiedSingleEditOperation) => {
918+
const minorBasedSorter = (a: IValidEditOperation, b: IValidEditOperation) => {
919919
return a.identifier!.minor - b.identifier!.minor;
920920
};
921921
let cursorSelections: Selection[] = [];
@@ -1000,8 +1000,8 @@ class CommandExecutor {
10001000
let operations: IIdentifiedSingleEditOperation[] = [];
10011001
let operationMinor = 0;
10021002

1003-
const addEditOperation = (selection: Range, text: string | null, forceMoveMarkers: boolean = false) => {
1004-
if (selection.isEmpty() && text === '') {
1003+
const addEditOperation = (range: IRange, text: string | null, forceMoveMarkers: boolean = false) => {
1004+
if (Range.isEmpty(range) && text === '') {
10051005
// This command wants to add a no-op => no thank you
10061006
return;
10071007
}
@@ -1010,20 +1010,21 @@ class CommandExecutor {
10101010
major: majorIdentifier,
10111011
minor: operationMinor++
10121012
},
1013-
range: selection,
1013+
range: range,
10141014
text: text,
10151015
forceMoveMarkers: forceMoveMarkers,
10161016
isAutoWhitespaceEdit: command.insertsAutoWhitespace
10171017
});
10181018
};
10191019

10201020
let hadTrackedEditOperation = false;
1021-
const addTrackedEditOperation = (selection: Range, text: string | null, forceMoveMarkers?: boolean) => {
1021+
const addTrackedEditOperation = (selection: IRange, text: string | null, forceMoveMarkers?: boolean) => {
10221022
hadTrackedEditOperation = true;
10231023
addEditOperation(selection, text, forceMoveMarkers);
10241024
};
10251025

1026-
const trackSelection = (selection: Selection, trackPreviousOnEmpty?: boolean) => {
1026+
const trackSelection = (_selection: ISelection, trackPreviousOnEmpty?: boolean) => {
1027+
const selection = Selection.liftSelection(_selection);
10271028
let stickiness: TrackedRangeStickiness;
10281029
if (selection.isEmpty()) {
10291030
if (typeof trackPreviousOnEmpty === 'boolean') {
@@ -1093,7 +1094,7 @@ class CommandExecutor {
10931094
const previousOp = operations[i - 1];
10941095
const currentOp = operations[i];
10951096

1096-
if (previousOp.range.getStartPosition().isBefore(currentOp.range.getEndPosition())) {
1097+
if (Range.getStartPosition(previousOp.range).isBefore(Range.getEndPosition(currentOp.range))) {
10971098

10981099
let loserMajor: number;
10991100

src/vs/editor/common/core/range.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,28 @@ export class Range {
264264
* Return the end position (which will be after or equal to the start position)
265265
*/
266266
public getEndPosition(): Position {
267-
return new Position(this.endLineNumber, this.endColumn);
267+
return Range.getEndPosition(this);
268+
}
269+
270+
/**
271+
* Return the end position (which will be after or equal to the start position)
272+
*/
273+
public static getEndPosition(range: IRange): Position {
274+
return new Position(range.endLineNumber, range.endColumn);
268275
}
269276

270277
/**
271278
* Return the start position (which will be before or equal to the end position)
272279
*/
273280
public getStartPosition(): Position {
274-
return new Position(this.startLineNumber, this.startColumn);
281+
return Range.getStartPosition(this);
282+
}
283+
284+
/**
285+
* Return the start position (which will be before or equal to the end position)
286+
*/
287+
public static getStartPosition(range: IRange): Position {
288+
return new Position(range.startLineNumber, range.startColumn);
275289
}
276290

277291
/**

src/vs/editor/common/editorCommon.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ConfigurationChangedEvent, IComputedEditorOptions, IEditorOptions } fro
1010
import { IPosition, Position } from 'vs/editor/common/core/position';
1111
import { IRange, Range } from 'vs/editor/common/core/range';
1212
import { ISelection, Selection } from 'vs/editor/common/core/selection';
13-
import { IIdentifiedSingleEditOperation, IModelDecorationsChangeAccessor, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
13+
import { IModelDecorationsChangeAccessor, ITextModel, OverviewRulerLane, TrackedRangeStickiness, IValidEditOperation } from 'vs/editor/common/model';
1414
import { ThemeColor } from 'vs/platform/theme/common/themeService';
1515

1616
/**
@@ -22,15 +22,15 @@ export interface IEditOperationBuilder {
2222
* @param range The range to replace (delete). May be empty to represent a simple insert.
2323
* @param text The text to replace with. May be null to represent a simple delete.
2424
*/
25-
addEditOperation(range: Range, text: string | null, forceMoveMarkers?: boolean): void;
25+
addEditOperation(range: IRange, text: string | null, forceMoveMarkers?: boolean): void;
2626

2727
/**
2828
* Add a new edit operation (a replace operation).
2929
* The inverse edits will be accessible in `ICursorStateComputerData.getInverseEditOperations()`
3030
* @param range The range to replace (delete). May be empty to represent a simple insert.
3131
* @param text The text to replace with. May be null to represent a simple delete.
3232
*/
33-
addTrackedEditOperation(range: Range, text: string | null, forceMoveMarkers?: boolean): void;
33+
addTrackedEditOperation(range: IRange, text: string | null, forceMoveMarkers?: boolean): void;
3434

3535
/**
3636
* Track `selection` when applying edit operations.
@@ -51,7 +51,7 @@ export interface ICursorStateComputerData {
5151
/**
5252
* Get the inverse edit operations of the added edit operations.
5353
*/
54-
getInverseEditOperations(): IIdentifiedSingleEditOperation[];
54+
getInverseEditOperations(): IValidEditOperation[];
5555
/**
5656
* Get a previously tracked selection.
5757
* @param id The unique identifier returned by `trackSelection`.

src/vs/editor/common/model.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ export interface IIdentifiedSingleEditOperation {
335335
/**
336336
* The range to replace. This can be empty to emulate a simple insert.
337337
*/
338-
range: Range;
338+
range: IRange;
339339
/**
340340
* The text to replace with. This can be null to emulate a simple delete.
341341
*/
@@ -358,14 +358,35 @@ export interface IIdentifiedSingleEditOperation {
358358
_isTracked?: boolean;
359359
}
360360

361+
export interface IValidEditOperation {
362+
/**
363+
* An identifier associated with this single edit operation.
364+
* @internal
365+
*/
366+
identifier: ISingleEditOperationIdentifier | null;
367+
/**
368+
* The range to replace. This can be empty to emulate a simple insert.
369+
*/
370+
range: Range;
371+
/**
372+
* The text to replace with. This can be null to emulate a simple delete.
373+
*/
374+
text: string | null;
375+
/**
376+
* This indicates that this operation has "insert" semantics.
377+
* i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved.
378+
*/
379+
forceMoveMarkers: boolean;
380+
}
381+
361382
/**
362383
* A callback that can compute the cursor state after applying a series of edit operations.
363384
*/
364385
export interface ICursorStateComputer {
365386
/**
366387
* A callback that can compute the resulting cursors state after some edit operations have been executed.
367388
*/
368-
(inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] | null;
389+
(inverseEditOperations: IValidEditOperation[]): Selection[] | null;
369390
}
370391

371392
export class TextModelResolvedOptions {
@@ -1063,7 +1084,7 @@ export interface ITextModel {
10631084
* @param operations The edit operations.
10641085
* @return The inverse edit operations, that, when applied, will bring the model back to the previous state.
10651086
*/
1066-
applyEdits(operations: IIdentifiedSingleEditOperation[]): IIdentifiedSingleEditOperation[];
1087+
applyEdits(operations: IIdentifiedSingleEditOperation[]): IValidEditOperation[];
10671088

10681089
/**
10691090
* Change the end of line sequence without recording in the undo stack.
@@ -1206,6 +1227,20 @@ export const enum ModelConstants {
12061227
FIRST_LINE_DETECTION_LENGTH_LIMIT = 1000
12071228
}
12081229

1230+
/**
1231+
* @internal
1232+
*/
1233+
export class ValidAnnotatedEditOperation implements IIdentifiedSingleEditOperation {
1234+
constructor(
1235+
public readonly identifier: ISingleEditOperationIdentifier | null,
1236+
public readonly range: Range,
1237+
public readonly text: string | null,
1238+
public readonly forceMoveMarkers: boolean,
1239+
public readonly isAutoWhitespaceEdit: boolean,
1240+
public readonly _isTracked: boolean,
1241+
) { }
1242+
}
1243+
12091244
/**
12101245
* @internal
12111246
*/
@@ -1234,7 +1269,7 @@ export interface ITextBuffer {
12341269
getLineLastNonWhitespaceColumn(lineNumber: number): number;
12351270

12361271
setEOL(newEOL: '\r\n' | '\n'): void;
1237-
applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult;
1272+
applyEdits(rawOperations: ValidAnnotatedEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult;
12381273
findMatchesLineByLine(searchRange: Range, searchData: SearchData, captureMatches: boolean, limitResultCount: number): FindMatch[];
12391274
}
12401275

@@ -1244,7 +1279,7 @@ export interface ITextBuffer {
12441279
export class ApplyEditsResult {
12451280

12461281
constructor(
1247-
public readonly reverseEdits: IIdentifiedSingleEditOperation[],
1282+
public readonly reverseEdits: IValidEditOperation[],
12481283
public readonly changes: IInternalModelContentChange[],
12491284
public readonly trimAutoWhitespaceLineNumbers: number[] | null
12501285
) { }

src/vs/editor/common/model/editStack.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
import { onUnexpectedError } from 'vs/base/common/errors';
77
import { Selection } from 'vs/editor/common/core/selection';
8-
import { EndOfLineSequence, ICursorStateComputer, IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
8+
import { EndOfLineSequence, ICursorStateComputer, IIdentifiedSingleEditOperation, IValidEditOperation } from 'vs/editor/common/model';
99
import { TextModel } from 'vs/editor/common/model/textModel';
1010

1111
interface IEditOperation {
12-
operations: IIdentifiedSingleEditOperation[];
12+
operations: IValidEditOperation[];
1313
}
1414

1515
interface IStackElement {
@@ -174,7 +174,7 @@ export class EditStack {
174174
return stackElement!.afterCursorState;
175175
}
176176

177-
private static _computeCursorState(cursorStateComputer: ICursorStateComputer | null, inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] | null {
177+
private static _computeCursorState(cursorStateComputer: ICursorStateComputer | null, inverseEditOperations: IValidEditOperation[]): Selection[] | null {
178178
try {
179179
return cursorStateComputer ? cursorStateComputer(inverseEditOperations) : null;
180180
} catch (e) {

src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import * as strings from 'vs/base/common/strings';
77
import { Position } from 'vs/editor/common/core/position';
88
import { Range } from 'vs/editor/common/core/range';
9-
import { ApplyEditsResult, EndOfLinePreference, FindMatch, IIdentifiedSingleEditOperation, IInternalModelContentChange, ISingleEditOperationIdentifier, ITextBuffer, ITextSnapshot } from 'vs/editor/common/model';
9+
import { ApplyEditsResult, EndOfLinePreference, FindMatch, IInternalModelContentChange, ISingleEditOperationIdentifier, ITextBuffer, ITextSnapshot, ValidAnnotatedEditOperation, IValidEditOperation } from 'vs/editor/common/model';
1010
import { PieceTreeBase, StringBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase';
1111
import { SearchData } from 'vs/editor/common/model/textModelSearch';
1212

@@ -21,7 +21,7 @@ export interface IValidatedEditOperation {
2121
isAutoWhitespaceEdit: boolean;
2222
}
2323

24-
export interface IReverseSingleEditOperation extends IIdentifiedSingleEditOperation {
24+
export interface IReverseSingleEditOperation extends IValidEditOperation {
2525
sortIndex: number;
2626
}
2727

@@ -201,7 +201,7 @@ export class PieceTreeTextBuffer implements ITextBuffer {
201201
this._pieceTree.setEOL(newEOL);
202202
}
203203

204-
public applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult {
204+
public applyEdits(rawOperations: ValidAnnotatedEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult {
205205
let mightContainRTL = this._mightContainRTL;
206206
let mightContainNonBasicASCII = this._mightContainNonBasicASCII;
207207
let canReduceOperations = true;

src/vs/editor/common/model/textModel.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,18 +1154,40 @@ export class TextModel extends Disposable implements model.ITextModel {
11541154
}
11551155
}
11561156

1157+
private _validateEditOperation(rawOperation: model.IIdentifiedSingleEditOperation): model.ValidAnnotatedEditOperation {
1158+
if (rawOperation instanceof model.ValidAnnotatedEditOperation) {
1159+
return rawOperation;
1160+
}
1161+
return new model.ValidAnnotatedEditOperation(
1162+
rawOperation.identifier || null,
1163+
this.validateRange(rawOperation.range),
1164+
rawOperation.text,
1165+
rawOperation.forceMoveMarkers || false,
1166+
rawOperation.isAutoWhitespaceEdit || false,
1167+
rawOperation._isTracked || false
1168+
);
1169+
}
1170+
1171+
private _validateEditOperations(rawOperations: model.IIdentifiedSingleEditOperation[]): model.ValidAnnotatedEditOperation[] {
1172+
const result: model.ValidAnnotatedEditOperation[] = [];
1173+
for (let i = 0, len = rawOperations.length; i < len; i++) {
1174+
result[i] = this._validateEditOperation(rawOperations[i]);
1175+
}
1176+
return result;
1177+
}
1178+
11571179
public pushEditOperations(beforeCursorState: Selection[], editOperations: model.IIdentifiedSingleEditOperation[], cursorStateComputer: model.ICursorStateComputer | null): Selection[] | null {
11581180
try {
11591181
this._onDidChangeDecorations.beginDeferredEmit();
11601182
this._eventEmitter.beginDeferredEmit();
1161-
return this._pushEditOperations(beforeCursorState, editOperations, cursorStateComputer);
1183+
return this._pushEditOperations(beforeCursorState, this._validateEditOperations(editOperations), cursorStateComputer);
11621184
} finally {
11631185
this._eventEmitter.endDeferredEmit();
11641186
this._onDidChangeDecorations.endDeferredEmit();
11651187
}
11661188
}
11671189

1168-
private _pushEditOperations(beforeCursorState: Selection[], editOperations: model.IIdentifiedSingleEditOperation[], cursorStateComputer: model.ICursorStateComputer | null): Selection[] | null {
1190+
private _pushEditOperations(beforeCursorState: Selection[], editOperations: model.ValidAnnotatedEditOperation[], cursorStateComputer: model.ICursorStateComputer | null): Selection[] | null {
11691191
if (this._options.trimAutoWhitespace && this._trimAutoWhitespaceLines) {
11701192
// Go through each saved line number and insert a trim whitespace edit
11711193
// if it is safe to do so (no conflicts with other edits).
@@ -1238,10 +1260,8 @@ export class TextModel extends Disposable implements model.ITextModel {
12381260
}
12391261

12401262
if (allowTrimLine) {
1241-
editOperations.push({
1242-
range: new Range(trimLineNumber, 1, trimLineNumber, maxLineColumn),
1243-
text: null
1244-
});
1263+
const trimRange = new Range(trimLineNumber, 1, trimLineNumber, maxLineColumn);
1264+
editOperations.push(new model.ValidAnnotatedEditOperation(null, trimRange, null, false, false, false));
12451265
}
12461266

12471267
}
@@ -1252,21 +1272,18 @@ export class TextModel extends Disposable implements model.ITextModel {
12521272
return this._commandManager.pushEditOperation(beforeCursorState, editOperations, cursorStateComputer);
12531273
}
12541274

1255-
public applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IIdentifiedSingleEditOperation[] {
1275+
public applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IValidEditOperation[] {
12561276
try {
12571277
this._onDidChangeDecorations.beginDeferredEmit();
12581278
this._eventEmitter.beginDeferredEmit();
1259-
return this._applyEdits(rawOperations);
1279+
return this._applyEdits(this._validateEditOperations(rawOperations));
12601280
} finally {
12611281
this._eventEmitter.endDeferredEmit();
12621282
this._onDidChangeDecorations.endDeferredEmit();
12631283
}
12641284
}
12651285

1266-
private _applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IIdentifiedSingleEditOperation[] {
1267-
for (let i = 0, len = rawOperations.length; i < len; i++) {
1268-
rawOperations[i].range = this.validateRange(rawOperations[i].range);
1269-
}
1286+
private _applyEdits(rawOperations: model.ValidAnnotatedEditOperation[]): model.IValidEditOperation[] {
12701287

12711288
const oldLineCount = this._buffer.getLineCount();
12721289
const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace);

src/vs/editor/common/services/modelServiceImpl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { URI } from 'vs/base/common/uri';
1111
import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions';
1212
import { EditOperation } from 'vs/editor/common/core/editOperation';
1313
import { Range } from 'vs/editor/common/core/range';
14-
import { DefaultEndOfLine, EndOfLinePreference, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBuffer, ITextBufferFactory, ITextModel, ITextModelCreationOptions } from 'vs/editor/common/model';
14+
import { DefaultEndOfLine, EndOfLinePreference, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBuffer, ITextBufferFactory, ITextModel, ITextModelCreationOptions, IValidEditOperation } from 'vs/editor/common/model';
1515
import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel';
1616
import { IModelLanguageChangedEvent, IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
1717
import { LanguageIdentifier, DocumentSemanticTokensProviderRegistry, DocumentSemanticTokensProvider, SemanticTokensLegend, SemanticTokens, SemanticTokensEdits, TokenMetadata, FontStyle, MetadataConsts } from 'vs/editor/common/modes';
@@ -305,7 +305,7 @@ export class ModelServiceImpl extends Disposable implements IModelService {
305305
model.pushEditOperations(
306306
[],
307307
ModelServiceImpl._computeEdits(model, textBuffer),
308-
(inverseEditOperations: IIdentifiedSingleEditOperation[]) => []
308+
(inverseEditOperations: IValidEditOperation[]) => []
309309
);
310310
model.pushStackElement();
311311
}

src/vs/editor/contrib/comment/blockCommentCommand.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Position } from 'vs/editor/common/core/position';
99
import { Range } from 'vs/editor/common/core/range';
1010
import { Selection } from 'vs/editor/common/core/selection';
1111
import { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
12-
import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model';
12+
import { ITextModel, IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
1313
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
1414

1515
export class BlockCommentCommand implements ICommand {

0 commit comments

Comments
 (0)