@codingame/monaco-vscode-extensions-service-override
Version:
VSCode public API plugged on the monaco editor - extensions service-override
402 lines (398 loc) • 18.9 kB
JavaScript
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
import { Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
import { DisposableStore, DisposableMap, combinedDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
import { isCodeEditor, isDiffEditor } from '@codingame/monaco-vscode-api/vscode/vs/editor/browser/editorBrowser';
import { ICodeEditorService } from '@codingame/monaco-vscode-api/vscode/vs/editor/browser/services/codeEditorService.service';
import { shouldSynchronizeModel } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/model';
import { IModelService } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/services/model.service';
import { ITextModelService } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/services/resolverService.service';
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
import { extHostCustomer } from '../../services/extensions/common/extHostCustomers.js';
import { MainThreadDocuments } from './mainThreadDocuments.js';
import { MainThreadTextEditor } from './mainThreadEditor.js';
import { MainThreadTextEditors } from './mainThreadEditors.js';
import { ExtHostContext, MainContext } from '@codingame/monaco-vscode-api/vscode/vs/workbench/api/common/extHost.protocol';
import { editorGroupToColumn } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorGroupColumn';
import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
import { IEditorGroupsService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorGroupsService.service';
import { ITextFileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/textfile/common/textfiles.service';
import { IWorkbenchEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service';
import { IWorkingCopyFileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/workingCopy/common/workingCopyFileService.service';
import { IUriIdentityService } from '@codingame/monaco-vscode-api/vscode/vs/platform/uriIdentity/common/uriIdentity.service';
import { IClipboardService } from '@codingame/monaco-vscode-api/vscode/vs/platform/clipboard/common/clipboardService.service';
import { IPathService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/path/common/pathService.service';
import { diffSets, diffMaps } from '@codingame/monaco-vscode-api/vscode/vs/base/common/collections';
import { IPaneCompositePartService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/panecomposite/browser/panecomposite.service';
import { ViewContainerLocation } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/views';
import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
import { IQuickDiffModelService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/scm/browser/quickDiffModel.service';
class TextEditorSnapshot {
constructor(editor) {
this.editor = editor;
this.id = `${editor.getId()},${editor.getModel().id}`;
}
}
class DocumentAndEditorStateDelta {
constructor(
removedDocuments,
addedDocuments,
removedEditors,
addedEditors,
oldActiveEditor,
newActiveEditor
) {
this.removedDocuments = removedDocuments;
this.addedDocuments = addedDocuments;
this.removedEditors = removedEditors;
this.addedEditors = addedEditors;
this.oldActiveEditor = oldActiveEditor;
this.newActiveEditor = newActiveEditor;
this.isEmpty = this.removedDocuments.length === 0 && this.addedDocuments.length === 0 && this.removedEditors.length === 0 && this.addedEditors.length === 0 && oldActiveEditor === newActiveEditor;
}
toString() {
let ret = "DocumentAndEditorStateDelta\n";
ret += `\tRemoved Documents: [${( this.removedDocuments.map(d => ( d.uri.toString(true)))).join(", ")}]\n`;
ret += `\tAdded Documents: [${( this.addedDocuments.map(d => ( d.uri.toString(true)))).join(", ")}]\n`;
ret += `\tRemoved Editors: [${( this.removedEditors.map(e => e.id)).join(", ")}]\n`;
ret += `\tAdded Editors: [${( this.addedEditors.map(e => e.id)).join(", ")}]\n`;
ret += `\tNew Active Editor: ${this.newActiveEditor}\n`;
return ret;
}
}
class DocumentAndEditorState {
static compute(before, after) {
if (!before) {
return ( new DocumentAndEditorStateDelta([], [...( after.documents.values())], [], [...( after.textEditors.values())], undefined, after.activeEditor));
}
const documentDelta = diffSets(before.documents, after.documents);
const editorDelta = diffMaps(before.textEditors, after.textEditors);
const oldActiveEditor = before.activeEditor !== after.activeEditor ? before.activeEditor : undefined;
const newActiveEditor = before.activeEditor !== after.activeEditor ? after.activeEditor : undefined;
return ( new DocumentAndEditorStateDelta(
documentDelta.removed,
documentDelta.added,
editorDelta.removed,
editorDelta.added,
oldActiveEditor,
newActiveEditor
));
}
constructor(documents, textEditors, activeEditor) {
this.documents = documents;
this.textEditors = textEditors;
this.activeEditor = activeEditor;
}
}
var ActiveEditorOrder;
(function(ActiveEditorOrder) {
ActiveEditorOrder[ActiveEditorOrder["Editor"] = 0] = "Editor";
ActiveEditorOrder[ActiveEditorOrder["Panel"] = 1] = "Panel";
})(ActiveEditorOrder || (ActiveEditorOrder = {}));
let MainThreadDocumentAndEditorStateComputer = class MainThreadDocumentAndEditorStateComputer {
constructor(
_onDidChangeState,
_modelService,
_codeEditorService,
_editorService,
_paneCompositeService
) {
this._onDidChangeState = _onDidChangeState;
this._modelService = _modelService;
this._codeEditorService = _codeEditorService;
this._editorService = _editorService;
this._paneCompositeService = _paneCompositeService;
this._toDispose = ( new DisposableStore());
this._toDisposeOnEditorRemove = ( new DisposableMap());
this._activeEditorOrder = ActiveEditorOrder.Editor;
this._modelService.onModelAdded(this._updateStateOnModelAdd, this, this._toDispose);
this._modelService.onModelRemoved(_ => this._updateState(), this, this._toDispose);
this._editorService.onDidActiveEditorChange(_ => this._updateState(), this, this._toDispose);
this._codeEditorService.onCodeEditorAdd(this._onDidAddEditor, this, this._toDispose);
this._codeEditorService.onCodeEditorRemove(this._onDidRemoveEditor, this, this._toDispose);
this._codeEditorService.listCodeEditors().forEach(this._onDidAddEditor, this);
Event.filter(
this._paneCompositeService.onDidPaneCompositeOpen,
event => event.viewContainerLocation === ViewContainerLocation.Panel
)(
_ => this._activeEditorOrder = ActiveEditorOrder.Panel,
undefined,
this._toDispose
);
Event.filter(
this._paneCompositeService.onDidPaneCompositeClose,
event => event.viewContainerLocation === ViewContainerLocation.Panel
)(
_ => this._activeEditorOrder = ActiveEditorOrder.Editor,
undefined,
this._toDispose
);
this._editorService.onDidVisibleEditorsChange(
_ => this._activeEditorOrder = ActiveEditorOrder.Editor,
undefined,
this._toDispose
);
this._updateState();
}
dispose() {
this._toDispose.dispose();
this._toDisposeOnEditorRemove.dispose();
}
_onDidAddEditor(e) {
this._toDisposeOnEditorRemove.set(e.getId(), combinedDisposable(
e.onDidChangeModel(() => this._updateState()),
e.onDidFocusEditorText(() => this._updateState()),
e.onDidFocusEditorWidget(() => this._updateState(e))
));
this._updateState();
}
_onDidRemoveEditor(e) {
const id = e.getId();
if (( this._toDisposeOnEditorRemove.has(id))) {
this._toDisposeOnEditorRemove.deleteAndDispose(id);
this._updateState();
}
}
_updateStateOnModelAdd(model) {
if (!shouldSynchronizeModel(model)) {
return;
}
if (!this._currentState) {
this._updateState();
return;
}
this._currentState = ( new DocumentAndEditorState(
this._currentState.documents.add(model),
this._currentState.textEditors,
this._currentState.activeEditor
));
this._onDidChangeState(( new DocumentAndEditorStateDelta([], [model], [], [], undefined, undefined)));
}
_updateState(widgetFocusCandidate) {
const models = ( new Set());
for (const model of this._modelService.getModels()) {
if (shouldSynchronizeModel(model)) {
models.add(model);
}
}
const editors = ( new Map());
let activeEditor = null;
for (const editor of this._codeEditorService.listCodeEditors()) {
if (editor.isSimpleWidget) {
continue;
}
const model = editor.getModel();
if (
editor.hasModel() && model && shouldSynchronizeModel(model) && !model.isDisposed() && Boolean(this._modelService.getModel(model.uri))) {
const apiEditor = ( new TextEditorSnapshot(editor));
editors.set(apiEditor.id, apiEditor);
if (editor.hasTextFocus() || (widgetFocusCandidate === editor && editor.hasWidgetFocus())) {
activeEditor = apiEditor.id;
}
}
}
if (!activeEditor) {
let candidate;
if (this._activeEditorOrder === ActiveEditorOrder.Editor) {
candidate = this._getActiveEditorFromEditorPart() || this._getActiveEditorFromPanel();
} else {
candidate = this._getActiveEditorFromPanel() || this._getActiveEditorFromEditorPart();
}
if (candidate) {
for (const snapshot of ( editors.values())) {
if (candidate === snapshot.editor) {
activeEditor = snapshot.id;
}
}
}
}
const newState = ( new DocumentAndEditorState(models, editors, activeEditor));
const delta = DocumentAndEditorState.compute(this._currentState, newState);
if (!delta.isEmpty) {
this._currentState = newState;
this._onDidChangeState(delta);
}
}
_getActiveEditorFromPanel() {
const panel = this._paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel);
if (panel !== undefined) {
const control = panel.getControl();
if (isCodeEditor(control)) {
return control;
}
}
return undefined;
}
_getActiveEditorFromEditorPart() {
let activeTextEditorControl = this._editorService.activeTextEditorControl;
if (isDiffEditor(activeTextEditorControl)) {
activeTextEditorControl = activeTextEditorControl.getModifiedEditor();
}
return activeTextEditorControl;
}
};
MainThreadDocumentAndEditorStateComputer = ( __decorate([( __param(1, IModelService)), ( __param(2, ICodeEditorService)), ( __param(3, IEditorService)), ( __param(4, IPaneCompositePartService))], MainThreadDocumentAndEditorStateComputer));
let MainThreadDocumentsAndEditors = class MainThreadDocumentsAndEditors {
constructor(
extHostContext,
_modelService,
_textFileService,
_editorService,
codeEditorService,
fileService,
textModelResolverService,
_editorGroupService,
paneCompositeService,
environmentService,
workingCopyFileService,
uriIdentityService,
_clipboardService,
pathService,
configurationService,
quickDiffModelService
) {
this._modelService = _modelService;
this._textFileService = _textFileService;
this._editorService = _editorService;
this._editorGroupService = _editorGroupService;
this._clipboardService = _clipboardService;
this._toDispose = ( new DisposableStore());
this._textEditors = ( new Map());
this._proxy = ( extHostContext.getProxy(ExtHostContext.ExtHostDocumentsAndEditors));
this._mainThreadDocuments = this._toDispose.add(( new MainThreadDocuments(
extHostContext,
this._modelService,
this._textFileService,
fileService,
textModelResolverService,
environmentService,
uriIdentityService,
workingCopyFileService,
pathService
)));
extHostContext.set(MainContext.MainThreadDocuments, this._mainThreadDocuments);
this._mainThreadEditors = this._toDispose.add(( new MainThreadTextEditors(
this,
extHostContext,
codeEditorService,
this._editorService,
this._editorGroupService,
configurationService,
quickDiffModelService,
uriIdentityService
)));
extHostContext.set(MainContext.MainThreadTextEditors, this._mainThreadEditors);
this._toDispose.add(( new MainThreadDocumentAndEditorStateComputer(
delta => this._onDelta(delta),
_modelService,
codeEditorService,
this._editorService,
paneCompositeService
)));
}
dispose() {
this._toDispose.dispose();
}
_onDelta(delta) {
const removedEditors = [];
const addedEditors = [];
const removedDocuments = ( delta.removedDocuments.map(m => m.uri));
for (const apiEditor of delta.addedEditors) {
const mainThreadEditor = ( new MainThreadTextEditor(apiEditor.id, apiEditor.editor.getModel(), apiEditor.editor, {
onGainedFocus() {},
onLostFocus() {}
}, this._mainThreadDocuments, this._modelService, this._clipboardService));
this._textEditors.set(apiEditor.id, mainThreadEditor);
addedEditors.push(mainThreadEditor);
}
for (const {
id
} of delta.removedEditors) {
const mainThreadEditor = this._textEditors.get(id);
if (mainThreadEditor) {
mainThreadEditor.dispose();
this._textEditors.delete(id);
removedEditors.push(id);
}
}
const extHostDelta = Object.create(null);
let empty = true;
if (delta.newActiveEditor !== undefined) {
empty = false;
extHostDelta.newActiveEditor = delta.newActiveEditor;
}
if (removedDocuments.length > 0) {
empty = false;
extHostDelta.removedDocuments = removedDocuments;
}
if (removedEditors.length > 0) {
empty = false;
extHostDelta.removedEditors = removedEditors;
}
if (delta.addedDocuments.length > 0) {
empty = false;
extHostDelta.addedDocuments = ( delta.addedDocuments.map(m => this._toModelAddData(m)));
}
if (delta.addedEditors.length > 0) {
empty = false;
extHostDelta.addedEditors = ( addedEditors.map(e => this._toTextEditorAddData(e)));
}
if (!empty) {
this._proxy.$acceptDocumentsAndEditorsDelta(extHostDelta);
removedDocuments.forEach(this._mainThreadDocuments.handleModelRemoved, this._mainThreadDocuments);
delta.addedDocuments.forEach(this._mainThreadDocuments.handleModelAdded, this._mainThreadDocuments);
removedEditors.forEach(this._mainThreadEditors.handleTextEditorRemoved, this._mainThreadEditors);
addedEditors.forEach(this._mainThreadEditors.handleTextEditorAdded, this._mainThreadEditors);
}
}
_toModelAddData(model) {
return {
uri: model.uri,
versionId: model.getVersionId(),
lines: model.getLinesContent(),
EOL: model.getEOL(),
languageId: model.getLanguageId(),
isDirty: this._textFileService.isDirty(model.uri),
encoding: this._textFileService.getEncoding(model.uri)
};
}
_toTextEditorAddData(textEditor) {
const props = textEditor.getProperties();
return {
id: textEditor.getId(),
documentUri: textEditor.getModel().uri,
options: props.options,
selections: props.selections,
visibleRanges: props.visibleRanges,
editorPosition: this._findEditorPosition(textEditor)
};
}
_findEditorPosition(editor) {
for (const editorPane of this._editorService.visibleEditorPanes) {
if (editor.matches(editorPane)) {
return editorGroupToColumn(this._editorGroupService, editorPane.group);
}
}
return undefined;
}
findTextEditorIdFor(editorPane) {
for (const [id, editor] of this._textEditors) {
if (editor.matches(editorPane)) {
return id;
}
}
return undefined;
}
getIdOfCodeEditor(codeEditor) {
for (const [id, editor] of this._textEditors) {
if (editor.getCodeEditor() === codeEditor) {
return id;
}
}
return undefined;
}
getEditor(id) {
return this._textEditors.get(id);
}
};
MainThreadDocumentsAndEditors = __decorate([extHostCustomer, ( __param(1, IModelService)), ( __param(2, ITextFileService)), ( __param(3, IEditorService)), ( __param(4, ICodeEditorService)), ( __param(5, IFileService)), ( __param(6, ITextModelService)), ( __param(7, IEditorGroupsService)), ( __param(8, IPaneCompositePartService)), ( __param(9, IWorkbenchEnvironmentService)), ( __param(10, IWorkingCopyFileService)), ( __param(11, IUriIdentityService)), ( __param(12, IClipboardService)), ( __param(13, IPathService)), ( __param(14, IConfigurationService)), ( __param(15, IQuickDiffModelService))], MainThreadDocumentsAndEditors);
export { MainThreadDocumentsAndEditors };