提交 ac0e3c61 编写于 作者: J Johannes Rieken

allow bulk edit to change EOL sequences

上级 f52053a7
......@@ -15,15 +15,26 @@ import { IFileService, IFileChange } from 'vs/platform/files/common/files';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { IIdentifiedSingleEditOperation, IModel, IRange, ISelection, ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { IIdentifiedSingleEditOperation, IModel, IRange, ISelection, EndOfLineSequence, ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
export interface IResourceEdit {
export interface IResourceTextEdit {
resource: URI;
range?: IRange;
newText: string;
}
export interface IResourceEOLEdit {
resource: URI;
eol: EndOfLineSequence;
}
export type IResourceEdit = IResourceTextEdit | IResourceEOLEdit;
function isIEndOfLineSequenceEdit(thing: any): thing is IResourceEOLEdit {
return thing && URI.isUri((<IResourceEOLEdit>thing).resource) && typeof (<IResourceEOLEdit>thing).eol === 'number';
}
interface IRecording {
stop(): void;
hasChanged(resource: URI): boolean;
......@@ -74,6 +85,7 @@ class EditTask implements IDisposable {
private get _model(): IModel { return this._modelReference.object.textEditorModel; }
private _modelReference: IReference<ITextEditorModel>;
private _edits: IIdentifiedSingleEditOperation[];
private _newEol: EndOfLineSequence;
constructor(modelReference: IReference<ITextEditorModel>) {
this._endCursorSelection = null;
......@@ -82,6 +94,12 @@ class EditTask implements IDisposable {
}
public addEdit(edit: IResourceEdit): void {
if (isIEndOfLineSequenceEdit(edit)) {
// store new EOL-sequence, last wins
this._newEol = edit.eol;
} else {
// create edit operation
let range: IRange;
if (!edit.range) {
range = this._model.getFullModelRange();
......@@ -90,16 +108,18 @@ class EditTask implements IDisposable {
}
this._edits.push(EditOperation.replaceMove(Range.lift(range), edit.newText));
}
}
public apply(): void {
if (this._edits.length === 0) {
return;
}
if (this._edits.length > 0) {
this._edits.sort(EditTask._editCompare);
this._initialSelections = this._getInitialSelections();
this._model.pushEditOperations(this._initialSelections, this._edits, (edits) => this._getEndCursorSelections(edits));
}
if (this._newEol !== undefined) {
this._model.setEOL(this._newEol);
}
}
protected _getInitialSelections(): Selection[] {
const firstRange = this._edits[0].range;
......
......@@ -26,7 +26,7 @@ import { IWorkspace } from 'vs/platform/workspace/common/workspace';
import * as editorCommon from 'vs/editor/common/editorCommon';
import * as modes from 'vs/editor/common/modes';
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
import { IResourceTextEdit } from 'vs/editor/common/services/bulkEdit';
import { ITextSource } from 'vs/editor/common/model/textSource';
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
......@@ -234,7 +234,7 @@ export abstract class MainThreadWorkspaceShape {
$startSearch(include: string, exclude: string, maxResults: number, requestId: number): Thenable<URI[]> { throw ni(); }
$cancelSearch(requestId: number): Thenable<boolean> { throw ni(); }
$saveAll(includeUntitled?: boolean): Thenable<boolean> { throw ni(); }
$applyWorkspaceEdit(edits: IResourceEdit[]): TPromise<boolean> { throw ni(); }
$applyWorkspaceEdit(edits: IResourceTextEdit[]): TPromise<boolean> { throw ni(); }
}
export abstract class MainProcessExtensionServiceShape {
......
......@@ -13,7 +13,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { MainThreadWorkspaceShape, ExtHostDocumentSaveParticipantShape } from 'vs/workbench/api/node/extHost.protocol';
import { TextEdit } from 'vs/workbench/api/node/extHostTypes';
import { fromRange, TextDocumentSaveReason } from 'vs/workbench/api/node/extHostTypeConverters';
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
import { IResourceTextEdit } from 'vs/editor/common/services/bulkEdit';
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import * as vscode from 'vscode';
......@@ -103,8 +103,8 @@ export class ExtHostDocumentSaveParticipant extends ExtHostDocumentSaveParticipa
const promises: TPromise<any | vscode.TextEdit[]>[] = [];
const {document, reason} = stubEvent;
const {version} = document;
const { document, reason } = stubEvent;
const { version } = document;
const event = Object.freeze(<vscode.TextDocumentWillSaveEvent>{
document,
......@@ -134,10 +134,10 @@ export class ExtHostDocumentSaveParticipant extends ExtHostDocumentSaveParticipa
}).then(values => {
const edits: IResourceEdit[] = [];
const edits: IResourceTextEdit[] = [];
for (const value of values) {
if (Array.isArray(value) && (<vscode.TextEdit[]>value).every(e => e instanceof TextEdit)) {
for (const {newText, range} of value) {
for (const { newText, range } of value) {
edits.push({
resource: <URI>document.uri,
range: fromRange(range),
......
......@@ -8,7 +8,7 @@ import URI from 'vs/base/common/uri';
import { normalize } from 'vs/base/common/paths';
import { relative } from 'path';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
import { IResourceTextEdit } from 'vs/editor/common/services/bulkEdit';
import { TPromise } from 'vs/base/common/winjs.base';
import { fromRange } from 'vs/workbench/api/node/extHostTypeConverters';
import { MainContext, MainThreadWorkspaceShape } from './extHost.protocol';
......@@ -70,7 +70,7 @@ export class ExtHostWorkspace {
appyEdit(edit: vscode.WorkspaceEdit): TPromise<boolean> {
let resourceEdits: IResourceEdit[] = [];
let resourceEdits: IResourceTextEdit[] = [];
let entries = edit.entries();
for (let entry of entries) {
......
......@@ -10,7 +10,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { bulkEdit, IResourceEdit } from 'vs/editor/common/services/bulkEdit';
import { bulkEdit, IResourceTextEdit } from 'vs/editor/common/services/bulkEdit';
import { TPromise } from 'vs/base/common/winjs.base';
import { Uri } from 'vscode';
import { MainThreadWorkspaceShape } from './extHost.protocol';
......@@ -89,7 +89,7 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
});
}
$applyWorkspaceEdit(edits: IResourceEdit[]): TPromise<boolean> {
$applyWorkspaceEdit(edits: IResourceTextEdit[]): TPromise<boolean> {
let codeEditor: ICommonCodeEditor;
let editor = this._editorService.getActiveEditor();
......
......@@ -15,7 +15,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { Match, FileMatch, FileMatchOrMatch, ISearchWorkbenchService } from 'vs/workbench/parts/search/common/searchModel';
import { BulkEdit, IResourceEdit, createBulkEdit } from 'vs/editor/common/services/bulkEdit';
import { BulkEdit, IResourceTextEdit, createBulkEdit } from 'vs/editor/common/services/bulkEdit';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
......@@ -182,9 +182,9 @@ export class ReplaceService implements IReplaceService {
});
}
private createEdit(match: Match, text: string, resource: URI = null): IResourceEdit {
private createEdit(match: Match, text: string, resource: URI = null): IResourceTextEdit {
let fileMatch: FileMatch = match.parent();
let resourceEdit: IResourceEdit = {
let resourceEdit: IResourceTextEdit = {
resource: resource !== null ? resource : fileMatch.resource(),
range: match.range(),
newText: text
......
......@@ -13,7 +13,7 @@ import { TextDocumentSaveReason, TextEdit, Position } from 'vs/workbench/api/nod
import { MainThreadWorkspaceShape } from 'vs/workbench/api/node/extHost.protocol';
import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/node/extHostDocumentSaveParticipant';
import { OneGetThreadService } from './testThreadService';
import { IResourceEdit } from 'vs/editor/common/services/bulkEdit';
import { IResourceTextEdit } from 'vs/editor/common/services/bulkEdit';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import * as vscode from 'vscode';
......@@ -252,7 +252,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
test('event delivery, pushEdits sync', () => {
let edits: IResourceEdit[];
let edits: IResourceTextEdit[];
const participant = new ExtHostDocumentSaveParticipant(documents, new class extends MainThreadWorkspaceShape {
$applyWorkspaceEdit(_edits) {
edits = _edits;
......@@ -273,7 +273,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
test('event delivery, concurrent change', () => {
let edits: IResourceEdit[];
let edits: IResourceTextEdit[];
const participant = new ExtHostDocumentSaveParticipant(documents, new class extends MainThreadWorkspaceShape {
$applyWorkspaceEdit(_edits) {
edits = _edits;
......@@ -306,7 +306,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
test('event delivery, two listeners -> two document states', () => {
const participant = new ExtHostDocumentSaveParticipant(documents, new class extends MainThreadWorkspaceShape {
$applyWorkspaceEdit(_edits: IResourceEdit[]) {
$applyWorkspaceEdit(_edits: IResourceTextEdit[]) {
for (const { resource, newText, range } of _edits) {
documents.$acceptModelChanged(resource.toString(), [{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册