CodinGame / monaco-vscode-api

VSCode public API plugged on the monaco editor
MIT License
253 stars 33 forks source link

I have read your document, but I still don't know how to write it to configure my own color theme. #531

Open wudicom520 opened 3 weeks ago

wudicom520 commented 3 weeks ago

I am using Vite+Vue3 The latest monaco-vscode-api package used

I read #465 ,but I'm confused.

// default monaco-editor imports
import * as monaco from 'monaco-editor';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';

// utilities to override Monaco services
import { initialize } from 'vscode/services'
import getConfigurationServiceOverride, { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override'

window.MonacoEnvironment = {
  getWorker: (_moduleId, _label) => new editorWorker()
}

// overriding Monaco service with VSCode
await initialize({
    ...getConfigurationServiceOverride(),
});

// json config like in vscode settings.json
updateUserConfiguration(`{
    "editor.fontSize": 30,
    "editor.lineHeight": 30,
    "editor.fontFamily": "monospace",
    "editor.fontWeight": "bold",
    "editor.letterSpacing": 0,
}`)

// creating an editor with VSCode configuration
monaco.editor.create(document.getElementById('editor')!, {
    value: "Editor with VSCode config and large bold fonts",
});

Yes, this way I can configure some font operations. What if I want to configure my own defined theme The original method of using Monaco was relatively simple, eg

    monaco.editor.defineTheme("myTheme", {
      base: "vs-dark",
      inherit: true,
      rules: [],
      colors: {
        "editor.foreground": "#FFFFFF",
        "editor.background": "#393939",
        "editorCursor.foreground": "#FFFFFF",
        "editor.lineHighlightBackground": "#40405A20",
        "editorLineNumber.foreground": "#ffffff",
        "editor.selectionBackground": "#FFFFFF30",
        "editor.inactiveSelectionBackground": "#88000015",
      },
    });
    monaco.editor.setTheme("myTheme");

Of course, I made some attempts but it didn't work. e.g

    updateUserConfiguration(`{
      "editor.foreground": "#FFFFFF",
      "editor.background": "#393939",
      "editorCursor.foreground": "#FFFFFF",
      "editor.lineHighlightBackground": "#40405A20",
      "editorLineNumber.foreground": "#ffffff",
      "editor.selectionBackground": "#FFFFFF30",
      "editor.inactiveSelectionBackground": "#88000015",
    }`)

I admit that my programming ability is weak, and I hope you can provide beginners with a rich set of operation and learning documents.

I read #517 Benefiting greatly But it's been several days now and there hasn't been any progress.

<template>
    <div ref="cusEditor" style="height: 100%;"></div>
</template>

<script setup lang="ts">
import * as monaco from 'monaco-editor';
import { initialize } from 'vscode/services'

import "vscode/localExtensionHost";
import { initWebSocketAndStartClient } from './lsp-client'
import '@codingame/monaco-vscode-python-default-extension';
import "@codingame/monaco-vscode-theme-defaults-default-extension";

import getLanguagesServiceOverride from "@codingame/monaco-vscode-languages-service-override";
import getThemeServiceOverride from "@codingame/monaco-vscode-theme-service-override";
import getTextMateServiceOverride from "@codingame/monaco-vscode-textmate-service-override";
import getConfigurationServiceOverride, { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override'
import * as vscode from 'vscode'

import { ref, shallowRef } from 'vue';
import { useIdeStore } from '@/stores/ide';
import { storeToRefs } from 'pinia';
// import { language as pythonLanguage } from 'monaco-editor/esm/vs/basic-languages/python/python.js';

// we need to import this so monaco-languageclient can use vscode-api

// import  {initWebSocketAndStartClient}  from './lsp-client';
import {OPTIONS_BASE} from "./registerCompletion";
import {COLOER_BASE} from "./registerColor";
// everything else is the same except the last line

const ideStore = useIdeStore();
const { ideInfo } = storeToRefs(ideStore);

interface IProps {
  modelValue: string;
  disabled?: boolean;
  editorConfig?: { language: string; theme: string };
  onchange?: (value: string) => void;

}
const props = withDefaults(defineProps<IProps>(), {
  modelValue: '',
  disabled: false,
  editorConfig: () => ({ language: 'python', theme: 'vs-dark' }),
  onchange: (value: string) => {
  }
});

const cusEditor = ref<HTMLElement | null>(null);
let editor: monaco.editor.IStandaloneCodeEditor | null = null;
let monacoProviderRef = ref();
// let monacoProviderRef = ref()
// const modelValueRef = ref<string>();

export type WorkerLoader = () => Worker;
const workerLoaders: Partial<Record<string, WorkerLoader>> = {
    TextEditorWorker: () => new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' }),
    TextMateWorker: () => new Worker(new URL('@codingame/monaco-vscode-textmate-service-override/worker', import.meta.url), { type: 'module' })
};

window.MonacoEnvironment = {
  getWorker: function (_moduleId, label) {
    // console.log('getWorker', _moduleId, label);
    const workerFactory = workerLoaders[label];
  if (workerFactory != null) {
    return workerFactory();
  }
    throw new Error(`Worker ${label} not found`);
  }
};

onMounted(async () => {
  try {
    console.log('Initializing Monaco Editor services...');

    if (ideInfo.value.isFinishEditorInit === false) {
      await initialize({
        ...getConfigurationServiceOverride(),
        // ...getTextMateServiceOverride(),
        // ...getThemeServiceOverride(),
        ...getLanguagesServiceOverride(),
      });
      ideStore.setIsFinishEditorInit();
    }

    // updateUserConfiguration(`{
    //   "editor.foreground": "#FFFFFF",
    //   "editor.background": "#393939",
    //   "editorCursor.foreground": "#FFFFFF",
    //   "editor.lineHighlightBackground": "#40405A20",
    //   "editorLineNumber.foreground": "#ffffff",
    //   "editor.selectionBackground": "#FFFFFF30",
    //   "editor.inactiveSelectionBackground": "#88000015",
    // }`)
    console.log('Creating Monaco Editor instance...');
    const editor = monaco.editor.create(cusEditor.value, {
      value: props.modelValue,
      theme: props.editorConfig.theme,
      minimap: {
        enabled: false // 禁用 MiniMap
      },
      ...OPTIONS_BASE
    });
    monaco.editor.defineTheme("myTheme", {
      base: "vs-dark",
      inherit: true,
      rules: [],
      colors: {
        "editor.foreground": "#FFFFFF",
        "editor.background": "#393939",
        "editorCursor.foreground": "#FFFFFF",
        "editor.lineHighlightBackground": "#40405A20",
        "editorLineNumber.foreground": "#ffffff",
        "editor.selectionBackground": "#FFFFFF30",
        "editor.inactiveSelectionBackground": "#88000015",
      },
    });
    monaco.editor.setTheme("myTheme");
    setLanguagesTips();
    const url = "ws://localhost:21001/api/v1/ws/lspserver";
    console.log('Initializing WebSocket and starting LSP client...');
    initWebSocketAndStartClient(url);

  } catch (e) {
    console.error('Error initializing Monaco Editor:', e);
  }
});

const setLanguagesTips = () => {

};

const onDispose = () => {
    editor && editor.dispose && editor.dispose();
};
onUnmounted(() => {
    onDispose();
});
</script>

Thanks

CGNonofr commented 2 weeks ago

If you are not using the theme and textmate service overrides, using monaco.editor.defineTheme is perfectly fine

updateUserConfiguration allows to update the user configuration, it has nothing to do with the color theme

if you are using the textmate and theme service overrides, themes are registered by VSCode extensions. You need one to register your custom theme. Either by using an existing extension vsix file, or programmatically:

import { ExtensionHostKind, registerExtension } from 'vscode/extensions'

const { registerFileUrl } = registerExtension({
  name: 'myTheme',
  publisher: 'me',
  version: '1.0.0',
  engines: {
    vscode: '*'
  },
  contributes: {
    themes: [
      {
        id: "My Theme Id",
        label: "My Theme Name",
        uiTheme: "vs-dark",
        path: "./themes/mytheme.json",
      }
    ]
  }
)

// The theme content can be registered using its content via a base64 urls
registerFileUrl('./themes/mytheme.json', 'data:text/javascript;base64,' + window.btoa(JSON.stringify(themeJsonContent)))
// Or reference a json file from the disk
registerFileUrl('./themes/mytheme.json', new URL('./the/file/on/the/disk.json', import.meta.url))