From 6237ca9b82af64f9a32113debbd4ca5d51a35e97 Mon Sep 17 00:00:00 2001 From: Kai Salmen Date: Fri, 20 Oct 2023 10:49:01 +0200 Subject: [PATCH] Update to latest monaco-editor-wrapper and monaco-editor-react (#196) * Update to latest monaco-editor-wrapper and monaco-editor-react * Implemented review comments --- .gitignore | 6 - .vscode/launch.json | 15 + README.md | 2 +- core/.gitignore | 2 + core/README.md | 5 + core/package.json | 67 ++ core/src/index.ts | 17 + core/src/monaco-editor-wrapper-utils.ts | 176 ++++ core/tsconfig.json | 15 + .../vite.bundle.ts | 23 +- hugo/.gitignore | 5 + .../scripts/arithmetics/arithmetics-tools.tsx | 2 +- .../scripts/arithmetics/arithmetics.tsx | 6 +- .../scripts/domainmodel/domainmodel.tsx | 8 +- .../assets/scripts/minilogo/minilogo-tools.ts | 2 +- hugo/assets/scripts/minilogo/minilogo.tsx | 6 +- hugo/assets/scripts/monaco-editor-react.ts | 2 - hugo/assets/scripts/sql/constants.ts | 2 +- hugo/assets/scripts/sql/ui.tsx | 6 +- .../scripts/statemachine/statemachine.tsx | 6 +- hugo/assets/scripts/utils.ts | 201 ---- hugo/content/playground/_index.html | 6 +- hugo/content/playground/common.ts | 18 +- hugo/layouts/langium/showcase-page.html | 1 - hugo/package.json | 29 +- hugo/vite.showcase-worker.ts | 2 +- package-lock.json | 991 +++++++++++------- package.json | 15 +- 28 files changed, 954 insertions(+), 682 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 core/.gitignore create mode 100644 core/README.md create mode 100644 core/package.json create mode 100644 core/src/index.ts create mode 100644 core/src/monaco-editor-wrapper-utils.ts create mode 100644 core/tsconfig.json rename hugo/vite.bundle-monaco-editor-react.ts => core/vite.bundle.ts (51%) create mode 100644 hugo/.gitignore delete mode 100644 hugo/assets/scripts/monaco-editor-react.ts delete mode 100644 hugo/assets/scripts/utils.ts diff --git a/.gitignore b/.gitignore index 2e095e84..6504043b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,4 @@ /public/ -/hugo/resources/ -/hugo/static/css/ -hugo/static/libs -hugo/static/showcase/ -hugo/static/libs/ -hugo/static/playground/ node_modules/ .DS_Store .hugo_build.lock diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..abee2eef --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible Node.js debug attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome", + "url": "http://localhost:1313", + "webRoot": "${workspaceFolder}" + } + ] +} diff --git a/README.md b/README.md index bd1fb42d..764e68e8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository contains the assets required to build the Langium website and do Our setup uses TailwindCSS to build the styles which are then copied into the Hugo installation, from which our website is finally built. -Please look into the sub folders [hugo/](hugo/README.md) and [tailwind/](tailwind/README.md). +Please look into the sub folders [core/](core/README.md) [hugo/](hugo/README.md) and [tailwind/](tailwind/README.md). You can find the `showcase/` folder [here](hugo/content/showcase). diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 00000000..b6291f30 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1,2 @@ +bundle/ +dist/ diff --git a/core/README.md b/core/README.md new file mode 100644 index 00000000..4a6fed62 --- /dev/null +++ b/core/README.md @@ -0,0 +1,5 @@ +# core/ + +We utilize [monaco-editor-wrapper](https://www.npmjs.com/package/monaco-editor-wrapper) and [@typefox/monaco-editor-react](https://www.npmjs.com/package/@typefox/monaco-editor-react) to make the monaco-editor intgration a smoother experience. + +This package provides utility `createUserConfig` that provides a fully specified user configuration to be used by either of the two packages. The other purpose is to bundle the code, so it can be integrated with hugo and remove the burden dealing with complex javascript in the hugo build process. diff --git a/core/package.json b/core/package.json new file mode 100644 index 00000000..bcc0ab3a --- /dev/null +++ b/core/package.json @@ -0,0 +1,67 @@ +{ + "name": "langium-website-core", + "version": "1.0.0", + "type": "module", + "description": "Bundling complex sources for hugo", + "author": "TypeFox", + "license": "MIT", + "private": true, + "main": "./dist/index.js", + "module": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./bundle": { + "types": "./dist/index.d.ts", + "default": "./bundle/monaco-editor-wrapper-bundle/index.js" + } + }, + "typesVersions": { + "*": { + ".": [ + "dist/index" + ], + "bundle": [ + "dist/index" + ] + } + }, + "files": [ + "dist", + "bundle", + "src", + "LICENSE", + "README.md" + ], + "scripts": { + "clean": "shx rm -rf ./bundle ./dist", + "compile": "tsc", + "build:bundle": "vite --config vite.bundle.ts build", + "build": "npm run clean && npm run compile && npm run build:bundle" + }, + "devDependencies": { + "@types/react": "~18.2.28", + "@types/react-dom": "~18.2.13", + "@types/vscode": "~1.83.0", + "typescript": "~5.2.2", + "vite": "~4.4.11" + }, + "dependencies": { + "@codingame/monaco-vscode-keybindings-service-override": "~1.83.2", + "@typefox/monaco-editor-react": "2.3.0", + "monaco-editor": "~0.44.0", + "monaco-editor-workers": "~0.44.0", + "monaco-editor-wrapper": "~3.3.0", + "monaco-languageclient": "~6.6.0", + "react": "~18.2.0", + "react-dom": "~18.2.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.83.2 <1.84.0", + "vscode-languageserver": "~8.0.2" + }, + "volta": { + "node": "18.18.1", + "npm": "9.9.0" + } +} diff --git a/core/src/index.ts b/core/src/index.ts new file mode 100644 index 00000000..151921cf --- /dev/null +++ b/core/src/index.ts @@ -0,0 +1,17 @@ +import * as monaco from "monaco-editor"; +import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override'; +import type { MonacoEditorProps } from "@typefox/monaco-editor-react"; +import { MonacoEditorReactComp } from "@typefox/monaco-editor-react"; +import { addMonacoStyles } from 'monaco-editor-wrapper/styles'; + +export * from "monaco-editor-wrapper"; +export type * from "monaco-editor-wrapper"; +export * from "./monaco-editor-wrapper-utils.js"; + +export { + monaco, + MonacoEditorProps, + MonacoEditorReactComp, + addMonacoStyles, + getKeybindingsServiceOverride +} diff --git a/core/src/monaco-editor-wrapper-utils.ts b/core/src/monaco-editor-wrapper-utils.ts new file mode 100644 index 00000000..fd739bff --- /dev/null +++ b/core/src/monaco-editor-wrapper-utils.ts @@ -0,0 +1,176 @@ +import { languages } from "monaco-editor"; +import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override'; +import { EditorAppConfigClassic, EditorAppConfigExtended, LanguageClientConfig, UserConfig } from "monaco-editor-wrapper"; + +export type WorkerUrl = string; + +/** + * Generalized configuration used with 'getMonacoEditorReactConfig' to generate a working configuration for monaco-editor-react + */ +export interface MonacoReactConfig { + code: string, + languageId: string, + worker: WorkerUrl | Worker, + readonly?: boolean // whether to make the editor readonly or not (by default is false) +} + +/** + * Extended config, specifically for textmate usage + */ +export interface MonacoExtendedReactConfig extends MonacoReactConfig { + textmateGrammar: any; +} + +/** + * Editor config, specifically for monarch grammar usage + */ +export interface MonacoEditorReactConfig extends MonacoReactConfig { + monarchGrammar?: languages.IMonarchLanguage; +} + +/** + * Helper to identify a Extended config, for use with TextMate + */ +function isMonacoExtendedReactConfig(config: unknown): config is MonacoExtendedReactConfig { + return (config as MonacoExtendedReactConfig).textmateGrammar !== undefined; +} + + +/** + * Default language configuration, common to most Langium DSLs + */ +export const defaultLanguageConfig = { + "comments": { + "lineComment": "//", + "blockComment": ["/*", "*/"] + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ] +}; + +/** + * Generates a UserConfig for a given Langium example, which is then passed to the monaco-editor-react component + * + * @param config A Extended or classic editor config to generate a UserConfig from + * @returns A completed UserConfig + */ +export function createUserConfig(config: MonacoExtendedReactConfig | MonacoEditorReactConfig): UserConfig { + // setup urls for config & grammar + const id = config.languageId; + + // check whether to use extended config (Textmate) or the classic editor config (Monarch) + let editorAppConfig: EditorAppConfigClassic | EditorAppConfigExtended; + const useExtendedConfig = isMonacoExtendedReactConfig(config); + if (useExtendedConfig) { + // setup extension contents + const languageConfigUrl = `/${id}-configuration.json`; + const languageGrammarUrl = `/${id}-grammar.json`; + const extensionContents = new Map(); + extensionContents.set(languageConfigUrl, JSON.stringify(defaultLanguageConfig)); + extensionContents.set(languageGrammarUrl, JSON.stringify(config.textmateGrammar)); + + editorAppConfig = { + $type: 'extended', + languageId: id, + code: config.code, + useDiffEditor: false, + extensions: [{ + config: { + name: id, + publisher: 'TypeFox', + version: '1.0.0', + engines: { + vscode: '*' + }, + contributes: { + languages: [{ + id: id, + extensions: [ `.${id}` ], + configuration: languageConfigUrl + }], + grammars: [{ + language: id, + scopeName: `source.${id}`, + path: languageGrammarUrl + }] + } + }, + filesOrContents: extensionContents, + }], + userConfiguration: { + json: JSON.stringify({ + 'workbench.colorTheme': 'Default Dark Modern', + 'editor.semanticHighlighting.enabled': true, + 'editor.lightbulb.enabled': true, + 'editor.guides.bracketPairsHorizontal': 'active' + }) + } + }; + } else { + editorAppConfig = { + $type: 'classic', + languageId: id, + code: config.code, + useDiffEditor: false, + languageExtensionConfig: { id }, + languageDef: config.monarchGrammar, + editorOptions: { + 'semanticHighlighting.enabled': true, + readOnly: config.readonly, + theme: 'vs-dark' + } + }; + } + + let languageClientConfig: LanguageClientConfig; + if (typeof config.worker === 'string') { + languageClientConfig = { + options: { + $type: 'WorkerConfig', + url: new URL(config.worker, window.location.href), + type: 'module', + name: `${id}-language-server-worker`, + } + }; + } else { + languageClientConfig = { + options: { + $type: 'WorkerDirect', + worker: config.worker + } + }; + } + + // generate user config for langium based language + const userConfig: UserConfig = { + wrapperConfig: { + serviceConfig: { + // only use keyboard service in addition to the default services from monaco-editor-wrapper + userServices: { + ...getKeybindingsServiceOverride() + }, + debugLogging: true + }, + editorAppConfig + }, + languageClientConfig + } + return userConfig; +} diff --git a/core/tsconfig.json b/core/tsconfig.json new file mode 100644 index 00000000..501bcbcb --- /dev/null +++ b/core/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "noImplicitAny": true, + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "rootDir": "src", + "outDir": "dist", + "declaration": true, + "declarationDir": "dist" + }, + "include": [ + "src/**/*.ts", + ] +} \ No newline at end of file diff --git a/hugo/vite.bundle-monaco-editor-react.ts b/core/vite.bundle.ts similarity index 51% rename from hugo/vite.bundle-monaco-editor-react.ts rename to core/vite.bundle.ts index e9043e81..24a35854 100644 --- a/hugo/vite.bundle-monaco-editor-react.ts +++ b/core/vite.bundle.ts @@ -4,21 +4,21 @@ import { defineConfig } from 'vite'; const config = defineConfig({ build: { lib: { - entry: resolve(__dirname, './assets/scripts/monaco-editor-react.ts'), - name: 'monaco-editor-react', - fileName: () => 'monaco-editor-react.js', + entry: resolve(__dirname, './src/index.ts'), + name: 'monaco-editor-wrapper-bundle', + fileName: () => 'index.js', formats: ['es'] }, - outDir: resolve(__dirname, 'static/libs/monaco-editor-react'), - assetsDir: resolve(__dirname, 'static/libs/monaco-editor-react/assets'), - emptyOutDir: false, + outDir: resolve(__dirname, 'bundle/monaco-editor-wrapper-bundle'), + assetsDir: resolve(__dirname, 'bundle/monaco-editor-wrapper-bundle/assets'), + emptyOutDir: true, cssCodeSplit: false, commonjsOptions: { strictRequires: true }, rollupOptions: { output: { - name: 'monaco-editor-react', + name: 'monaco-editor-wrapper-bundle', exports: 'named', sourcemap: false, assetFileNames: (assetInfo) => { @@ -28,11 +28,8 @@ const config = defineConfig({ } }, resolve: { - alias: { - path: 'path-browserify' - } - }, - assetsInclude: ['**/*.wasm'] + dedupe: ['monaco-editor', 'vscode'] + } }); -export default config; \ No newline at end of file +export default config; diff --git a/hugo/.gitignore b/hugo/.gitignore new file mode 100644 index 00000000..b9d7b3f1 --- /dev/null +++ b/hugo/.gitignore @@ -0,0 +1,5 @@ +resources/ +static/css/ +static/showcase/ +static/libs/ +static/playground/ diff --git a/hugo/assets/scripts/arithmetics/arithmetics-tools.tsx b/hugo/assets/scripts/arithmetics/arithmetics-tools.tsx index 25941728..651b1777 100644 --- a/hugo/assets/scripts/arithmetics/arithmetics-tools.tsx +++ b/hugo/assets/scripts/arithmetics/arithmetics-tools.tsx @@ -1,4 +1,4 @@ -import { monaco } from "monaco-editor-wrapper/."; +import { monaco } from "langium-website-core/bundle"; import { Pos } from "../langium-utils/langium-ast"; export interface Evaluation { diff --git a/hugo/assets/scripts/arithmetics/arithmetics.tsx b/hugo/assets/scripts/arithmetics/arithmetics.tsx index 89f87589..19ff8c76 100644 --- a/hugo/assets/scripts/arithmetics/arithmetics.tsx +++ b/hugo/assets/scripts/arithmetics/arithmetics.tsx @@ -1,11 +1,11 @@ -import { MonacoEditorReactComp } from "./static/libs/monaco-editor-react/monaco-editor-react.js"; +import { addMonacoStyles, createUserConfig, MonacoEditorReactComp, UserConfig } from "langium-website-core/bundle"; import { buildWorkerDefinition } from "monaco-editor-workers"; import React from "react"; import { createRoot } from "react-dom/client"; import { Diagnostic, DocumentChangeResponse } from "../langium-utils/langium-ast"; import { Evaluation, examples, syntaxHighlighting } from "./arithmetics-tools"; -import { UserConfig } from "monaco-editor-wrapper"; -import { createUserConfig } from "../utils"; + +addMonacoStyles('monaco-styles-helper'); buildWorkerDefinition( "../../libs/monaco-editor-workers/workers", diff --git a/hugo/assets/scripts/domainmodel/domainmodel.tsx b/hugo/assets/scripts/domainmodel/domainmodel.tsx index 02fc14f5..0a3e3d89 100644 --- a/hugo/assets/scripts/domainmodel/domainmodel.tsx +++ b/hugo/assets/scripts/domainmodel/domainmodel.tsx @@ -1,13 +1,13 @@ -import { MonacoEditorReactComp } from "@typefox/monaco-editor-react/bundle"; +import { addMonacoStyles, createUserConfig, MonacoEditorReactComp, UserConfig } from "langium-website-core/bundle"; import { buildWorkerDefinition } from "monaco-editor-workers"; import React from "react"; import { createRoot } from "react-dom/client"; import { Diagnostic, DocumentChangeResponse, LangiumAST } from "../langium-utils/langium-ast"; import { DomainModelAstNode, example, getTreeNode, syntaxHighlighting } from "./domainmodel-tools"; -import { UserConfig } from "monaco-editor-wrapper"; -import { createUserConfig } from "../utils"; import D3Tree from "./d3tree"; - + +addMonacoStyles('monaco-styles-helper'); + buildWorkerDefinition( "../../libs/monaco-editor-workers/workers", new URL("", window.location.href).href, diff --git a/hugo/assets/scripts/minilogo/minilogo-tools.ts b/hugo/assets/scripts/minilogo/minilogo-tools.ts index 9978a0e5..deee44bc 100644 --- a/hugo/assets/scripts/minilogo/minilogo-tools.ts +++ b/hugo/assets/scripts/minilogo/minilogo-tools.ts @@ -1,4 +1,4 @@ -import { monaco } from "monaco-editor-wrapper/."; +import { monaco } from "langium-website-core/bundle"; export interface Command { name: 'penUp' | 'penDown' | 'move' | 'color'; diff --git a/hugo/assets/scripts/minilogo/minilogo.tsx b/hugo/assets/scripts/minilogo/minilogo.tsx index 25bcdde6..3f39c923 100644 --- a/hugo/assets/scripts/minilogo/minilogo.tsx +++ b/hugo/assets/scripts/minilogo/minilogo.tsx @@ -1,12 +1,12 @@ -import { MonacoEditorReactComp } from "@typefox/monaco-editor-react/bundle"; +import { addMonacoStyles, createUserConfig, MonacoEditorReactComp, UserConfig } from "langium-website-core/bundle"; import { buildWorkerDefinition } from "monaco-editor-workers"; import React, { createRef } from "react"; import { createRoot } from "react-dom/client"; import { Diagnostic, DocumentChangeResponse, LangiumAST } from "../langium-utils/langium-ast"; import { ColorArgs, Command, MoveArgs, examples, syntaxHighlighting } from "./minilogo-tools"; import { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from "lz-string"; -import { UserConfig } from "monaco-editor-wrapper"; -import { createUserConfig } from "../utils"; + +addMonacoStyles('monaco-styles-helper'); buildWorkerDefinition( "../../libs/monaco-editor-workers/workers", diff --git a/hugo/assets/scripts/monaco-editor-react.ts b/hugo/assets/scripts/monaco-editor-react.ts deleted file mode 100644 index a92213a9..00000000 --- a/hugo/assets/scripts/monaco-editor-react.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "@typefox/monaco-editor-react"; -import 'vscode/default-extensions/theme-defaults'; diff --git a/hugo/assets/scripts/sql/constants.ts b/hugo/assets/scripts/sql/constants.ts index 92ea8528..5d237a09 100644 --- a/hugo/assets/scripts/sql/constants.ts +++ b/hugo/assets/scripts/sql/constants.ts @@ -1,4 +1,4 @@ -import { monaco } from "@typefox/monaco-editor-react/."; +import { monaco } from "langium-website-core/bundle"; export const syntaxHighlighting: monaco.languages.IMonarchLanguage = { tokenizer: { diff --git a/hugo/assets/scripts/sql/ui.tsx b/hugo/assets/scripts/sql/ui.tsx index b2d339c0..4e352182 100644 --- a/hugo/assets/scripts/sql/ui.tsx +++ b/hugo/assets/scripts/sql/ui.tsx @@ -1,4 +1,4 @@ -import { MonacoEditorReactComp } from "./static/libs/monaco-editor-react/monaco-editor-react.js"; +import { addMonacoStyles, createUserConfig, MonacoEditorReactComp, UserConfig } from "langium-website-core/bundle"; import { buildWorkerDefinition } from "monaco-editor-workers"; import React from "react"; import { createRoot } from "react-dom/client"; @@ -9,8 +9,8 @@ import { defaultText, syntaxHighlighting, } from "./constants"; -import { UserConfig } from "monaco-editor-wrapper"; -import { createUserConfig } from '../utils'; + +addMonacoStyles('monaco-styles-helper'); buildWorkerDefinition( "../../libs/monaco-editor-workers/workers", diff --git a/hugo/assets/scripts/statemachine/statemachine.tsx b/hugo/assets/scripts/statemachine/statemachine.tsx index a3b1f6b0..2bb3d540 100644 --- a/hugo/assets/scripts/statemachine/statemachine.tsx +++ b/hugo/assets/scripts/statemachine/statemachine.tsx @@ -1,13 +1,13 @@ -import { MonacoEditorReactComp } from "./static/libs/monaco-editor-react/monaco-editor-react.js"; +import { addMonacoStyles, createUserConfig, MonacoEditorReactComp, UserConfig } from "langium-website-core/bundle"; import { buildWorkerDefinition } from "monaco-editor-workers"; import React from "react"; import { createRoot } from "react-dom/client"; import { Diagnostic, DocumentChangeResponse, LangiumAST } from "../langium-utils/langium-ast"; import { defaultText, StateMachineAstNode, StateMachineState, StateMachineTools } from "./statemachine-tools"; -import { UserConfig } from "monaco-editor-wrapper"; -import { createUserConfig } from '../utils'; import statemachineGrammar from 'langium-statemachine-dsl/syntaxes/statemachine.tmLanguage.json'; +addMonacoStyles('monaco-styles-helper'); + buildWorkerDefinition( "../../libs/monaco-editor-workers/workers", new URL("", window.location.href).href, diff --git a/hugo/assets/scripts/utils.ts b/hugo/assets/scripts/utils.ts deleted file mode 100644 index 442b764b..00000000 --- a/hugo/assets/scripts/utils.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { UserConfig } from "monaco-editor-wrapper"; -import { monaco } from "monaco-editor-wrapper/."; - -export type WorkerUrl = string; - -/** - * Generalized configuration used with 'getMonacoEditorReactConfig' to generate a working configuration for monaco-editor-react - */ -export interface MonacoReactConfig { - code: string, - htmlElement: HTMLElement, - languageId: string, - worker: WorkerUrl | Worker, - readonly?: boolean // whether to make the editor readonly or not (by default is false) -} - -/** - * VSCode API config, specifically for textmate usage - */ -export interface MonacoVSCodeReactConfig extends MonacoReactConfig { - textmateGrammar: any; -} - -/** - * Editor config, specifically for monarch grammar usage - */ -export interface MonacoEditorReactConfig extends MonacoReactConfig { - monarchGrammar?: monaco.languages.IMonarchLanguage; -} - -/** - * Helper to identify a VSCode API config, for use with TextMate - */ -function isMonacoVSCodeReactConfig(config: unknown): config is MonacoVSCodeReactConfig { - return (config as MonacoVSCodeReactConfig).textmateGrammar !== undefined; -} - -/** - * Helper to identify an editor config (classic), for use with Monarch - */ -function isMonacoEditorReactConfig(config: unknown): config is MonacoEditorReactConfig { - return (config as MonacoEditorReactConfig).monarchGrammar !== undefined; -} - -/** - * Default language configuration, common to most Langium DSLs - */ -export const defaultLanguageConfig = { - "comments": { - "lineComment": "//", - "blockComment": ["/*", "*/"] - }, - "brackets": [ - ["{", "}"], - ["[", "]"], - ["(", ")"] - ], - "autoClosingPairs": [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ["\"", "\""], - ["'", "'"] - ], - "surroundingPairs": [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ["\"", "\""], - ["'", "'"] - ] -}; - -/** - * Generates a UserConfig for a given Langium example, which is then passed to the monaco-editor-react component - * - * @param config A VSCode API or classic editor config to generate a UserConfig from - * @returns A completed UserConfig - */ -export function createUserConfig(config: MonacoVSCodeReactConfig | MonacoEditorReactConfig): UserConfig { - // setup extension contents - const extensionContents = new Map(); - - // setup urls for config & grammar - const id = config.languageId; - const languageConfigUrl = `/${id}-configuration.json`; - const languageGrammarUrl = `/${id}-grammar.json`; - - // set extension contents - extensionContents.set(languageConfigUrl, JSON.stringify(defaultLanguageConfig)); - - // check whether to use the VSCode API config (TM), or the classic editor config (Monarch) - const useVscodeConfig = isMonacoVSCodeReactConfig(config); - - if (isMonacoVSCodeReactConfig(config)) { - extensionContents.set(languageGrammarUrl, JSON.stringify(config.textmateGrammar)); - } - - // generate langium config - return { - htmlElement: config.htmlElement, - wrapperConfig: { - // have to disable this for Monarch - // generally true otherwise (toggles using monacoVscodeApiConfig / monacoEditorConfig) - useVscodeConfig, - - serviceConfig: { - // the theme service & textmate services are dependent, they need to both be enabled or disabled together - // this explicitly disables the Monarch capabilities - // both are tied to whether we are using the VSCode config as well - enableThemeService: useVscodeConfig, - enableTextmateService: useVscodeConfig, - - enableModelService: true, - configureEditorOrViewsServiceConfig: { - enableViewsService: false, - useDefaultOpenEditorFunction: true - }, - configureConfigurationServiceConfig: { - defaultWorkspaceUri: '/tmp/' - }, - enableKeybindingsService: true, - enableLanguagesService: true, - debugLogging: false - }, - // VSCode config (for TextMate grammars) - monacoVscodeApiConfig: { - extension: { - name: id, - publisher: 'TypeFox', - version: '1.0.0', - engines: { - vscode: '*' - }, - contributes: { - languages: [{ - id, - extensions: [], - aliases: [ - id - ], - configuration: `.${languageConfigUrl}` - }], - grammars: isMonacoVSCodeReactConfig(config) ? [{ - language: id, - scopeName: `source.${id}`, - path: `.${languageGrammarUrl}` - }] : undefined, - keybindings: [{ - key: 'ctrl+p', - command: 'editor.action.quickCommand', - when: 'editorTextFocus' - }, { - key: 'ctrl+shift+c', - command: 'editor.action.commentLine', - when: 'editorTextFocus' - }] - } - }, - extensionFilesOrContents: extensionContents, - userConfiguration: { - json: `{ - "workbench.colorTheme": "Default Dark Modern", - "editor.fontSize": 14, - "editor.lightbulb.enabled": true, - "editor.lineHeight": 20, - "editor.guides.bracketPairsHorizontal": "active", - "editor.lightbulb.enabled": true -}` - } - }, - // Editor config (classic) (for Monarch) - monacoEditorConfig: { - languageExtensionConfig: { - id - }, - languageDef: isMonacoEditorReactConfig(config) ? config.monarchGrammar : undefined - } - }, - editorConfig: { - languageId: id, - code: config.code, - useDiffEditor: false, - automaticLayout: true, - theme: 'vs-dark', - editorOptions: { - readOnly: config.readonly - } - }, - languageClientConfig: { - enabled: true, - useWebSocket: false, - // build a worker config from a worker URL string, or just copy in the entire worker - workerConfigOptions: typeof config.worker === 'string' ? { - url: new URL(config.worker, window.location.href), - type: 'module', - name: `${id}-language-server-worker`, - } : config.worker - } - }; -} diff --git a/hugo/content/playground/_index.html b/hugo/content/playground/_index.html index 8764727d..d005d41b 100644 --- a/hugo/content/playground/_index.html +++ b/hugo/content/playground/_index.html @@ -10,14 +10,14 @@ noMain: true playground: true --- -