/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; import Event, { Emitter } from 'vs/base/common/event'; import { toThenable } from 'vs/base/common/async'; import { TPromise } from 'vs/base/common/winjs.base'; import { TextEditorSelectionChangeKind } from './extHostTypes'; import * as TypeConverters from './extHostTypeConverters'; import { TextEditorDecorationType, ExtHostTextEditor } from './extHostTextEditor'; import { ExtHostDocumentsAndEditors } from './extHostDocumentsAndEditors'; import { Position as EditorPosition } from 'vs/platform/editor/common/editor'; import { MainContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextDocumentShowOptions, ITextEditorPositionData, IResolvedTextEditorConfiguration, ISelectionChangeEvent, IMainContext, IWorkspaceResourceEdit } from './extHost.protocol'; import * as vscode from 'vscode'; export class ExtHostEditors implements ExtHostEditorsShape { private readonly _onDidChangeTextEditorSelection = new Emitter(); private readonly _onDidChangeTextEditorOptions = new Emitter(); private readonly _onDidChangeTextEditorViewColumn = new Emitter(); private readonly _onDidChangeActiveTextEditor = new Emitter(); private readonly _onDidChangeVisibleTextEditors = new Emitter(); readonly onDidChangeTextEditorSelection: Event = this._onDidChangeTextEditorSelection.event; readonly onDidChangeTextEditorOptions: Event = this._onDidChangeTextEditorOptions.event; readonly onDidChangeTextEditorViewColumn: Event = this._onDidChangeTextEditorViewColumn.event; readonly onDidChangeActiveTextEditor: Event = this._onDidChangeActiveTextEditor.event; readonly onDidChangeVisibleTextEditors: Event = this._onDidChangeVisibleTextEditors.event; private _proxy: MainThreadEditorsShape; private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors; constructor( mainContext: IMainContext, extHostDocumentsAndEditors: ExtHostDocumentsAndEditors, ) { this._proxy = mainContext.get(MainContext.MainThreadEditors); this._extHostDocumentsAndEditors = extHostDocumentsAndEditors; this._extHostDocumentsAndEditors.onDidChangeVisibleTextEditors(e => this._onDidChangeVisibleTextEditors.fire(e)); this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => this._onDidChangeActiveTextEditor.fire(e)); } getActiveTextEditor(): ExtHostTextEditor { return this._extHostDocumentsAndEditors.activeEditor(); } getVisibleTextEditors(): vscode.TextEditor[] { return this._extHostDocumentsAndEditors.allEditors(); } showTextDocument(document: vscode.TextDocument, column: vscode.ViewColumn, preserveFocus: boolean): TPromise; showTextDocument(document: vscode.TextDocument, options: { column: vscode.ViewColumn, preserveFocus: boolean, pinned: boolean }): TPromise; showTextDocument(document: vscode.TextDocument, columnOrOptions: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): TPromise; showTextDocument(document: vscode.TextDocument, columnOrOptions: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): TPromise { let options: ITextDocumentShowOptions; if (typeof columnOrOptions === 'number') { options = { position: TypeConverters.fromViewColumn(columnOrOptions), preserveFocus }; } else if (typeof columnOrOptions === 'object') { options = { position: TypeConverters.fromViewColumn(columnOrOptions.viewColumn), preserveFocus: columnOrOptions.preserveFocus, selection: typeof columnOrOptions.selection === 'object' ? TypeConverters.fromRange(columnOrOptions.selection) : undefined, pinned: typeof columnOrOptions.preview === 'boolean' ? !columnOrOptions.preview : undefined }; } else { options = { position: EditorPosition.ONE, preserveFocus: false }; } return this._proxy.$tryShowTextDocument(document.uri, options).then(id => { let editor = this._extHostDocumentsAndEditors.getEditor(id); if (editor) { return editor; } else { throw new Error(`Failed to show text document ${document.uri.toString()}, should show in editor #${id}`); } }); } createTextEditorDecorationType(options: vscode.DecorationRenderOptions): vscode.TextEditorDecorationType { return new TextEditorDecorationType(this._proxy, options); } applyWorkspaceEdit(edit: vscode.WorkspaceEdit): TPromise { let workspaceResourceEdits: IWorkspaceResourceEdit[] = []; let entries = edit.entries(); for (let entry of entries) { let [uri, edits] = entry; let doc = this._extHostDocumentsAndEditors.getDocument(uri.toString()); let docVersion: number = undefined; if (doc) { docVersion = doc.version; } let workspaceResourceEdit: IWorkspaceResourceEdit = { resource: uri, modelVersionId: docVersion, edits: [] }; for (let edit of edits) { workspaceResourceEdit.edits.push({ newText: edit.newText, newEol: TypeConverters.EndOfLine.from(edit.newEol), range: edit.range && TypeConverters.fromRange(edit.range) }); } workspaceResourceEdits.push(workspaceResourceEdit); } return this._proxy.$tryApplyWorkspaceEdit(workspaceResourceEdits); } // --- called from main thread $acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void { let editor = this._extHostDocumentsAndEditors.getEditor(id); editor._acceptOptions(opts); this._onDidChangeTextEditorOptions.fire({ textEditor: editor, options: opts }); } $acceptSelectionsChanged(id: string, event: ISelectionChangeEvent): void { const kind = TextEditorSelectionChangeKind.fromValue(event.source); const selections = event.selections.map(TypeConverters.toSelection); const textEditor = this._extHostDocumentsAndEditors.getEditor(id); textEditor._acceptSelections(selections); this._onDidChangeTextEditorSelection.fire({ textEditor, selections, kind }); } $acceptEditorPositionData(data: ITextEditorPositionData): void { for (let id in data) { let textEditor = this._extHostDocumentsAndEditors.getEditor(id); let viewColumn = TypeConverters.toViewColumn(data[id]); if (textEditor.viewColumn !== viewColumn) { textEditor._acceptViewColumn(viewColumn); this._onDidChangeTextEditorViewColumn.fire({ textEditor, viewColumn }); } } } getDiffInformation(id: string): Thenable { return toThenable(this._proxy.$getDiffInformation(id)); } }