diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts index be02a99220ba6..340ea021b787f 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts @@ -14,7 +14,7 @@ import { MainThreadTextEditor } from './mainThreadEditor'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { EditorViewColumn, editorGroupToViewColumn } from 'vs/workbench/api/shared/editor'; -import { IEditor } from 'vs/workbench/common/editor'; +import { IEditor as IWorkbenchEditor } from 'vs/workbench/common/editor'; import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { MainThreadDocuments } from 'vs/workbench/api/electron-browser/mainThreadDocuments'; import { MainThreadTextEditors } from 'vs/workbench/api/electron-browser/mainThreadEditors'; @@ -23,9 +23,12 @@ import { IFileService } from 'vs/platform/files/common/files'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { isDiffEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { isDiffEditor, ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { URI } from 'vs/base/common/uri'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; +import { IEditor } from 'vs/editor/common/editorCommon'; namespace mapset { @@ -151,17 +154,23 @@ class DocumentAndEditorState { } } +const enum ActiveEditorOrder { + Editor, Panel +} + class MainThreadDocumentAndEditorStateComputer { private _toDispose: IDisposable[] = []; private _toDisposeOnEditorRemove = new Map(); private _currentState: DocumentAndEditorState; + private _activeEditorOrder: ActiveEditorOrder = ActiveEditorOrder.Editor; constructor( private readonly _onDidChangeState: (delta: DocumentAndEditorStateDelta) => void, @IModelService private readonly _modelService: IModelService, @ICodeEditorService private readonly _codeEditorService: ICodeEditorService, - @IEditorService private readonly _editorService: IEditorService + @IEditorService private readonly _editorService: IEditorService, + @IPanelService private readonly _panelService: IPanelService ) { this._modelService.onModelAdded(this._updateStateOnModelAdd, this, this._toDispose); this._modelService.onModelRemoved(this._updateState, this, this._toDispose); @@ -170,6 +179,10 @@ class MainThreadDocumentAndEditorStateComputer { this._codeEditorService.onCodeEditorRemove(this._onDidRemoveEditor, this, this._toDispose); this._codeEditorService.listCodeEditors().forEach(this._onDidAddEditor, this); + this._panelService.onDidPanelOpen(_ => this._activeEditorOrder = ActiveEditorOrder.Panel, undefined, this._toDispose); + this._panelService.onDidPanelClose(_ => this._activeEditorOrder = ActiveEditorOrder.Editor, undefined, this._toDispose); + this._editorService.onDidVisibleEditorsChange(_ => this._activeEditorOrder = ActiveEditorOrder.Editor, undefined, this._toDispose); + this._updateState(); } @@ -180,7 +193,6 @@ class MainThreadDocumentAndEditorStateComputer { private _onDidAddEditor(e: ICodeEditor): void { this._toDisposeOnEditorRemove.set(e.getId(), e.onDidChangeModel(() => this._updateState())); this._toDisposeOnEditorRemove.set(e.getId(), e.onDidFocusEditorText(() => this._updateState())); - this._toDisposeOnEditorRemove.set(e.getId(), e.onDidBlurEditorText(() => this._updateState())); this._updateState(); } @@ -229,7 +241,6 @@ class MainThreadDocumentAndEditorStateComputer { } } - // editor: only take those that have a not too large model const editors = new Map(); let activeEditor: string = null; @@ -252,13 +263,16 @@ class MainThreadDocumentAndEditorStateComputer { } // active editor: if none of the previous editors had focus we try - // to match the active workbench editor with one of editor we have - // just computed + // to match output panels or the the active workbench editor with + // one of editor we have just computed if (!activeEditor) { - let candidate = this._editorService.activeTextEditorWidget; - if (isDiffEditor(candidate)) { - candidate = candidate.getModifiedEditor(); + let candidate: IEditor; + if (this._activeEditorOrder === ActiveEditorOrder.Editor) { + candidate = this._getActiveEditorFromEditorPart() || this._getActiveEditorFromPanel(); + } else { + candidate = this._getActiveEditorFromPanel() || this._getActiveEditorFromEditorPart(); } + if (candidate) { editors.forEach(snapshot => { if (candidate === snapshot.editor) { @@ -276,6 +290,23 @@ class MainThreadDocumentAndEditorStateComputer { this._onDidChangeState(delta); } } + + private _getActiveEditorFromPanel(): IEditor { + let panel = this._panelService.getActivePanel(); + if (panel instanceof BaseTextEditor && isCodeEditor(panel.getControl())) { + return panel.getControl(); + } else { + return undefined; + } + } + + private _getActiveEditorFromEditorPart(): IEditor { + let result = this._editorService.activeTextEditorWidget; + if (isDiffEditor(result)) { + result = result.getModifiedEditor(); + } + return result; + } } @extHostCustomer @@ -307,7 +338,8 @@ export class MainThreadDocumentsAndEditors { @ITextModelService textModelResolverService: ITextModelService, @IUntitledEditorService untitledEditorService: IUntitledEditorService, @IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService, - @IBulkEditService bulkEditService: IBulkEditService + @IBulkEditService bulkEditService: IBulkEditService, + @IPanelService panelService: IPanelService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentsAndEditors); @@ -319,7 +351,7 @@ export class MainThreadDocumentsAndEditors { extHostContext.set(MainContext.MainThreadTextEditors, mainThreadTextEditors); // It is expected that the ctor of the state computer calls our `_onDelta`. - this._stateComputer = new MainThreadDocumentAndEditorStateComputer(delta => this._onDelta(delta), _modelService, codeEditorService, this._editorService); + this._stateComputer = new MainThreadDocumentAndEditorStateComputer(delta => this._onDelta(delta), _modelService, codeEditorService, this._editorService, panelService); this._toDispose = [ mainThreadDocuments, @@ -430,7 +462,7 @@ export class MainThreadDocumentsAndEditors { return undefined; } - findTextEditorIdFor(editor: IEditor): string { + findTextEditorIdFor(editor: IWorkbenchEditor): string { for (let id in this._textEditors) { if (this._textEditors[id].matches(editor)) { return id; diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts index 2392b091e983e..cec7be76a5517 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts @@ -21,6 +21,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IFileService } from 'vs/platform/files/common/files'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; suite('MainThreadDocumentsAndEditors', () => { @@ -74,7 +75,15 @@ suite('MainThreadDocumentsAndEditors', () => { null, null, editorGroupService, - null + null, + new class extends mock() implements IPanelService { + _serviceBrand: any; + onDidPanelOpen = Event.None; + onDidPanelClose = Event.None; + getActivePanel() { + return null; + } + } ); /* tslint:enable */ }); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index 36b9046aed84a..759c914431b1c 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -29,6 +29,7 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IReference, ImmortalReference } from 'vs/base/common/lifecycle'; import { LabelService } from 'vs/platform/label/common/label'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; suite('MainThreadEditors', () => { @@ -108,6 +109,14 @@ suite('MainThreadEditors', () => { null, editorGroupService, bulkEditService, + new class extends mock() implements IPanelService { + _serviceBrand: any; + onDidPanelOpen = Event.None; + onDidPanelClose = Event.None; + getActivePanel() { + return null; + } + } ); editors = new MainThreadTextEditors(