Skip to content

Commit

Permalink
Inital commit for adding API to apply workspace edit
Browse files Browse the repository at this point in the history
Signed-off-by: Vitalii Parfonov <vparfonov@redhat.com>
  • Loading branch information
vparfonov committed Jan 9, 2019
1 parent 6a3444d commit 0a6abc4
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ export interface TextEditorsMain {
$tryRevealRange(id: string, range: Range, revealType: TextEditorRevealType): Promise<void>;
$trySetSelections(id: string, selections: Selection[]): Promise<void>;
$tryApplyEdits(id: string, modelVersionId: number, edits: SingleEditOperation[], opts: ApplyEditsOptions): Promise<boolean>;
// $tryApplyWorkspaceEdit(workspaceEditDto: WorkspaceEditDto): Promise<boolean>;
$tryApplyWorkspaceEdit(workspaceEditDto: WorkspaceEditDto): Promise<boolean>;
$tryInsertSnippet(id: string, template: string, selections: Range[], opts: UndoStopOptions): Promise<boolean>;
// $getDiffInformation(id: string): Promise<editorCommon.ILineChange[]>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { DocumentsMainImpl } from './documents-main';
import { TextEditorsMainImpl } from './text-editors-main';
import { EditorManager } from '@theia/editor/lib/browser';
import { OpenerService } from '@theia/core/lib/browser/opener-service';
import { MonacoBulkEditService } from '@theia/monaco/lib/browser/monaco-bulk-edit-service';

export class EditorsAndDocumentsMain {
private toDispose = new DisposableCollection();
Expand All @@ -53,11 +54,12 @@ export class EditorsAndDocumentsMain {
const modelService = container.get<EditorModelService>(EditorModelService);
const editorManager = container.get<EditorManager>(EditorManager);
const openerService = container.get<OpenerService>(OpenerService);
const bulkEditService = container.get<MonacoBulkEditService>(MonacoBulkEditService);

const documentsMain = new DocumentsMainImpl(this, modelService, rpc, editorManager, openerService);
rpc.set(PLUGIN_RPC_CONTEXT.DOCUMENTS_MAIN, documentsMain);

const editorsMain = new TextEditorsMainImpl(this, rpc);
const editorsMain = new TextEditorsMainImpl(this, rpc, bulkEditService);
rpc.set(PLUGIN_RPC_CONTEXT.TEXT_EDITORS_MAIN, editorsMain);

this.stateComputer = new EditorAndDocumentStateComputer(d => this.onDelta(d), editorService, modelService);
Expand Down
33 changes: 31 additions & 2 deletions packages/plugin-ext/src/main/browser/text-editors-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,29 @@ import {
ApplyEditsOptions,
UndoStopOptions,
DecorationRenderOptions,
DecorationOptions
DecorationOptions,
ResourceTextEditDto,
ResourceFileEditDto,
WorkspaceEditDto
} from '../../api/plugin-api';
import { Range } from '../../api/model';
import { EditorsAndDocumentsMain } from './editors-and-documents-main';
import { RPCProtocol } from '../../api/rpc-protocol';
import { DisposableCollection } from '@theia/core';
import { TextEditorMain } from './text-editor-main';
import { disposed } from '../../common/errors';
import URI from 'vscode-uri';
import { MonacoBulkEditService } from '@theia/monaco/lib/browser/monaco-bulk-edit-service';

export class TextEditorsMainImpl implements TextEditorsMain {

private toDispose = new DisposableCollection();
private proxy: TextEditorsExt;
private editorsToDispose = new Map<string, DisposableCollection>();
constructor(private readonly editorsAndDocuments: EditorsAndDocumentsMain, rpc: RPCProtocol) {

constructor(private readonly editorsAndDocuments: EditorsAndDocumentsMain,
rpc: RPCProtocol,
private readonly bulkEditService: MonacoBulkEditService) {
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.TEXT_EDITORS_EXT);
this.toDispose.push(editorsAndDocuments.onTextEditorAdd(editors => editors.forEach(this.onTextEditorAdd, this)));
this.toDispose.push(editorsAndDocuments.onTextEditorRemove(editors => editors.forEach(this.onTextEditorRemove, this)));
Expand Down Expand Up @@ -101,6 +109,13 @@ export class TextEditorsMainImpl implements TextEditorsMain {
return Promise.resolve(this.editorsAndDocuments.getEditor(id)!.applyEdits(modelVersionId, edits, opts));
}

$tryApplyWorkspaceEdit(dto: WorkspaceEditDto): Promise<boolean> {
const edits = this.reviveWorkspaceEditDto(dto);
return new Promise(resolve => {
this.bulkEditService.apply( edits).then(() => resolve(true), err => resolve(false));
});
}

$tryInsertSnippet(id: string, template: string, ranges: Range[], opts: UndoStopOptions): Promise<boolean> {
if (!this.editorsAndDocuments.getEditor(id)) {
return Promise.reject(disposed(`TextEditor(${id})`));
Expand Down Expand Up @@ -131,4 +146,18 @@ export class TextEditorsMainImpl implements TextEditorsMain {
this.editorsAndDocuments.getEditor(id)!.setDecorationsFast(key, ranges);
return Promise.resolve();
}

reviveWorkspaceEditDto(data: WorkspaceEditDto): monaco.languages.WorkspaceEdit {
if (data && data.edits) {
for (const edit of data.edits) {
if (typeof (<ResourceTextEditDto>edit).resource === 'object') {
(<ResourceTextEditDto>edit).resource = URI.revive((<ResourceTextEditDto>edit).resource);
} else {
(<ResourceFileEditDto>edit).newUri = URI.revive((<ResourceFileEditDto>edit).newUri);
(<ResourceFileEditDto>edit).oldUri = URI.revive((<ResourceFileEditDto>edit).oldUri);
}
}
}
return <monaco.languages.WorkspaceEdit>data;
}
}
3 changes: 3 additions & 0 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,9 @@ export function createAPIFactory(
findFiles(include: theia.GlobPattern, exclude?: theia.GlobPattern | undefined, maxResults?: number, token?: CancellationToken): PromiseLike<Uri[]> {
return workspaceExt.findFiles(include, undefined, maxResults, token);
},
applyEdit(edit: theia.WorkspaceEdit): PromiseLike<boolean> {
return editors.applyWorkspaceEdit(edit);
},
registerTextDocumentContentProvider(scheme: string, provider: theia.TextDocumentContentProvider): theia.Disposable {
return workspaceExt.registerTextDocumentContentProvider(scheme, provider);
},
Expand Down
5 changes: 5 additions & 0 deletions packages/plugin-ext/src/plugin/text-editors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ export class TextEditorsExtImpl implements TextEditorsExt {
return new TextEditorDecorationType(this.proxy, options);
}

applyWorkspaceEdit(edit: theia.WorkspaceEdit): Promise<boolean> {
const dto = Converters.fromWorkspaceEdit(edit, this.editorsAndDocuments);
return this.proxy.$tryApplyWorkspaceEdit(dto);
}

}

export class TextEditorDecorationType implements theia.TextEditorDecorationType {
Expand Down
20 changes: 20 additions & 0 deletions packages/plugin/src/theia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3872,6 +3872,25 @@ declare module '@theia/plugin' {
*/
export function findFiles(include: GlobPattern, exclude?: GlobPattern | undefined, maxResults?: number, token?: CancellationToken): PromiseLike<Uri[]>;

/**
* Make changes to one or many resources or create, delete, and rename resources as defined by the given
* [workspace edit](#WorkspaceEdit).
*
* All changes of a workspace edit are applied in the same order in which they have been added. If
* multiple textual inserts are made at the same position, these strings appear in the resulting text
* in the order the 'inserts' were made. Invalid sequences like 'delete file a' -> 'insert text in file a'
* cause failure of the operation.
*
* When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used.
* A workspace edit with resource creations or deletions aborts the operation, e.g. consective edits will
* not be attempted, when a single edit fails.
*
* @param edit A workspace edit.
* @return A thenable that resolves when the edit could be applied.
*/
export function applyEdit(edit: WorkspaceEdit): PromiseLike<boolean>;


/**
* Register a filesystem provider for a given scheme, e.g. `ftp`.
*
Expand Down Expand Up @@ -4756,6 +4775,7 @@ declare module '@theia/plugin' {
constructor(range: Range, newText: string);
}


/**
* Completion item kinds.
*/
Expand Down

0 comments on commit 0a6abc4

Please sign in to comment.