Skip to content

Commit

Permalink
Support language client usage independent of wrapper and allow to con…
Browse files Browse the repository at this point in the history
…figure and init vscode api independently
  • Loading branch information
kaisalmen committed Nov 14, 2024
1 parent 154defd commit a4d67db
Show file tree
Hide file tree
Showing 33 changed files with 352 additions and 274 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"LICENSE"
],
"dependencies": {
"@codingame/monaco-vscode-configuration-service-override": "~11.0.1",
"@codingame/monaco-vscode-extensions-service-override": "~11.0.1",
"@codingame/monaco-vscode-languages-service-override": "~11.0.1",
"@codingame/monaco-vscode-localization-service-override": "~11.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/commonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { MonacoLanguageClient } from './client.js';

export type ConnetionConfigOptions = WebSocketConfigOptionsDirect | WebSocketConfigOptionsParams | WebSocketConfigOptionsUrl | WorkerConfigOptionsParams | WorkerConfigOptionsDirect;
export type ConnectionConfigOptions = WebSocketConfigOptionsDirect | WebSocketConfigOptionsParams | WebSocketConfigOptionsUrl | WorkerConfigOptionsParams | WorkerConfigOptionsDirect;

export interface WebSocketCallOptions {
/** Adds handle on languageClient */
Expand Down
57 changes: 31 additions & 26 deletions packages/client/src/vscode/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { EnvironmentOverride } from 'vscode/workbench';
import { Logger } from 'monaco-languageclient/tools';
import { FakeWorker as Worker } from './fakeWorker.js';
import { setUnexpectedErrorHandler } from 'vscode/monaco';
import { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override';

export interface MonacoEnvironmentEnhanced extends monaco.Environment {
vscodeInitialising?: boolean;
Expand All @@ -26,21 +27,24 @@ export interface MonacoEnvironmentEnhanced extends monaco.Environment {
export interface UserConfiguration {
json?: string;
}
export interface ViewsConfig {
viewServiceType: 'EditorService' | 'ViewsService' | 'WorkspaceService';
openEditorFunc?: OpenEditor;
viewsInitFunc?: () => void;
}

export interface VscodeApiConfig {
userServices?: monaco.editor.IEditorOverrideServices;
enableTextmate: boolean;
vscodeApiInitPerformExternally?: boolean;
serviceOverrides?: monaco.editor.IEditorOverrideServices;
enableExtHostWorker?: boolean;
workspaceConfig?: IWorkbenchConstructionOptions;
userConfiguration?: UserConfiguration;
viewsConfig?: {
viewServiceType: 'EditorService' | 'ViewsService' | 'WorkspaceService';
openEditorFunc?: OpenEditor;
viewsInitFunc?: () => void;
},
viewsConfig?: ViewsConfig,
envOptions?: EnvironmentOverride;
}

export interface InitVscodeApiInstructions extends VscodeApiConfig {
export interface InitServicesInstructions {
htmlContainer: HTMLElement;
caller?: string;
performServiceConsistencyChecks?: () => boolean;
Expand Down Expand Up @@ -82,13 +86,15 @@ export const reportServiceLoading = (services: monaco.editor.IEditorOverrideServ
}
};

export const mergeServices = (services: monaco.editor.IEditorOverrideServices, overrideServices: monaco.editor.IEditorOverrideServices) => {
for (const [name, service] of Object.entries(services)) {
overrideServices[name] = service;
export const mergeServices = (overrideServices: monaco.editor.IEditorOverrideServices, services?: monaco.editor.IEditorOverrideServices) => {
if (services !== undefined) {
for (const [name, service] of Object.entries(services)) {
overrideServices[name] = service;
}
}
};

export const initServices = async (instructions: InitVscodeApiInstructions) => {
export const initServices = async (vscodeApiConfig: VscodeApiConfig, instructions: InitServicesInstructions) => {
const envEnhanced = initEnhancedMonacoEnvironment();

if (!(envEnhanced.vscodeInitialising ?? false)) {
Expand All @@ -98,12 +104,14 @@ export const initServices = async (instructions: InitVscodeApiInstructions) => {
envEnhanced.vscodeInitialising = true;
instructions.logger?.debug(`Initializing vscode services. Caller: ${instructions.caller ?? 'unknown'}`);

await importAllServices(instructions);
instructions.viewsConfig?.viewsInitFunc?.();
await importAllServices(vscodeApiConfig, instructions);
vscodeApiConfig.viewsConfig?.viewsInitFunc?.();
instructions.logger?.debug('Initialization of vscode services completed successfully.');

envEnhanced.vscodeApiInitialised = true;
}

await updateUserConfiguration(vscodeApiConfig.userConfiguration?.json ?? JSON.stringify({}));
}
};

Expand All @@ -118,22 +126,20 @@ export const initServices = async (instructions: InitVscodeApiInstructions) => {
* - languages
* - model
*/
export const importAllServices = async (instructions: InitVscodeApiInstructions) => {
const userServices: monaco.editor.IEditorOverrideServices = instructions.userServices ?? {};
export const importAllServices = async (vscodeApiConfig: VscodeApiConfig, instructions: InitServicesInstructions) => {
const services = await supplyRequiredServices();

const lcRequiredServices = await supplyRequiredServices();
mergeServices(services, vscodeApiConfig.serviceOverrides);
await configureExtHostWorker(vscodeApiConfig.enableExtHostWorker === true, services);

mergeServices(lcRequiredServices, userServices);
await configureExtHostWorker(instructions.enableExtHostWorker === true, userServices);

reportServiceLoading(userServices, instructions.logger);
reportServiceLoading(services, instructions.logger);

if (instructions.performServiceConsistencyChecks === undefined ||
(typeof instructions.performServiceConsistencyChecks === 'function' && instructions.performServiceConsistencyChecks())) {
if (instructions.viewsConfig?.viewServiceType === 'ViewsService' || instructions.viewsConfig?.viewServiceType === 'WorkspaceService') {
await initialize(userServices, instructions.htmlContainer, instructions.workspaceConfig, instructions.envOptions);
if (vscodeApiConfig.viewsConfig?.viewServiceType === 'ViewsService' || vscodeApiConfig.viewsConfig?.viewServiceType === 'WorkspaceService') {
await initialize(services, instructions.htmlContainer, vscodeApiConfig.workspaceConfig, vscodeApiConfig.envOptions);
} else {
await initialize(userServices, undefined, instructions.workspaceConfig, instructions.envOptions);
await initialize(services, undefined, vscodeApiConfig.workspaceConfig, vscodeApiConfig.envOptions);
}
}

Expand All @@ -153,10 +159,9 @@ export const configureExtHostWorker = async (enableExtHostWorker: boolean, userS
options: fakeWorker.options
};

const extHostServices = {
mergeServices(userServices, {
...getExtensionServiceOverride(workerConfig),
};
mergeServices(extHostServices, userServices);
});
}
};

Expand Down
7 changes: 4 additions & 3 deletions packages/examples/src/appPlayground/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ export const runApplicationPlayground = async () => {
const wrapperConfig: WrapperConfig = {
id: 'AAP',
logLevel: LogLevel.Debug,
htmlContainer: document.body,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getConfigurationServiceOverride(),
...getKeybindingsServiceOverride(),
...getLifecycleServiceOverride(),
Expand Down Expand Up @@ -106,8 +108,7 @@ export const runApplicationPlayground = async () => {
}
}
}],
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: document.body
monacoWorkerFactory: configureMonacoWorkers
}
};

Expand Down
12 changes: 5 additions & 7 deletions packages/examples/src/bare/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { initServices } from 'monaco-languageclient/vscode/services';
import { LogLevel } from 'vscode/services';
// monaco-editor does not supply json highlighting with the json worker,
// that's why we use the textmate extension from VSCode
import getThemeServiceOverride from '@codingame/monaco-vscode-theme-service-override';
import getTextmateServiceOverride from '@codingame/monaco-vscode-textmate-service-override';
import getConfigurationServiceOverride from '@codingame/monaco-vscode-configuration-service-override';
import '@codingame/monaco-vscode-theme-defaults-default-extension';
import '@codingame/monaco-vscode-json-default-extension';
Expand All @@ -24,11 +22,11 @@ export const runClient = async () => {
const logger = new ConsoleLogger(LogLevel.Debug);
const htmlContainer = document.getElementById('monaco-editor-root')!;
await initServices({
userServices: {
...getConfigurationServiceOverride(),
...getThemeServiceOverride(),
...getTextmateServiceOverride(),
},
enableTextmate: true,
serviceOverrides: {
...getConfigurationServiceOverride()
}
}, {
htmlContainer,
logger
});
Expand Down
7 changes: 4 additions & 3 deletions packages/examples/src/browser/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ export const runBrowserEditor = async () => {
const wrapper = new MonacoEditorLanguageClientWrapper();
const jsonClientUserConfig: WrapperConfig = {
logLevel: LogLevel.Debug,
htmlContainer,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getKeybindingsServiceOverride(),
},
userConfiguration: {
Expand All @@ -52,8 +54,7 @@ export const runBrowserEditor = async () => {
}
},
useDiffEditor: false,
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer
monacoWorkerFactory: configureMonacoWorkers
}
};
await wrapper.init(jsonClientUserConfig);
Expand Down
7 changes: 4 additions & 3 deletions packages/examples/src/clangd/client/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const createWrapperConfig = async (config: {
}): Promise<WrapperConfig> => {
return {
logLevel: LogLevel.Debug,
htmlContainer: config.htmlContainer,
languageClientConfigs: {
LANGUAGE_ID: {
name: 'Clangd WASM Language Server',
Expand All @@ -55,7 +56,8 @@ export const createWrapperConfig = async (config: {
}
},
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getConfigurationServiceOverride(),
...getKeybindingsServiceOverride(),
...getLifecycleServiceOverride(),
Expand Down Expand Up @@ -119,8 +121,7 @@ export const createWrapperConfig = async (config: {
}
}
}],
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: config.htmlContainer
monacoWorkerFactory: configureMonacoWorkers
}
};
};
7 changes: 4 additions & 3 deletions packages/examples/src/eclipse.jdt.ls/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ export const runEclipseJdtLsClient = () => {

const userConfig: WrapperConfig = {
logLevel: LogLevel.Debug,
htmlContainer: document.getElementById('monaco-editor-root')!,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getKeybindingsServiceOverride(),
},
userConfiguration: {
Expand All @@ -44,8 +46,7 @@ export const runEclipseJdtLsClient = () => {
}
},
useDiffEditor: false,
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: document.getElementById('monaco-editor-root')!
monacoWorkerFactory: configureMonacoWorkers
},
languageClientConfigs: {
java: {
Expand Down
7 changes: 4 additions & 3 deletions packages/examples/src/groovy/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ File file = new File("E:/Example.txt");

const userConfig: WrapperConfig = {
logLevel: LogLevel.Debug,
htmlContainer: document.getElementById('monaco-editor-root')!,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getKeybindingsServiceOverride(),
},
userConfiguration: {
Expand All @@ -40,8 +42,7 @@ const userConfig: WrapperConfig = {
}
},
useDiffEditor: false,
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: document.getElementById('monaco-editor-root')!
monacoWorkerFactory: configureMonacoWorkers
},
languageClientConfigs: {
groovy: {
Expand Down
7 changes: 4 additions & 3 deletions packages/examples/src/json/client/wrapperWs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ export const buildJsonClientUserConfig = (params: {
}): WrapperConfig => {
return {
logLevel: LogLevel.Debug,
htmlContainer: params.htmlContainer,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getKeybindingsServiceOverride(),
},
userConfiguration: {
Expand All @@ -43,8 +45,7 @@ export const buildJsonClientUserConfig = (params: {
}
},
useDiffEditor: false,
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: params.htmlContainer
monacoWorkerFactory: configureMonacoWorkers
},
languageClientConfigs: {
json: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export const setupLangiumClientClassic = async (): Promise<WrapperConfig> => {
const langiumWorker = loadLangiumWorker();
return {
logLevel: LogLevel.Debug,
htmlContainer: document.getElementById('monaco-editor-root')!,
vscodeApiConfig: {
userServices: {
enableTextmate: false,
serviceOverrides: {
...getConfigurationServiceOverride(),
...getKeybindingsServiceOverride()
}
Expand Down Expand Up @@ -46,8 +48,7 @@ export const setupLangiumClientClassic = async (): Promise<WrapperConfig> => {
useWorkerFactory({
logger
});
},
htmlContainer: document.getElementById('monaco-editor-root')!
}
},
languageClientConfigs: {
langium: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ export const setupLangiumClientExtended = async (): Promise<WrapperConfig> => {

return {
logLevel: LogLevel.Debug,
htmlContainer: document.getElementById('monaco-editor-root')!,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getKeybindingsServiceOverride()
},
userConfiguration: {
Expand Down Expand Up @@ -74,8 +76,7 @@ export const setupLangiumClientExtended = async (): Promise<WrapperConfig> => {
},
filesOrContents: extensionFilesOrContents
}],
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: document.getElementById('monaco-editor-root')!
monacoWorkerFactory: configureMonacoWorkers
},
languageClientConfigs: {
langium: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ export const createLangiumGlobalConfig = async (params: {

return {
logLevel: LogLevel.Debug,
htmlContainer: params.htmlContainer,
vscodeApiConfig: {
userServices: {
enableTextmate: true,
serviceOverrides: {
...getKeybindingsServiceOverride(),
...getLifecycleServiceOverride(),
...getLocalizationServiceOverride(createDefaultLocaleConfiguration()),
Expand Down Expand Up @@ -99,8 +101,7 @@ export const createLangiumGlobalConfig = async (params: {
},
filesOrContents: extensionFilesOrContents
}],
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: params.htmlContainer
monacoWorkerFactory: configureMonacoWorkers
},
languageClientConfigs
};
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/src/langium/statemachine/main-react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const runStatemachineReact = async () => {
worker: loadStatemachineWorkerRegular(),
htmlContainer: document.getElementById('monaco-editor-root')!
});
const root = ReactDOM.createRoot(wrapperConfig.editorAppConfig.htmlContainer);
const root = ReactDOM.createRoot(wrapperConfig.htmlContainer);

try {
document.querySelector('#button-start')?.addEventListener('click', async () => {
Expand Down
Loading

0 comments on commit a4d67db

Please sign in to comment.