diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index a27b5cd390a7f8c51c4318eda081ecd0dce463b4..bebe637f66e63376d2fc80369215a95640137422 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -1987,59 +1987,6 @@ export enum TrackedRangeStickiness { GrowsOnlyWhenTypingAfter = 3, } -/** - * A model that can track ranges. - */ -export interface ITextModelWithTrackedRanges extends ITextModel { - /** - * Start tracking a range (across edit operations). - * @param range The range to start tracking. - * @param stickiness The behaviour when typing at the edges of the range. - * @return A unique identifier for the tracked range. - * @internal - */ - addTrackedRange(range: IRange, stickiness: TrackedRangeStickiness): string; - - /** - * Change the range of a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRange` call. - * @param newRange The new range of the tracked range. - * @internal - */ - changeTrackedRange(id: string, newRange: IRange): void; - - /** - * Change the stickiness (behaviour when typing at the edges of the range) for a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRange` call. - * @param newStickiness The new behaviour when typing at the edges of the range. - * @internal - */ - changeTrackedRangeStickiness(id: string, newStickiness: TrackedRangeStickiness): void; - - /** - * Remove a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRaneg` call. - * @internal - */ - removeTrackedRange(id: string): void; - - /** - * Get the range of a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRaneg` call. - * @internal - */ - getTrackedRange(id: string): Range; - - /** - * Gets all the tracked ranges for the lines between `startLineNumber` and `endLineNumber` as an array. - * @param startLineNumber The start line number - * @param endLineNumber The end line number - * @return An array with the tracked ranges - * @internal - */ - getLinesTrackedRanges(startLineNumber: number, endLineNumber: number): IModelTrackedRange[]; -} - /** * A model that can have decorations. */ @@ -2210,7 +2157,7 @@ export interface IEditableTextModel extends ITextModelWithMarkers { /** * A model. */ -export interface IModel extends IReadOnlyModel, IEditableTextModel, ITextModelWithMarkers, ITokenizedModel, ITextModelWithTrackedRanges, ITextModelWithDecorations, IEditorModel { +export interface IModel extends IReadOnlyModel, IEditableTextModel, ITextModelWithMarkers, ITokenizedModel, ITextModelWithDecorations, IEditorModel { /** * @deprecated Please use `onDidChangeContent` instead. * An event emitted when the contents of the model have changed. diff --git a/src/vs/editor/common/model/editableTextModel.ts b/src/vs/editor/common/model/editableTextModel.ts index 639f9f311b7901bf13b8af593ea4c8052d28d6dd..c5a043fe0310321de466500843bbcd9041ec3129 100644 --- a/src/vs/editor/common/model/editableTextModel.ts +++ b/src/vs/editor/common/model/editableTextModel.ts @@ -735,14 +735,14 @@ export class EditableTextModel extends TextModelWithDecorations implements edito public setEditableRange(range: editorCommon.IRange): void { this._commandManager.clear(); if (this._hasEditableRange) { - this.removeTrackedRange(this._editableRangeId); + this._removeTrackedRange(this._editableRangeId); this._editableRangeId = null; this._hasEditableRange = false; } if (range) { this._hasEditableRange = true; - this._editableRangeId = this.addTrackedRange(range, editorCommon.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges); + this._editableRangeId = this._addTrackedRange(range, editorCommon.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges); } } @@ -752,7 +752,7 @@ export class EditableTextModel extends TextModelWithDecorations implements edito public getEditableRange(): Range { if (this._hasEditableRange) { - return this.getTrackedRange(this._editableRangeId); + return this._getTrackedRange(this._editableRangeId); } else { return this.getFullModelRange(); } diff --git a/src/vs/editor/common/model/textModelWithDecorations.ts b/src/vs/editor/common/model/textModelWithDecorations.ts index 7cd77307c609d2320a222aade51ee6576628ad01..2ecde07d0670d710d0c4a66dc035427df40c3bf5 100644 --- a/src/vs/editor/common/model/textModelWithDecorations.ts +++ b/src/vs/editor/common/model/textModelWithDecorations.ts @@ -173,7 +173,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme public getDecorationRange(decorationId: string): Range { if (this.decorations.hasOwnProperty(decorationId)) { var decoration = this.decorations[decorationId]; - return this.getTrackedRange(decoration.rangeId); + return this._getTrackedRange(decoration.rangeId); } return null; } @@ -189,7 +189,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme private _getDecorationsInRange(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number, ownerId: number, filterOutValidation: boolean): editorCommon.IModelDecoration[] { var result: editorCommon.IModelDecoration[] = [], decoration: IInternalDecoration, - lineRanges = this.getLinesTrackedRanges(startLineNumber, endLineNumber), + lineRanges = this._getLinesTrackedRanges(startLineNumber, endLineNumber), i: number, lineRange: editorCommon.IModelTrackedRange, len: number; @@ -264,7 +264,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme result.push({ id: decoration.id, ownerId: decoration.ownerId, - range: this.getTrackedRange(decoration.rangeId), + range: this._getTrackedRange(decoration.rangeId), options: decoration.options }); } @@ -351,7 +351,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme return { id: decoration.id, ownerId: decoration.ownerId, - range: this.getTrackedRange(decoration.rangeId), + range: this._getTrackedRange(decoration.rangeId), isForValidation: (decoration.options.className === editorCommon.ClassName.EditorErrorDecoration || decoration.options.className === editorCommon.ClassName.EditorWarningDecoration), options: decoration.options }; @@ -373,7 +373,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme } private _addDecorationImpl(eventBuilder: DeferredEventsBuilder, ownerId: number, range: Range, options: ModelDecorationOptions): string { - var rangeId = this.addTrackedRange(range, options.stickiness); + var rangeId = this._addTrackedRange(range, options.stickiness); var decoration = new ModelInternalDecoration(this._decorationIdGenerator.nextId(), ownerId, rangeId, options); @@ -408,7 +408,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme private _changeDecorationImpl(eventBuilder: DeferredEventsBuilder, id: string, newRange: Range): void { if (this.decorations.hasOwnProperty(id)) { let decoration = this.decorations[id]; - this.changeTrackedRange(decoration.rangeId, newRange); + this._changeTrackedRange(decoration.rangeId, newRange); eventBuilder.addMovedDecoration(id); } } @@ -419,7 +419,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme let oldOptions = decoration.options; if (oldOptions.stickiness !== options.stickiness) { - this.changeTrackedRangeStickiness(decoration.rangeId, options.stickiness); + this._changeTrackedRangeStickiness(decoration.rangeId, options.stickiness); } decoration.options = options; @@ -432,7 +432,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme if (this.decorations.hasOwnProperty(id)) { let decoration = this.decorations[id]; - this.removeTrackedRange(decoration.rangeId); + this._removeTrackedRange(decoration.rangeId); delete this.rangeIdToDecorationId[decoration.rangeId]; delete this.decorations[id]; @@ -480,7 +480,7 @@ export class TextModelWithDecorations extends TextModelWithTrackedRanges impleme result.push({ id: id, - range: this.getTrackedRange(decoration.rangeId), + range: this._getTrackedRange(decoration.rangeId), options: decoration.options }); } diff --git a/src/vs/editor/common/model/textModelWithTrackedRanges.ts b/src/vs/editor/common/model/textModelWithTrackedRanges.ts index 8b3b024d5bbee68cfb23004829e4d7c302d6353d..3acc653734deaafd702efcc753727a7f5ddecc85 100644 --- a/src/vs/editor/common/model/textModelWithTrackedRanges.ts +++ b/src/vs/editor/common/model/textModelWithTrackedRanges.ts @@ -35,7 +35,7 @@ class TrackedRange implements ITrackedRange { var _INSTANCE_COUNT = 0; -export class TextModelWithTrackedRanges extends TextModelWithMarkers implements editorCommon.ITextModelWithTrackedRanges { +export class TextModelWithTrackedRanges extends TextModelWithMarkers { private _rangeIdGenerator: IdGenerator; private _ranges: ITrackedRangesMap; @@ -89,7 +89,7 @@ export class TextModelWithTrackedRanges extends TextModelWithMarkers implements return Object.keys(this._ranges).length; } - public addTrackedRange(_textRange: editorCommon.IRange, stickiness: editorCommon.TrackedRangeStickiness): string { + protected _addTrackedRange(_textRange: editorCommon.IRange, stickiness: editorCommon.TrackedRangeStickiness): string { let textRange = this.validateRange(_textRange); let startMarkerSticksToPreviousCharacter = this._shouldStartMarkerSticksToPreviousCharacter(stickiness); @@ -151,7 +151,7 @@ export class TextModelWithTrackedRanges extends TextModelWithMarkers implements return result; } - public changeTrackedRange(rangeId: string, newTextRange: editorCommon.IRange): void { + protected _changeTrackedRange(rangeId: string, newTextRange: editorCommon.IRange): void { if (this._ranges.hasOwnProperty(rangeId)) { newTextRange = this.validateRange(newTextRange); @@ -163,7 +163,7 @@ export class TextModelWithTrackedRanges extends TextModelWithMarkers implements } } - public changeTrackedRangeStickiness(rangeId: string, newStickiness: editorCommon.TrackedRangeStickiness): void { + protected _changeTrackedRangeStickiness(rangeId: string, newStickiness: editorCommon.TrackedRangeStickiness): void { if (this._ranges.hasOwnProperty(rangeId)) { var range = this._ranges[rangeId]; this._changeMarkerStickiness(range.startMarkerId, this._shouldStartMarkerSticksToPreviousCharacter(newStickiness)); @@ -171,14 +171,7 @@ export class TextModelWithTrackedRanges extends TextModelWithMarkers implements } } - public isValidTrackedRange(rangeId: string): boolean { - if (this._isDisposed || !this._ranges) { - return false; - } - return this._ranges.hasOwnProperty(rangeId); - } - - public removeTrackedRange(rangeId: string): void { + protected _removeTrackedRange(rangeId: string): void { if (this._ranges.hasOwnProperty(rangeId)) { var range = this._ranges[rangeId]; @@ -225,7 +218,7 @@ export class TextModelWithTrackedRanges extends TextModelWithMarkers implements return new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column); } - public getTrackedRange(rangeId: string): Range { + protected _getTrackedRange(rangeId: string): Range { var range = this._ranges[rangeId]; var startMarker = this._getMarker(range.startMarkerId); var endMarker = this._getMarker(range.endMarkerId); @@ -263,7 +256,7 @@ export class TextModelWithTrackedRanges extends TextModelWithMarkers implements return result; } - public getLinesTrackedRanges(startLineNumber: number, endLineNumber: number): editorCommon.IModelTrackedRange[] { + protected _getLinesTrackedRanges(startLineNumber: number, endLineNumber: number): editorCommon.IModelTrackedRange[] { let result = this._getMultiLineTrackedRanges(startLineNumber, endLineNumber); let resultMap: { [rangeId: string]: boolean; } = {}; diff --git a/src/vs/editor/contrib/snippet/common/snippetController.ts b/src/vs/editor/contrib/snippet/common/snippetController.ts index 448f1efde87945302b29e4c1427a5185344de31a..4bf002ad07a60fa0c04ce721bf5640f73ea9cac9 100644 --- a/src/vs/editor/contrib/snippet/common/snippetController.ts +++ b/src/vs/editor/contrib/snippet/common/snippetController.ts @@ -70,29 +70,33 @@ export class InsertSnippetController { sortedOccurrences.sort(Range.compareRangesUsingStarts); // track each occurence - for (const {occurences} of adaptedSnippet.placeHolders) { - const trackedRanges: string[] = []; + this.model.changeDecorations((changeAccessor) => { + for (const {occurences} of adaptedSnippet.placeHolders) { + const trackedRanges: string[] = []; - for (const range of occurences) { - let stickiness = editorCommon.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges; + for (const range of occurences) { + let stickiness = editorCommon.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges; - // Check if the previous range ends exactly where this range starts - // and iff so change the stickiness to avoid conflicts - let idx = binarySearch(sortedOccurrences, range, Range.compareRangesUsingStarts); - if (idx > 0 - && sortedOccurrences[idx - 1].endLineNumber === range.startLineNumber - && sortedOccurrences[idx - 1].endColumn === range.startColumn) { + // Check if the previous range ends exactly where this range starts + // and iff so change the stickiness to avoid conflicts + let idx = binarySearch(sortedOccurrences, range, Range.compareRangesUsingStarts); + if (idx > 0 + && sortedOccurrences[idx - 1].endLineNumber === range.startLineNumber + && sortedOccurrences[idx - 1].endColumn === range.startColumn) { + + stickiness = editorCommon.TrackedRangeStickiness.GrowsOnlyWhenTypingAfter; + } - stickiness = editorCommon.TrackedRangeStickiness.GrowsOnlyWhenTypingAfter; + trackedRanges.push(changeAccessor.addDecoration(range, { + stickiness: stickiness + })); } - trackedRanges.push(this.model.addTrackedRange(range, stickiness)); + this.trackedPlaceHolders.push({ + ranges: trackedRanges + }); } - - this.trackedPlaceHolders.push({ - ranges: trackedRanges - }); - } + }); this.editor.changeDecorations((changeAccessor: editorCommon.IModelDecorationsChangeAccessor) => { let newDecorations: editorCommon.IModelDeltaDecoration[] = []; @@ -110,7 +114,7 @@ export class InsertSnippetController { for (let i = 0, len = this.trackedPlaceHolders.length; i < len; i++) { let className = (i === this.finishPlaceHolderIndex) ? 'finish-snippet-placeholder' : 'snippet-placeholder'; newDecorations.push({ - range: this.model.getTrackedRange(this.trackedPlaceHolders[i].ranges[0]), + range: this.model.getDecorationRange(this.trackedPlaceHolders[i].ranges[0]), options: { className: className } @@ -210,7 +214,7 @@ export class InsertSnippetController { var ranges = this.trackedPlaceHolders[i].ranges; for (var j = 0; (allCollapsed || allEqualToEditableRange) && j < ranges.length; j++) { - var range = this.model.getTrackedRange(ranges[j]); + var range = this.model.getDecorationRange(ranges[j]); if (allCollapsed) { if (!range.isEmpty()) { @@ -272,7 +276,7 @@ export class InsertSnippetController { } var oldPlaceHolderIndex = this.currentPlaceHolderIndex; - var oldRange = this.model.getTrackedRange(this.trackedPlaceHolders[oldPlaceHolderIndex].ranges[0]); + var oldRange = this.model.getDecorationRange(this.trackedPlaceHolders[oldPlaceHolderIndex].ranges[0]); var sameRange = true; do { if (goToNext) { @@ -281,7 +285,7 @@ export class InsertSnippetController { this.currentPlaceHolderIndex = (this.trackedPlaceHolders.length + this.currentPlaceHolderIndex - 1) % this.trackedPlaceHolders.length; } - var newRange = this.model.getTrackedRange(this.trackedPlaceHolders[this.currentPlaceHolderIndex].ranges[0]); + var newRange = this.model.getDecorationRange(this.trackedPlaceHolders[this.currentPlaceHolderIndex].ranges[0]); sameRange = oldRange.equalsRange(newRange); @@ -296,7 +300,7 @@ export class InsertSnippetController { return false; } if (this.finishPlaceHolderIndex !== -1) { - var finishRange = this.model.getTrackedRange(this.trackedPlaceHolders[this.finishPlaceHolderIndex].ranges[0]); + var finishRange = this.model.getDecorationRange(this.trackedPlaceHolders[this.finishPlaceHolderIndex].ranges[0]); // Let's just position cursor at the end of the finish range this.editor.setPosition({ lineNumber: finishRange.endLineNumber, @@ -320,7 +324,7 @@ export class InsertSnippetController { private doLinkEditing(): void { var selections: editorCommon.ISelection[] = []; for (var i = 0, len = this.trackedPlaceHolders[this.currentPlaceHolderIndex].ranges.length; i < len; i++) { - var range = this.model.getTrackedRange(this.trackedPlaceHolders[this.currentPlaceHolderIndex].ranges[i]); + var range = this.model.getDecorationRange(this.trackedPlaceHolders[this.currentPlaceHolderIndex].ranges[i]); selections.push({ selectionStartLineNumber: range.startLineNumber, selectionStartColumn: range.startColumn, @@ -341,12 +345,14 @@ export class InsertSnippetController { this.listenersToRemove = dispose(this.listenersToRemove); - for (var i = 0; i < this.trackedPlaceHolders.length; i++) { - var ranges = this.trackedPlaceHolders[i].ranges; - for (var j = 0; j < ranges.length; j++) { - this.model.removeTrackedRange(ranges[j]); + this.model.changeDecorations((changeAccessor) => { + for (var i = 0; i < this.trackedPlaceHolders.length; i++) { + var ranges = this.trackedPlaceHolders[i].ranges; + for (var j = 0; j < ranges.length; j++) { + changeAccessor.removeDecoration(ranges[j]); + } } - } + }); this.trackedPlaceHolders = []; this.editor.changeDecorations((changeAccessor: editorCommon.IModelDecorationsChangeAccessor) => { diff --git a/src/vs/editor/test/common/model/modelDecorations.test.ts b/src/vs/editor/test/common/model/modelDecorations.test.ts index 9e8fb6f3e88a0830a78f0744d183755b58eba6aa..7fd03018ca34ce9f757d779613af86b7ae4a3b10 100644 --- a/src/vs/editor/test/common/model/modelDecorations.test.ts +++ b/src/vs/editor/test/common/model/modelDecorations.test.ts @@ -582,13 +582,21 @@ suite('deltaDecorations', () => { 'How are you?' ].join('\n')); - var trackedRangeId = model.addTrackedRange({ - startLineNumber: 1, - startColumn: 1, - endLineNumber: 1, - endColumn: 1 - }, TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges); - model.removeTrackedRange(trackedRangeId); + var trackedRangeId = model.changeDecorations((changeAcessor) => { + return changeAcessor.addDecoration( + { + startLineNumber: 1, + startColumn: 1, + endLineNumber: 1, + endColumn: 1 + }, { + stickiness: TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges + } + ); + }); + model.changeDecorations((changeAccessor) => { + changeAccessor.removeDecoration(trackedRangeId); + }); var ids = model.deltaDecorations([], [ toModelDeltaDecoration(decoration('a', 1, 1, 1, 12)), diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e450662b960458d7ba7f15c3de455e3971ae6213..d530f505d5aec60ecaec0e3f9f90cc99c2ec04f1 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2108,12 +2108,6 @@ declare module monaco.editor { GrowsOnlyWhenTypingAfter = 3, } - /** - * A model that can track ranges. - */ - export interface ITextModelWithTrackedRanges extends ITextModel { - } - /** * A model that can have decorations. */ @@ -2222,7 +2216,7 @@ declare module monaco.editor { /** * A model. */ - export interface IModel extends IReadOnlyModel, IEditableTextModel, ITextModelWithMarkers, ITokenizedModel, ITextModelWithTrackedRanges, ITextModelWithDecorations, IEditorModel { + export interface IModel extends IReadOnlyModel, IEditableTextModel, ITextModelWithMarkers, ITokenizedModel, ITextModelWithDecorations, IEditorModel { /** * An event emitted when the contents of the model have changed. * @event