-
Notifications
You must be signed in to change notification settings - Fork 49
Description
Preface, I am not saying that "your library is shit", both packages/foundations are a godsend, they are perfect for an all-in-one batteries included Monaco setup. Both libs together creates a new level above Monaco, making a high-level structure and this is awesome! Idea of "plug-in monaco setup" sounds awesome, implementation is awesome, everything about it is awesome. Except using it. Entry barrier is higher than Mount Everest, entire thing sets a new level of complexity, documentation is severely lacking to a non existent. Using both libraries for the first time is insanely hard, harder than Haskell, harder than writing a HTTP server in COBOL.
I have a theme. https://github.com/sainnhe/gruvbox-material-vscode/blob/master/themes/gruvbox-material-dark.json. A VSCode theme. What is the sane way to use it? Throw it to https://vsctim.vercel.app/, then get the Monaco editor compatible JSON,
then
monaco.editor.defineTheme('gruvbox-material-dark', gruvboxMaterialDark)
monaco.editor.setTheme('gruvbox-material-dark')
bing, right?
Uncaught (in promise) TypeError: standaloneThemeService.defineTheme is not a function
hmmm, lets look at the issue. #458 okay, that makes sense, I have set theme services
userServices: {
...getEditorServiceOverride(useOpenEditorStub),
...getKeybindingsServiceOverride(),
...getVscodeEditorServiceOverride(useOpenEditorStub),
...getThemeServiceOverride()
},
you are expected to use a VSCode extension to declare it.
uhhhhhhhhhhhh what? what vscode extension? I have a berlin wall of package.json
what do you mean by VSCode extension?
but okay, I can live with default themes.
hmm... there is something wrong... it looks like labels are not loaded...
editorAppConfig: {
$type: "extended",
codeResources: {
main: {
text: code,
uri: codeUri,
},
},
loadThemes: true,
useDiffEditor: false,
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: document.getElementById("monaco-editor-root")!,
},
loadThemes
is set to True in monaco-editor-wrapper.WrapperConfig
. so when monaco-editor-wrapper
initializes, I also import the default extension.
override async init() {
if (this.config.loadThemes ?? true) {
await import('@codingame/monaco-vscode-theme-defaults-default-extension');
}
makes sense! lets set our theme
Uncaught Error: Unable to load extension-file://vscode.theme-defaults/themes/dark_modern.json: Not Found
...what?
there is default themes under the @codingame/monaco-vscode-theme-defaults-default-extension
so what is wrong? where am I supposed to look at? what is going on here? where should I take reference? custom color themes does not work, default colors does not work, there is no documentation for it, what am I supposed to do here?
WrapperConfig
import * as vscode from "vscode";
import getEditorServiceOverride from "@codingame/monaco-vscode-editor-service-override";
import getKeybindingsServiceOverride from "@codingame/monaco-vscode-keybindings-service-override";
import getVscodeEditorServiceOverride from "@codingame/monaco-vscode-editor-service-override";
import getThemeServiceOverride from "@codingame/monaco-vscode-theme-service-override"
import "@codingame/monaco-vscode-python-default-extension";
import { LogLevel } from "vscode/services";
import { createUrl, type WrapperConfig } from "monaco-editor-wrapper";
import { useOpenEditorStub } from "monaco-editor-wrapper/vscode/services";
import type { MonacoLanguageClient } from "monaco-languageclient";
import {
toSocket,
WebSocketMessageReader,
WebSocketMessageWriter,
} from "vscode-ws-jsonrpc";
import { MonacoEditorWrapperProps } from "../components/Editor";
import { configureMonacoWorkers } from "./configureLSPWorkers";
export const CreatePythonUserConfig = (
workspaceRoot: string,
code: string,
codeUri: string,
props: MonacoEditorWrapperProps,
): WrapperConfig => {
const url = createUrl({
secured: props.lspSecured,
host: props.lspHost,
port: props.lspPort,
path: props.lspPath,
});
const webSocket = new WebSocket(url);
const iWebSocket = toSocket(webSocket);
const reader = new WebSocketMessageReader(iWebSocket);
const writer = new WebSocketMessageWriter(iWebSocket);
return {
languageClientConfigs: {
python: {
languageId: "python",
name: "Python Language Server Example",
connection: {
options: {
$type: "WebSocketDirect",
webSocket: webSocket,
startOptions: {
onCall: (languageClient?: MonacoLanguageClient) => {
setTimeout(() => {
// biome-ignore lint/complexity/noForEach: <explanation>
["pyright.restartserver", "pyright.organizeimports"].forEach(
(cmdName) => {
vscode.commands.registerCommand(
cmdName,
(...args: unknown[]) => {
languageClient?.sendRequest(
"workspace/executeCommand",
{ command: cmdName, arguments: args },
);
},
);
},
);
}, 250);
},
reportStatus: true,
},
},
messageTransports: { reader, writer },
},
clientOptions: {
documentSelector: ["python"],
workspaceFolder: {
index: 0,
name: "workspace",
uri: vscode.Uri.parse(workspaceRoot),
},
},
},
},
logLevel: LogLevel.Debug,
vscodeApiConfig: {
userServices: {
...getEditorServiceOverride(useOpenEditorStub),
...getKeybindingsServiceOverride(),
...getVscodeEditorServiceOverride(useOpenEditorStub),
...getThemeServiceOverride()
},
userConfiguration: {
json: JSON.stringify({
"workbench.colorTheme": "Default Dark Modern",
"editor.guides.bracketPairsHorizontal": "active",
"editor.wordBasedSuggestions": "off",
// "editor.experimental.asyncTokenization": true,
}),
},
},
editorAppConfig: {
$type: "extended",
codeResources: {
main: {
text: code,
uri: codeUri,
},
},
loadThemes: true,
useDiffEditor: false,
monacoWorkerFactory: configureMonacoWorkers,
htmlContainer: document.getElementById("monaco-editor-root")!,
},
};
};
Monaco
import React, { useState, useEffect, useRef, StrictMode } from 'react'
import '@codingame/monaco-vscode-python-default-extension';
import { createFileRoute } from '@tanstack/react-router'
import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper'
import { CreatePythonUserConfig } from '../editor/python'
import { RegisteredFileSystemProvider, RegisteredMemoryFile, registerFileSystemOverlay } from '@codingame/monaco-vscode-files-service-override'
import * as vscode from 'vscode';
import * as monaco from 'monaco-editor'
import { gruvboxMaterialDark } from '../editor/themes/gruvbox-material-dark'
export const Route = createFileRoute('/code')({
component: MonacoPage,
})
export default function MonacoPage() {
const editorRef = useRef<MonacoEditorLanguageClientWrapper | null>(null);
const [editorReady, setEditorReady] = useState(false);
const wrapper = new MonacoEditorLanguageClientWrapper();
const wrapperConfig = CreatePythonUserConfig('/workspace', "print('Hello, World!')", '/workspace/script.py', {
lspHost: 'localhost',
lspPort: 8080,
lspPath: 'lsp/pyright',
lspSecured: false,
});
useEffect(() => {
const initEditor = async () => {
if (editorRef.current) return;
const fileSystemProvider = new RegisteredFileSystemProvider(false);
fileSystemProvider.registerFile(new RegisteredMemoryFile(vscode.Uri.file('/workspace/script.py'), "print('Hello, World!')"));
registerFileSystemOverlay(1, fileSystemProvider);
await wrapper.init(wrapperConfig);
await wrapper.start();
monaco.editor.defineTheme('gruvbox-material-dark', gruvboxMaterialDark)
monaco.editor.setTheme('gruvbox-material-dark')
setEditorReady(true);
};
initEditor();
}, [wrapper, wrapperConfig]);
return (
<div>
<div id="monaco-editor-root" style={{ height: '100vh', maxWidth: '130vh' }} />
</div>
)
}
package.json
{
"name": "otuzbir-tv-frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@codingame/monaco-vscode-configuration-service-override": "~10.0.2",
"@codingame/monaco-vscode-files-service-override": "~10.0.2",
"@codingame/monaco-vscode-groovy-default-extension": "~10.0.2",
"@codingame/monaco-vscode-java-default-extension": "~10.0.2",
"@codingame/monaco-vscode-javascript-default-extension": "~10.0.2",
"@codingame/monaco-vscode-json-default-extension": "~10.0.2",
"@codingame/monaco-vscode-keybindings-service-override": "~10.0.2",
"@codingame/monaco-vscode-lifecycle-service-override": "~10.0.2",
"@codingame/monaco-vscode-localization-service-override": "~10.0.2",
"@codingame/monaco-vscode-python-default-extension": "~10.0.2",
"@codingame/monaco-vscode-standalone-json-language-features": "~10.0.2",
"@codingame/monaco-vscode-standalone-languages": "~10.0.2",
"@codingame/monaco-vscode-standalone-typescript-language-features": "~10.0.2",
"@codingame/monaco-vscode-textmate-service-override": "~10.0.2",
"@codingame/monaco-vscode-theme-defaults-default-extension": "~10.0.2",
"@codingame/monaco-vscode-theme-service-override": "~10.0.2",
"@codingame/monaco-vscode-typescript-basics-default-extension": "~10.0.2",
"@codingame/monaco-vscode-typescript-language-features-default-extension": "~10.0.2",
"@typefox/monaco-editor-react": "~6.0.0-next.3",
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~10.0.2",
"monaco-editor-wrapper": "~6.0.0-next.3",
"monaco-languageclient": "~9.0.0-next.3",
"pyright": "~1.1.384",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"vscode": "npm:@codingame/monaco-vscode-api@~10.0.2",
"vscode-languageclient": "~9.0.1",
"ws": "~8.18.0"
},
"devDependencies": {
"@eslint/js": "^9.11.1",
"@tanstack/router-plugin": "^1.65.0",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.2",
"autoprefixer": "^10.4.20",
"eslint": "^9.11.1",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.12",
"globals": "^15.9.0",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"typescript": "^5.5.3",
"typescript-eslint": "^8.7.0",
"vite": "^5.4.8"
}
}
any help is appreciated, because there is no other resources to be found.
edit: I dont know why WrapperConfig is rendered as 4 space, sorry for that infinite blackhole.