From c14e864b2b81ca5df093f7040ec61e78a83b6e5b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 21 Jan 2016 12:05:02 +0100 Subject: [PATCH] #1835 add viewColumn property to TextEditor, not yet decided if we also need an event to signal changes --- .../vscode-api-tests/src/window.test.ts | 20 ++++- src/vs/vscode.d.ts | 6 ++ src/vs/workbench/api/node/extHostEditors.ts | 89 ++++++++++++++++--- .../api/node/extHostTypeConverters.ts | 12 +++ .../browser/parts/editor/baseEditor.ts | 2 + src/vs/workbench/common/events.ts | 5 ++ 6 files changed, 122 insertions(+), 12 deletions(-) diff --git a/extensions/vscode-api-tests/src/window.test.ts b/extensions/vscode-api-tests/src/window.test.ts index faff4a89cfa..b54aa7a085c 100644 --- a/extensions/vscode-api-tests/src/window.test.ts +++ b/extensions/vscode-api-tests/src/window.test.ts @@ -6,7 +6,7 @@ 'use strict'; import * as assert from 'assert'; -import {workspace, window} from 'vscode'; +import {workspace, window, ViewColumn} from 'vscode'; import {join} from 'path'; import {cleanUp, pathEquals} from './utils'; @@ -14,7 +14,7 @@ suite("window namespace tests", () => { teardown(cleanUp); - test('active text editor', () => { + test('editor, active text editor', () => { return workspace.openTextDocument(join(workspace.rootPath, './far.js')).then(doc => { return window.showTextDocument(doc).then((editor) => { const active = window.activeTextEditor; @@ -23,4 +23,20 @@ suite("window namespace tests", () => { }); }); }); + + test('editor, assign and check view columns', () => { + + return workspace.openTextDocument(join(workspace.rootPath, './far.js')).then(doc => { + let p1 = window.showTextDocument(doc, ViewColumn.One).then(editor => { + assert.equal(editor.viewColumn, ViewColumn.One); + }); + let p2 = window.showTextDocument(doc, ViewColumn.Two).then(editor => { + assert.equal(editor.viewColumn, ViewColumn.Two); + }); + let p3 = window.showTextDocument(doc, ViewColumn.Three).then(editor => { + assert.equal(editor.viewColumn, ViewColumn.Three); + }); + return Promise.all([p1, p2, p3]); + }); + }); }); \ No newline at end of file diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index d9a4cc5cb6b..39c572b26fe 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -725,6 +725,12 @@ declare namespace vscode { */ options: TextEditorOptions; + /** + * The column in which this editor shows. Will be `undefined` in case this + * isn't one of the three main editors, e.g an embedded editor. + */ + viewColumn: ViewColumn; + /** * Perform an edit on the document associated with this text editor. * diff --git a/src/vs/workbench/api/node/extHostEditors.ts b/src/vs/workbench/api/node/extHostEditors.ts index 9bda4f767c5..a8a21d7355d 100644 --- a/src/vs/workbench/api/node/extHostEditors.ts +++ b/src/vs/workbench/api/node/extHostEditors.ts @@ -23,12 +23,18 @@ import {EventType} from 'vs/workbench/common/events'; 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'; +import {equals as objectEquals} from 'vs/base/common/objects'; export interface ITextEditorAddData { id: string; document: URI; options: ITextEditorConfiguration; selections: ISelection[]; + editorPosition: EditorPosition; +} + +export interface ITextEditorPositionData { + [id: string]: EditorPosition; } @Remotable.PluginHostContext('ExtHostEditors') @@ -95,7 +101,7 @@ export class ExtHostEditors { _acceptTextEditorAdd(data: ITextEditorAddData): void { let document = this._modelService.getDocumentData(data.document); - let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options); + let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options, TypeConverters.toViewColumn(data.editorPosition)); this._editors[data.id] = newEditor; } @@ -129,6 +135,16 @@ export class ExtHostEditors { this._onDidChangeActiveTextEditor.fire(this.getActiveTextEditor()); } + _acceptEditorPositionData(data: ITextEditorPositionData): void { + for (let id in data) { + let editor = this._editors[id]; + let value = TypeConverters.toViewColumn(data[id]); + if (editor.viewColumn !== value) { + editor._acceptViewColumn(value); + } + } + } + _acceptTextEditorRemove(id: string): void { // make sure the removed editor is not visible let newVisibleEditors = this._visibleEditorIds.filter(visibleEditorId => visibleEditorId !== id); @@ -271,13 +287,15 @@ class ExtHostTextEditor implements vscode.TextEditor { private _documentData: ExtHostDocumentData; private _selections: Selection[]; private _options: TextEditorOptions; + private _viewColumn: vscode.ViewColumn; - constructor(proxy: MainThreadEditors, id: string, document: ExtHostDocumentData, selections: Selection[], options: EditorOptions) { + constructor(proxy: MainThreadEditors, id: string, document: ExtHostDocumentData, selections: Selection[], options: EditorOptions, viewColumn: vscode.ViewColumn) { this._proxy = proxy; this._id = id; this._documentData = document; this._selections = selections; this._options = options; + this._viewColumn = viewColumn; } dispose() { @@ -319,6 +337,20 @@ class ExtHostTextEditor implements vscode.TextEditor { this._options = options; } + // ---- view column + + get viewColumn(): vscode.ViewColumn { + return this._viewColumn; + } + + set viewColumn(value) { + throw readonly('viewColumn'); + } + + _acceptViewColumn(value: vscode.ViewColumn) { + this._viewColumn = value; + } + // ---- selections get selection(): Selection { @@ -423,6 +455,7 @@ export class MainThreadEditors { private _textEditorsMap: { [editorId: string]: MainThreadTextEditor; }; private _activeTextEditor: string; private _visibleEditors: string[]; + private _editorPositionData: ITextEditorPositionData; constructor( @IThreadService threadService: IThreadService, @@ -440,6 +473,7 @@ export class MainThreadEditors { this._textEditorsMap = Object.create(null); this._activeTextEditor = null; this._visibleEditors = []; + this._editorPositionData = null; this._editorTracker = new MainThreadEditorsTracker(editorService, modelService); this._toDispose.push(this._editorTracker); @@ -450,6 +484,7 @@ export class MainThreadEditors { this._toDispose.push(this._editorTracker.onDidUpdateTextEditors(() => this._updateActiveAndVisibleTextEditors())); this._toDispose.push(this._editorTracker.onChangedFocusedTextEditor((focusedTextEditorId) => this._updateActiveAndVisibleTextEditors())); this._toDispose.push(eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, () => this._updateActiveAndVisibleTextEditors())); + this._toDispose.push(eventService.addListener2(EventType.EDITOR_POSITION_CHANGED, () => this._updateActiveAndVisibleTextEditors())); } public dispose(): void { @@ -473,7 +508,8 @@ export class MainThreadEditors { id: id, document: textEditor.getModel().getAssociatedResource(), options: textEditor.getConfiguration(), - selections: textEditor.getSelections() + selections: textEditor.getSelections(), + editorPosition: this._findEditorPosition(textEditor) }); this._textEditorsListenersMap[id] = toDispose; @@ -489,16 +525,22 @@ export class MainThreadEditors { } private _updateActiveAndVisibleTextEditors(): void { + + // active and visible editors let visibleEditors = this._editorTracker.getVisibleTextEditorIds(); let activeEditor = this._findActiveTextEditorId(); - - if (activeEditor === this._activeTextEditor && arrayEquals(this._visibleEditors, visibleEditors, (a, b) => a === b)) { - // no change - return; + if (activeEditor !== this._activeTextEditor || !arrayEquals(this._visibleEditors, visibleEditors, (a, b) => a === b)) { + this._activeTextEditor = activeEditor; + this._visibleEditors = visibleEditors; + this._proxy._acceptActiveEditorAndVisibleEditors(this._activeTextEditor, this._visibleEditors); + } + + // editor columns + let editorPositionData = this._getTextEditorPositionData(); + if (!objectEquals(this._editorPositionData, editorPositionData)) { + this._editorPositionData = editorPositionData; + this._proxy._acceptEditorPositionData(this._editorPositionData); } - this._activeTextEditor = activeEditor; - this._visibleEditors = visibleEditors; - this._proxy._acceptActiveEditorAndVisibleEditors(this._activeTextEditor, this._visibleEditors); } private _findActiveTextEditorId(): string { @@ -527,6 +569,33 @@ export class MainThreadEditors { return this._editorTracker.findTextEditorIdFor((editor).getModifiedEditor()); } + private _findEditorPosition(editor: MainThreadTextEditor): EditorPosition { + for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) { + if (editor.matches(workbenchEditor)) { + return workbenchEditor.position; + } + } + } + + private _getTextEditorPositionData(): ITextEditorPositionData { + let result: ITextEditorPositionData = Object.create(null); + for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) { + let editor = workbenchEditor.getControl(); + // Substitute for (editor instanceof ICodeEditor) + if (!editor || typeof editor.getEditorType !== 'function') { + // Not a text editor... + continue; + } + if (editor.getEditorType() === EditorType.ICodeEditor) { + let id = this._editorTracker.findTextEditorIdFor(editor); + if (id) { + result[id] = workbenchEditor.position; + } + } + } + return result; + } + // --- from plugin host process _tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise { diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 087cd1949ab..0e38c558af8 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -111,6 +111,18 @@ export function fromViewColumn(column?: vscode.ViewColumn): EditorPosition { return editorColumn; } +export function toViewColumn(position?: EditorPosition): vscode.ViewColumn { + if (typeof position !== 'number') { + return; + } + if (position === EditorPosition.LEFT) { + return types.ViewColumn.One; + } else if (position === EditorPosition.CENTER) { + return types.ViewColumn.Two; + } else if (position === EditorPosition.RIGHT) { + return types.ViewColumn.Three; + } +} export function fromFormattedString(value: vscode.MarkedString): IHTMLContentElement { if (typeof value === 'string') { diff --git a/src/vs/workbench/browser/parts/editor/baseEditor.ts b/src/vs/workbench/browser/parts/editor/baseEditor.ts index 22498d48d4f..c1d22ff54e2 100644 --- a/src/vs/workbench/browser/parts/editor/baseEditor.ts +++ b/src/vs/workbench/browser/parts/editor/baseEditor.ts @@ -9,6 +9,7 @@ import {Action, IAction} from 'vs/base/common/actions'; import {ActionBarContributor} from 'vs/workbench/browser/actionBarRegistry'; import types = require('vs/base/common/types'); import {Builder} from 'vs/base/browser/builder'; +import {EventType, EditorEvent} from 'vs/workbench/common/events'; import {Registry} from 'vs/platform/platform'; import {Viewlet} from 'vs/workbench/browser/viewlet'; import {EditorInput, IFileEditorInput, EditorOptions} from 'vs/workbench/common/editor'; @@ -113,6 +114,7 @@ export abstract class BaseEditor extends Viewlet implements IEditor { */ public changePosition(position: Position): void { this._position = position; + this.emit(EventType.EDITOR_POSITION_CHANGED, new EditorEvent(this, this.getId(), this.input, this.options, this.position)); } /** diff --git a/src/vs/workbench/common/events.ts b/src/vs/workbench/common/events.ts index 8f2d01f1c9e..65bc12fd3bd 100644 --- a/src/vs/workbench/common/events.ts +++ b/src/vs/workbench/common/events.ts @@ -69,6 +69,11 @@ export class EventType { */ static EDITOR_SET_INPUT_ERROR = 'editorSetInputError'; + /** + * Event type for when the editor position has been changed + */ + static EDITOR_POSITION_CHANGED = 'editorPositionChanged'; + /** * An event type that fires when a text editor changes its selection. */