Skip to content
This repository has been archived by the owner on Mar 22, 2024. It is now read-only.

Commit

Permalink
Merge pull request #45 from TypeFox/issue-32
Browse files Browse the repository at this point in the history
semantic highlighting works with classic editor
  • Loading branch information
kaisalmen authored Sep 19, 2023
2 parents 5112564 + 52e9cdf commit 9115ccb
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 47 deletions.
10 changes: 8 additions & 2 deletions packages/examples/src/langium/config/wrapperLangiumClassic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ export const setupLangiumClientClassic = async (): Promise<UserConfig> => {
languageId: 'langium',
code: code,
useDiffEditor: false,
// configure it like this or in the userConfiguration
editorOptions: {
'semanticHighlighting.enabled': 'configuredByTheme'
'semanticHighlighting.enabled': true
},
languageExtensionConfig: { id: 'langium' },
languageDef: LangiumMonarchContent,
themeData: LangiumTheme,
theme: 'langium-theme'
theme: 'langium-theme',
userConfiguration: {
// or configure the semantic highlighting like this:
// `{ json: "editor.semanticHighlighting.enabled": true }`
json: '{}'
}
}
},
languageClientConfig: {
Expand Down
4 changes: 0 additions & 4 deletions packages/examples/src/langium/wrapperLangium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* ------------------------------------------------------------------------------------------ */

import 'vscode/default-extensions/theme-defaults';
import { updateUserConfiguration } from 'vscode/service-override/configuration';
import { buildWorkerDefinition } from 'monaco-editor-workers';
import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
import { setupLangiumClientVscodeApi } from './config/wrapperLangiumVscode.js';
Expand Down Expand Up @@ -47,9 +46,6 @@ export const startLangiumClientClassic = async () => {
const config = await setupLangiumClientClassic();
wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.start(config);
updateUserConfiguration(`{
"editor.semanticHighlighting.enabled": true
}`);
} catch (e) {
console.log(e);
}
Expand Down
15 changes: 8 additions & 7 deletions packages/monaco-editor-react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EditorAppConfigClassic, MonacoEditorLanguageClientWrapper, UserConfig, WorkerConfigDirect, WorkerConfigOptions } from 'monaco-editor-wrapper';
import { EditorAppClassic, EditorAppConfigClassic, MonacoEditorLanguageClientWrapper, UserConfig, WorkerConfigDirect, WorkerConfigOptions } from 'monaco-editor-wrapper';
import { IDisposable } from 'monaco-editor';
import * as vscode from 'vscode';
import React, { CSSProperties } from 'react';
Expand Down Expand Up @@ -73,17 +73,18 @@ export class MonacoEditorReactComp extends React.Component<MonacoEditorProps> {
}

if (!restarted) {
if (userConfig.wrapperConfig.editorAppConfig.$type === 'classic') {
const options = (userConfig.wrapperConfig.editorAppConfig as EditorAppConfigClassic).editorOptions;
const appConfig = userConfig.wrapperConfig.editorAppConfig;
if (appConfig.$type === 'classic') {
const options = (appConfig as EditorAppConfigClassic).editorOptions;
const prevOptions = (prevProps.userConfig.wrapperConfig.editorAppConfig as EditorAppConfigClassic).editorOptions;
if (options !== prevOptions) {
wrapper.updateEditorOptions((userConfig.wrapperConfig.editorAppConfig as EditorAppConfigClassic).editorOptions ?? {});
if (options !== prevOptions && options !== undefined) {
(wrapper.getMonacoEditorApp() as EditorAppClassic).updateMonacoEditorOptions(options);
}
}

const languageId = userConfig.wrapperConfig.editorAppConfig.languageId;
const languageId = appConfig.languageId;
const code = appConfig.code;
const prevLanguageId = prevProps.userConfig.wrapperConfig.editorAppConfig.languageId;
const code = userConfig.wrapperConfig.editorAppConfig.code;
const prevCode = prevProps.userConfig.wrapperConfig.editorAppConfig.code;
if (languageId !== prevLanguageId && code !== prevCode) {
this.wrapper.updateModel({
Expand Down
23 changes: 15 additions & 8 deletions packages/monaco-editor-wrapper/src/editorAppBase.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { editor, Uri } from 'monaco-editor';
import { createConfiguredEditor, createConfiguredDiffEditor, createModelReference, ITextFileEditorModel } from 'vscode/monaco';
import { IReference } from 'vscode/service-override/editor';
import { updateUserConfiguration as vscodeUpdateUserConfiguratio } from 'vscode/service-override/configuration';
import { ModelUpdate, UserConfig, WrapperConfig } from './wrapper.js';
import { EditorAppConfigClassic } from './editorAppClassic.js';
import { EditorAppConfigVscodeApi } from './editorAppVscodeApi.js';

export type VscodeUserConfiguration = {
json?: string;
}

export type EditorAppBaseConfig = {
languageId: string;
code: string;
Expand All @@ -18,10 +15,15 @@ export type EditorAppBaseConfig = {
codeOriginalUri?: string;
domReadOnly?: boolean;
readOnly?: boolean;
userConfiguration?: UserConfiguration;
}

export type EditorAppType = 'vscodeApi' | 'classic';

export type UserConfiguration = {
json: string;
}

/**
* This is the base class for both Monaco Ediotor Apps:
* - EditorAppClassic
Expand All @@ -43,7 +45,7 @@ export abstract class EditorAppBase {
this.id = id;
}

protected buildConfig(userConfig: UserConfig) {
protected buildConfig(userConfig: UserConfig): EditorAppBaseConfig {
const userAppConfig = userConfig.wrapperConfig.editorAppConfig;
return {
languageId: userAppConfig.languageId,
Expand All @@ -54,6 +56,9 @@ export abstract class EditorAppBase {
codeOriginalUri: userAppConfig.codeOriginalUri ?? undefined,
readOnly: userAppConfig.readOnly ?? false,
domReadOnly: userAppConfig.domReadOnly ?? false,
userConfiguration: userAppConfig.userConfiguration ?? {
json: '{}'
}
};
}

Expand Down Expand Up @@ -201,14 +206,16 @@ export abstract class EditorAppBase {
}
}

updateMonacoEditorOptions(options: editor.IEditorOptions & editor.IGlobalEditorOptions) {
this.editor?.updateOptions(options);
async updateUserConfiguration(config: UserConfiguration) {
if (config.json) {
return vscodeUpdateUserConfiguratio(config.json);
}
return Promise.reject(new Error('Supplied config is undefined'));
}

abstract getAppType(): string;
abstract init(): Promise<void>;
abstract createEditors(container: HTMLElement): Promise<void>;
abstract updateEditorOptions(options: editor.IEditorOptions & editor.IGlobalEditorOptions | VscodeUserConfiguration): void;
abstract getConfig(): EditorAppConfigClassic | EditorAppConfigVscodeApi;
abstract disposeApp(): void;
}
Expand Down
14 changes: 11 additions & 3 deletions packages/monaco-editor-wrapper/src/editorAppClassic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export class EditorAppClassic extends EditorAppBase {
this.config.languageExtensionConfig = userInput.languageExtensionConfig ?? undefined;
this.config.languageDef = userInput.languageDef ?? undefined;
this.config.themeData = userInput.themeData ?? undefined;

// buildConfig ensures userConfiguration is available
if (userInput.editorOptions?.['semanticHighlighting.enabled'] !== undefined) {
const parsedUserConfig = JSON.parse(this.config.userConfiguration!.json);
parsedUserConfig['editor.semanticHighlighting.enabled'] = userInput.editorOptions?.['semanticHighlighting.enabled'];
this.config.userConfiguration!.json = JSON.stringify(parsedUserConfig);
}
}

getAppType(): EditorAppType {
Expand Down Expand Up @@ -100,12 +107,13 @@ export class EditorAppClassic extends EditorAppBase {
}
editor.setTheme(this.config.theme!);

// buildConfig ensures userConfiguration is available
await this.updateUserConfiguration(this.config.userConfiguration!);
this.logger?.info('Init of MonacoConfig was completed.');
return Promise.resolve();
}

async updateEditorOptions(options: editor.IEditorOptions & editor.IGlobalEditorOptions) {
this.updateMonacoEditorOptions(options);
updateMonacoEditorOptions(options: editor.IEditorOptions & editor.IGlobalEditorOptions) {
this.getEditor()?.updateOptions(options);
}

disposeApp(): void {
Expand Down
13 changes: 3 additions & 10 deletions packages/monaco-editor-wrapper/src/editorAppVscodeApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type * as vscode from 'vscode';
import { EditorAppBase, EditorAppBaseConfig, EditorAppType, VscodeUserConfiguration } from './editorAppBase.js';
import { updateUserConfiguration } from 'vscode/service-override/configuration';
import { EditorAppBase, EditorAppBaseConfig, EditorAppType } from './editorAppBase.js';
import { registerExtension, IExtensionManifest, ExtensionHostKind } from 'vscode/extensions';
import { UserConfig } from './wrapper.js';
import { verifyUrlorCreateDataUrl } from './utils.js';
Expand All @@ -11,7 +10,6 @@ export type EditorAppConfigVscodeApi = EditorAppBaseConfig & {
$type: 'vscodeApi';
extension?: IExtensionManifest | object;
extensionFilesOrContents?: Map<string, string | URL>;
userConfiguration?: VscodeUserConfiguration;
};

export type RegisterExtensionResult = {
Expand Down Expand Up @@ -76,16 +74,11 @@ export class EditorAppVscodeApi extends EditorAppBase {
}
}

await this.updateEditorOptions(this.config.userConfiguration ?? {});
// buildConfig ensures userConfiguration is available
await this.updateUserConfiguration(this.config.userConfiguration!);
this.logger?.info('Init of VscodeApiConfig was completed.');
}

async updateEditorOptions(config: VscodeUserConfiguration) {
if (config.json) {
return updateUserConfiguration(config.json);
}
}

disposeApp(): void {
this.disposeEditor();
this.disposeDiffEditor();
Expand Down
4 changes: 2 additions & 2 deletions packages/monaco-editor-wrapper/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import type {
EditorAppBaseConfig,
EditorAppType,
VscodeUserConfiguration,
UserConfiguration,
} from './editorAppBase.js';

import type {
Expand Down Expand Up @@ -68,7 +68,7 @@ export type {
EditorAppConfigVscodeApi,
RegisterExtensionResult,
RegisterLocalProcessExtensionResult,
VscodeUserConfiguration,
UserConfiguration,
WebSocketCallOptions,
LanguageClientConfigType,
WebSocketConfigOptions,
Expand Down
11 changes: 3 additions & 8 deletions packages/monaco-editor-wrapper/src/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { editor } from 'monaco-editor';
import { initServices, wasVscodeApiInitialized, InitializeServiceConfig, MonacoLanguageClient } from 'monaco-languageclient';
import { EditorAppVscodeApi, EditorAppConfigVscodeApi } from './editorAppVscodeApi.js';
import { EditorAppClassic, EditorAppConfigClassic } from './editorAppClassic.js';
import { VscodeUserConfiguration, isVscodeApiEditorApp } from './editorAppBase.js';
import { UserConfiguration, isVscodeApiEditorApp } from './editorAppBase.js';
import { LanguageClientConfig, LanguageClientWrapper } from './languageClientWrapper.js';
import { Logger, LoggerConfig } from './logger.js';

Expand Down Expand Up @@ -67,7 +67,6 @@ export class MonacoEditorLanguageClientWrapper {
this.logger.debug('Init Services', this.serviceConfig.debugLogging);
await initServices(this.serviceConfig);
}

this.languageClientWrapper = new LanguageClientWrapper(userConfig.languageClientConfig, this.logger);
}

Expand Down Expand Up @@ -137,12 +136,8 @@ export class MonacoEditorLanguageClientWrapper {
await this.editorApp?.updateDiffModel(modelUpdate);
}

async updateEditorOptions(options: editor.IEditorOptions & editor.IGlobalEditorOptions | VscodeUserConfiguration): Promise<void> {
if (this.editorApp) {
await this.editorApp.updateEditorOptions(options);
} else {
await Promise.reject('Update was called when editor wrapper was not correctly configured.');
}
updateUserConfiguration(config: UserConfiguration) {
return this.editorApp?.updateUserConfiguration(config);
}

public reportStatus() {
Expand Down
29 changes: 26 additions & 3 deletions packages/monaco-editor-wrapper/test/editorAppBase.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expect, test } from 'vitest';
import { isVscodeApiEditorApp } from 'monaco-editor-wrapper';
import { createWrapperConfig } from './helper.js';
import { EditorAppClassic, isVscodeApiEditorApp } from 'monaco-editor-wrapper';
import { createBaseConfig, createWrapperConfig } from './helper.js';

describe('Test MonacoEditorLanguageClientWrapper', () => {
describe('Test EditorAppBase', () => {

test('isVscodeApiEditorApp: empty EditorAppConfigClassic', () => {
const wrapperConfig = createWrapperConfig('classic');
Expand All @@ -13,4 +13,27 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
const wrapperConfig = createWrapperConfig('vscodeApi');
expect(isVscodeApiEditorApp(wrapperConfig)).toBeTruthy();
});

test('config defaults', () => {
const config = createBaseConfig('classic');
const app = new EditorAppClassic('config defaults', config);
expect(app.getConfig().languageId).toEqual('typescript');
expect(app.getConfig().code).toEqual('');
expect(app.getConfig().codeOriginal).toEqual('');
expect(app.getConfig().useDiffEditor).toBeFalsy();
expect(app.getConfig().codeUri).toBeUndefined();
expect(app.getConfig().codeOriginalUri).toBeUndefined();
expect(app.getConfig().readOnly).toBeFalsy();
expect(app.getConfig().domReadOnly).toBeFalsy();
expect(app.getConfig().userConfiguration?.json).toEqual('{}');
});

test('config userConfiguration', () => {
const config = createBaseConfig('classic');
config.wrapperConfig.editorAppConfig.userConfiguration = {
json: '{ "editor.semanticHighlighting.enabled": true }'
};
const app = new EditorAppClassic('config defaults', config);
expect(app.getConfig().userConfiguration?.json).toEqual('{ "editor.semanticHighlighting.enabled": true }');
});
});
40 changes: 40 additions & 0 deletions packages/monaco-editor-wrapper/test/editorAppClassic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, expect, test } from 'vitest';
import { EditorAppClassic, EditorAppConfigClassic } from 'monaco-editor-wrapper';
import { createBaseConfig } from './helper.js';

const buildConfig = () => {
const config = createBaseConfig('classic');
(config.wrapperConfig.editorAppConfig as EditorAppConfigClassic).editorOptions = {};
return config;
};

describe('Test EditorAppClassic', () => {

test('editorOptions: semanticHighlighting=true', () => {
const config = buildConfig();
const configclassic = config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
configclassic.editorOptions!['semanticHighlighting.enabled'] = true;

const app = new EditorAppClassic('config defaults', config);
expect(configclassic.$type).toEqual('classic');
expect(app.getConfig().userConfiguration?.json).toEqual('{"editor.semanticHighlighting.enabled":true}');
});

test('editorOptions: semanticHighlighting=false', () => {
const config = buildConfig();
const configclassic = config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
configclassic.editorOptions!['semanticHighlighting.enabled'] = false;

const app = new EditorAppClassic('config defaults', config);
expect(app.getConfig().userConfiguration?.json).toEqual('{"editor.semanticHighlighting.enabled":false}');
});

test('editorOptions: semanticHighlighting="configuredByTheme"', () => {
const config = buildConfig();
const configclassic = config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
configclassic.editorOptions!['semanticHighlighting.enabled'] = 'configuredByTheme';

const app = new EditorAppClassic('config defaults', config);
expect(app.getConfig().userConfiguration?.json).toEqual('{"editor.semanticHighlighting.enabled":"configuredByTheme"}');
});
});

0 comments on commit 9115ccb

Please sign in to comment.