Fixes #8096: Add options to TextEditor.edit that allows to control the undo/redo behaviour around the edit

This commit is contained in:
Alex Dima
2016-08-26 16:49:25 +02:00
parent 70ea0865e4
commit 05e9b96033
5 changed files with 40 additions and 19 deletions

View File

@@ -31,8 +31,7 @@ import {ConfigurationTarget} from 'vs/workbench/services/configuration/common/co
import {IPickOpenEntry, IPickOptions} from 'vs/workbench/services/quickopen/common/quickOpenService';
import {IWorkspaceSymbol} from 'vs/workbench/parts/search/common/search';
import {TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent} from './mainThreadEditorsTracker';
import {EndOfLine} from './extHostTypes';
import {IApplyEditsOptions, TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent} from './mainThreadEditorsTracker';
export interface InstanceSetter<T> {
set<R extends T>(instance:T): R;
@@ -110,7 +109,7 @@ export abstract class MainThreadEditorsShape {
$trySetDecorations(id: string, key: string, ranges: editorCommon.IDecorationOptions[]): TPromise<any> { throw ni(); }
$tryRevealRange(id: string, range: editorCommon.IRange, revealType: TextEditorRevealType): TPromise<any> { throw ni(); }
$trySetSelections(id: string, selections: editorCommon.ISelection[]): TPromise<any> { throw ni(); }
$tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], setEndOfLine:EndOfLine): TPromise<boolean> { throw ni(); }
$tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], opts:IApplyEditsOptions): TPromise<boolean> { throw ni(); }
}
export abstract class MainThreadErrorsShape {

View File

@@ -181,6 +181,8 @@ export interface IEditData {
documentVersionId: number;
edits: ITextEditOperation[];
setEndOfLine: EndOfLine;
undoStopBefore:boolean;
undoStopAfter:boolean;
}
export class TextEditorEdit {
@@ -188,18 +190,24 @@ export class TextEditorEdit {
private _documentVersionId: number;
private _collectedEdits: ITextEditOperation[];
private _setEndOfLine: EndOfLine;
private _undoStopBefore: boolean;
private _undoStopAfter: boolean;
constructor(document: vscode.TextDocument) {
constructor(document: vscode.TextDocument, options:{ undoStopBefore: boolean; undoStopAfter: boolean; }) {
this._documentVersionId = document.version;
this._collectedEdits = [];
this._setEndOfLine = 0;
this._undoStopBefore = options.undoStopBefore;
this._undoStopAfter = options.undoStopAfter;
}
finalize(): IEditData {
return {
documentVersionId: this._documentVersionId,
edits: this._collectedEdits,
setEndOfLine: this._setEndOfLine
setEndOfLine: this._setEndOfLine,
undoStopBefore: this._undoStopBefore,
undoStopAfter: this._undoStopAfter
};
}
@@ -402,8 +410,8 @@ class ExtHostTextEditor implements vscode.TextEditor {
// ---- editing
edit(callback: (edit: TextEditorEdit) => void): Thenable<boolean> {
let edit = new TextEditorEdit(this._documentData.document);
edit(callback: (edit: TextEditorEdit) => void, options:{ undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Thenable<boolean> {
let edit = new TextEditorEdit(this._documentData.document, options);
callback(edit);
return this._applyEdit(edit);
}
@@ -420,7 +428,11 @@ class ExtHostTextEditor implements vscode.TextEditor {
};
});
return this._proxy.$tryApplyEdits(this._id, editData.documentVersionId, edits, editData.setEndOfLine);
return this._proxy.$tryApplyEdits(this._id, editData.documentVersionId, edits, {
setEndOfLine: editData.setEndOfLine,
undoStopBefore: editData.undoStopBefore,
undoStopAfter: editData.undoStopAfter
});
}
// ---- util

View File

@@ -8,14 +8,13 @@ import URI from 'vs/base/common/uri';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {TPromise} from 'vs/base/common/winjs.base';
import {IThreadService} from 'vs/workbench/services/thread/common/threadService';
import {EndOfLine} from './extHostTypes';
import {ISingleEditOperation, ISelection, IRange, IEditor, EditorType, ICommonCodeEditor, ICommonDiffEditor, IDecorationRenderOptions, IDecorationOptions} from 'vs/editor/common/editorCommon';
import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
import {Position as EditorPosition} from 'vs/platform/editor/common/editor';
import {IModelService} from 'vs/editor/common/services/modelService';
import {MainThreadEditorsTracker, TextEditorRevealType, MainThreadTextEditor, ITextEditorConfigurationUpdate} from 'vs/workbench/api/node/mainThreadEditorsTracker';
import {MainThreadEditorsTracker, TextEditorRevealType, MainThreadTextEditor, IApplyEditsOptions, ITextEditorConfigurationUpdate} from 'vs/workbench/api/node/mainThreadEditorsTracker';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IEventService} from 'vs/platform/event/common/event';
import {equals as arrayEquals} from 'vs/base/common/arrays';
@@ -282,11 +281,11 @@ export class MainThreadEditors extends MainThreadEditorsShape {
return TPromise.as(null);
}
$tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], setEndOfLine:EndOfLine): TPromise<boolean> {
$tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], opts:IApplyEditsOptions): TPromise<boolean> {
if (!this._textEditorsMap[id]) {
return TPromise.wrapError('TextEditor disposed');
}
return TPromise.as(this._textEditorsMap[id].applyEdits(modelVersionId, edits, setEndOfLine));
return TPromise.as(this._textEditorsMap[id].applyEdits(modelVersionId, edits, opts));
}
$registerTextEditorDecorationType(key: string, options: IDecorationRenderOptions): void {

View File

@@ -56,6 +56,12 @@ export enum TextEditorRevealType {
InCenterIfOutsideViewport = 2
}
export interface IApplyEditsOptions {
undoStopBefore: boolean;
undoStopAfter: boolean;
setEndOfLine: EndOfLine;
}
/**
* Text Editor that is permanently bound to the same model.
* It can be bound or not to a CodeEditor.
@@ -314,7 +320,7 @@ export class MainThreadTextEditor {
return editor.getControl() === this._codeEditor;
}
public applyEdits(versionIdCheck:number, edits:EditorCommon.ISingleEditOperation[], setEndOfLine:EndOfLine): boolean {
public applyEdits(versionIdCheck:number, edits:EditorCommon.ISingleEditOperation[], opts:IApplyEditsOptions): boolean {
if (this._model.getVersionId() !== versionIdCheck) {
console.warn('Model has changed in the meantime!');
// throw new Error('Model has changed in the meantime!');
@@ -323,9 +329,9 @@ export class MainThreadTextEditor {
}
if (this._codeEditor) {
if (setEndOfLine === EndOfLine.CRLF) {
if (opts.setEndOfLine === EndOfLine.CRLF) {
this._model.setEOL(EditorCommon.EndOfLineSequence.CRLF);
} else if (setEndOfLine === EndOfLine.LF) {
} else if (opts.setEndOfLine === EndOfLine.LF) {
this._model.setEOL(EditorCommon.EndOfLineSequence.LF);
}
@@ -338,9 +344,13 @@ export class MainThreadTextEditor {
};
});
this._codeEditor.pushUndoStop();
if (opts.undoStopBefore) {
this._codeEditor.pushUndoStop();
}
this._codeEditor.executeEdits('MainThreadTextEditor', transformedEdits);
this._codeEditor.pushUndoStop();
if (opts.undoStopAfter) {
this._codeEditor.pushUndoStop();
}
return true;
}