Skip to content

Commit

Permalink
Fixed race condition on monaco editor initialization
Browse files Browse the repository at this point in the history
Signed-off-by: Federico Bozzini <[email protected]>
  • Loading branch information
federicobozzini authored and paul-marechal committed Oct 14, 2020
1 parent 64bf4f5 commit 7544095
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
21 changes: 2 additions & 19 deletions packages/monaco/src/browser/monaco-editor-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { MonacoBulkEditService } from './monaco-bulk-edit-service';

import IEditorOverrideServices = monaco.editor.IEditorOverrideServices;
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
import { OS, ContributionProvider } from '@theia/core';
import { ContributionProvider } from '@theia/core';
import { KeybindingRegistry, OpenerService, open, WidgetOpenerOptions, FormatType } from '@theia/core/lib/browser';
import { MonacoResolvedKeybinding } from './monaco-resolved-keybinding';
import { HttpOpenHandlerOptions } from '@theia/core/lib/browser/http-open-handler';
Expand Down Expand Up @@ -67,8 +67,6 @@ export class MonacoEditorProvider {
@inject(OpenerService)
protected readonly openerService: OpenerService;

private isWindowsBackend: boolean = false;

protected _current: MonacoEditor | undefined;
/**
* Returns the last focused MonacoEditor.
Expand All @@ -90,28 +88,13 @@ export class MonacoEditorProvider {
@inject(EditorPreferences) protected readonly editorPreferences: EditorPreferences,
@inject(MonacoQuickOpenService) protected readonly quickOpenService: MonacoQuickOpenService,
@inject(MonacoDiffNavigatorFactory) protected readonly diffNavigatorFactory: MonacoDiffNavigatorFactory,
/** @deprecated since 1.6.0 */
@inject(ApplicationServer) protected readonly applicationServer: ApplicationServer,
@inject(monaco.contextKeyService.ContextKeyService) protected readonly contextKeyService: monaco.contextKeyService.ContextKeyService
) {
const staticServices = monaco.services.StaticServices;
const init = staticServices.init.bind(monaco.services.StaticServices);
this.applicationServer.getBackendOS().then(os => {
this.isWindowsBackend = os === OS.Type.Windows;
});

if (staticServices.resourcePropertiesService) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const original = staticServices.resourcePropertiesService.get() as any;
original.getEOL = () => {
const eol = this.editorPreferences['files.eol'];
if (eol) {
if (eol !== 'auto') {
return eol;
}
}
return this.isWindowsBackend ? '\r\n' : '\n';
};
}
monaco.services.StaticServices.init = o => {
const result = init(o);
result[0].set(monaco.services.ICodeEditorService, codeEditorService);
Expand Down
41 changes: 39 additions & 2 deletions packages/monaco/src/browser/monaco-text-model-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { inject, injectable, named } from 'inversify';
import { inject, injectable, named, postConstruct } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { ResourceProvider, ReferenceCollection, Event, MaybePromise, Resource, ContributionProvider } from '@theia/core';
import { ResourceProvider, ReferenceCollection, Event, MaybePromise, Resource, ContributionProvider, OS } from '@theia/core';
import { EditorPreferences, EditorPreferenceChange } from '@theia/editor/lib/browser';
import { MonacoEditorModel } from './monaco-editor-model';
import IReference = monaco.editor.IReference;
import { MonacoToProtocolConverter } from './monaco-to-protocol-converter';
import { ProtocolToMonacoConverter } from './protocol-to-monaco-converter';
import { ILogger } from '@theia/core/lib/common/logger';
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
import { Deferred } from '@theia/core/lib/common/promise-util';
export { IReference };

export const MonacoEditorModelFactory = Symbol('MonacoEditorModelFactory');
Expand All @@ -39,6 +41,12 @@ export interface MonacoEditorModelFactory {
@injectable()
export class MonacoTextModelService implements monaco.editor.ITextModelService {

protected readonly _ready = new Deferred<void>();
/**
* This component does some asynchronous work before being fully initialized.
*/
readonly ready: Promise<void> = this._ready.promise;

protected readonly _models = new ReferenceCollection<string, MonacoEditorModel>(
uri => this.loadModel(new URI(uri))
);
Expand All @@ -62,6 +70,34 @@ export class MonacoTextModelService implements monaco.editor.ITextModelService {
@inject(ILogger)
protected readonly logger: ILogger;

@inject(ApplicationServer)
protected readonly applicationServer!: ApplicationServer;

@postConstruct()
public init(): void {
let isWindowsBackend = false;

this.applicationServer.getBackendOS().then(os => {
isWindowsBackend = os === OS.Type.Windows;
}, () => undefined).then(() => this._ready.resolve());

const staticServices = monaco.services.StaticServices;

if (staticServices.resourcePropertiesService) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const original = staticServices.resourcePropertiesService.get() as any;
original.getEOL = () => {
const eol = this.editorPreferences['files.eol'];
if (eol) {
if (eol !== 'auto') {
return eol;
}
}
return isWindowsBackend ? '\r\n' : '\n';
};
}
}

get models(): MonacoEditorModel[] {
return this._models.values();
}
Expand All @@ -79,6 +115,7 @@ export class MonacoTextModelService implements monaco.editor.ITextModelService {
}

protected async loadModel(uri: URI): Promise<MonacoEditorModel> {
await this.ready;
await this.editorPreferences.ready;
const resource = await this.resourceProvider(uri);
const model = await (await this.createModel(resource)).load();
Expand Down

0 comments on commit 7544095

Please sign in to comment.