Coder Social home page Coder Social logo

typefox / monaco-components Goto Github PK

View Code? Open in Web Editor NEW
42.0 7.0 13.0 1.45 MB

Monaco Editor and Language Client Wrapper, plus Monaco Editor React Component

License: MIT License

HTML 7.67% TypeScript 88.72% JavaScript 3.61%
monaco monaco-editor monaco-languageclient react monaco-vscode-api

monaco-components's People

Contributors

cdietrich avatar christophcku avatar kaisalmen avatar lotes avatar montymxb avatar msujew avatar phated avatar rhumbertgz avatar stuey61296 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

monaco-components's Issues

Important: In the near future (before April March 2024) this repo will be fused with monaco-languageclient

Once TypeFox/monaco-languageclient#600 is merged and the next major release of all npm packages is ready this repository will be archived. This TypeFox/monaco-languageclient#543 (comment) summarizes the reasons pretty well. Overall maintenance effort is reduced and all monaco related packages and all helpful examples are concentrated at one location.
All open issues that are still relevant will be transferred over.

Selective applicance of wrappers css

Hi, is there a way to prevent the monaco editor wrapper messing with the css styling up to the body tag?
e.g. in dark mode "everything" gets dark

MonacoEditorReactComp + registerFileSystemOverlay

Hi, i am trying to get the MonacoEditorReactComp combined with registerFileSystemOverlay
in order to have library files available for referencing in the editor.

unfortnately vite/esbuild have problems to bundle it.

any ideas/hints? thanks

✘ [ERROR] No matching export in "node_modules/monaco-editor/esm/vs/nls.js" for import "localizeWithPath"

    node_modules/@codingame/monaco-vscode-files-service-override/node_modules/vscode/vscode/src/vs/platform/files/common/io.js:3:9:
      3 │ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';

https://github.com/cdietrich/my-monaco-editor-react-example/tree/cd/otherFilesExperiments

Worker Leaks if Language Client Fails to Start

This pertains to the MonacoEditorLanguageClientWrapper when using a worker for the language server.

When starting the wrapper up, if the languageClientWrapper internally fails to start for some reason (such as when working with a misconfigured LS), it's possible to get the LC stuck in a 'starting' state. In such a case disposing of the wrapper, which has failed to start, will also fail because the language client cannot be cleaned up. Due to the order of execution for cleanup on dispose, this means the worker for the language server (if using a worker & not a WS) can be leaked during dispose.

We should ensure that the worker is always cleaned up upon dispose, even if the language client fails on being disposed itself.

`monaco-treemending` with Yarn package manager

Description

When installing [email protected] with yarn, a postinstall : monaco-treemending script is run and it shows the command is not found.
image

It seems the latest commit removed postinstall : monaco-treemending script in this repository, but the changes are not released yet.

Peer Dependency Issue

When I traced the Peer Dependencies of [email protected] to the monaco-treemending script, it went like

[email protected] 👉 [email protected] 👉 @codingame/monaco-vscode-api@~1.78.6

I could see the actual monaco-treemending js script is present only in the @codingame/monaco-vscode-api@~1.78.6 package, not in any of the other packages.

Now coming to the issue, when installing monaco-editor-wrapper, npm is somehow looking into the peer dependencies and executing the bin scripts from @codingame/monaco-vscode-api@~1.78.6 , but this is not the case for yarn. Yarn is only looking in that package and avoiding the peer dependencies(I guess).

Because of this, yarn becomes unusable with the latest monaco-languageclient packages.

To Reproduce

yarn create vite

Choose any Framework and try the below command

yarn add [email protected]

(or)

yarn add [email protected]

Question

Do we need postinstall : monaco-treemending script in monaco-languageclient package? As it is already taken care of by @codingame/monaco-vscode-api and only that package has the js script to run...

Thanks.

New Problem in vite

Hi, any hints how to solve

[vite]: Rollup failed to resolve import "vscode/service-override/configuration" from "/Users/dietrich/git/my-monaco-editor-react-example/node_modules/monaco-editor-wrapper/dist/editorAppBase.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to

can't type newlines when `nextEmbedded` is set

Hi there, in my Monarch syntax highlighter, I have a rule where it uses embedded language:

initial: [
  [
    /^\s*%%(?={)/,
    { token: 'keyword', bracket: '@open', next: '@directive', nextEmbedded: 'javascript' },
  ],
  // other rules
]

When I enter that state, I can type anything, except newlines. And when I removed javascript and made it empty, it worked fine but without the language features.
I tried the code in https://microsoft.github.io/monaco-editor/monarch.html to check if the issue was in my code, but it's working fine.

Here's the minimum Monarch code:

export default {
  tokenizer: {
    initial: [
      [
        /^\s*%%(?={)/,
        { token: 'keyword', bracket: '@open', next: '@directive', nextEmbedded: 'javascript' },
      ],
    ],
    directive: [
      [/%%$/, { token: 'keyword', bracket: '@close', next: '@pop', nextEmbedded: '@pop' }],
    ],
  },
};

UI Flickering after updating manually the content (code) of the editor

Hello,

The UserConfig property of the MonacoEditorReactComp allows us to initialise the content of the editor using wrapperConfig / editorAppConfig / code property.

For example:

const userConfig: UserConfig = {
            htmlElement: rootElem,
            wrapperConfig: {
                ...
                editorAppConfig: {
                    $type: 'classic',
                    languageId: 'typescript',
                    useDiffEditor: false,
                    theme: 'vs-light',
                    code: content,
                },
            },
};
<MonacoEditorReactComp
                    ref={editorRef}
                    userConfig={userConfig}
/>

I would like to push an external update to the current editor code, let's consider a button that add a new console.log('Hello') to the editor.

My first attempt was using the useState hook:

const [content, setContent ] = useState(initialCode);

And then call the setContent inside of the onClickHandler of the button, but this cause a restart of the editor getting a flickering in the UI.

Then I found that I can access the current value of the editor as follow:

const editor = editorRef.current?.getEditorWrapper().getEditor();
const currentCode=  editor?.getValue();

and I tried to update the value of the editor inside of a useEffect with content as dependency. In this case, I initialised the wrapperConfig / editorAppConfig / code property with an empty string

editor?.setValue(content);

That approach was worst fully crashing the editor.

My third attempt was to try to update it via the updateModel of the MonacoEditorWrapper but it raised an error so the editor was restarted again.

My code

const wrapper = editorRef.current?.getEditorWrapper();
wrapper?.updateModel({code: code});

The new error

No service init on restart
wrapper.ts:85 Starting monaco-editor (15)
editorAppClassic.ts:101 Init of MonacoConfig was completed.
editorAppBase.ts:109 Uncaught (in promise) Error: You cannot update the editor model, because the regular editor is not configured.
    at EditorAppClassic.updateModel (editorAppBase.ts:109:35)
    at MonacoEditorLanguageClientWrapper.updateModel (wrapper.ts:132:31)
    at index.tsx:79:22
    at commitHookEffectListMount (react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (react-dom.development.js:24878:7)
    at commitPassiveMountEffects (react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (react-dom.development.js:27039:3)
    at flushPassiveEffects (react-dom.development.js:26984:14)

When I looked at the editorAppBase.ts Line 109 the exception is raised because the editor is null/undefined.

editorAppBase.ts

async updateModel(modelUpdate: ModelUpdate): Promise<void> {
        if (!this.editor) {
            return Promise.reject(new Error('You cannot update the editor model, because the regular editor is not configured.'));
        }

        this.updateAppConfig(modelUpdate);
        await this.updateEditorModel();
}

I updated my code as follows, but although the error is gone, the editor still is restarted.

const wrapper = editorRef.current?.getEditorWrapper();

if (wrapper?.getEditor()) {
     wrapper?.updateModel({code: code});
}

In the bellow gif you can see the flickering issue using my first approach. Due to the quality of the gif only on the four addition of the console.log you can see the flickering of the strings.

Sep-07-2023 10-31-12

Does anyone know the right way to update the code of the editor in a programatically/manual way?

Here is the code of my demo. It is basically a modification of the reactTs.ts example available in monaco-components repository

reactTs.ts

import React from 'react';
import ReactDOM from 'react-dom/client';
import EditorDemo from './EditorDemo.js';

const comp = <EditorDemo />
const rootElem = document.getElementById('root')!;
const root = ReactDOM.createRoot(rootElem);
root.render(comp);

EditorDemo.ts

import React, { useState } from 'react';
import { MonacoEditorReactComp } from '@typefox/monaco-editor-react';
import { UserConfig } from 'monaco-editor-wrapper';

import 'monaco-editor/esm/vs/basic-languages/typescript/typescript.contribution.js';
import 'monaco-editor/esm/vs/language/typescript/monaco.contribution.js';

import { buildWorkerDefinition } from 'monaco-editor-workers';
buildWorkerDefinition('../../../../node_modules/monaco-editor-workers/dist/workers', import.meta.url, false);

const EditorDemo: React.FC = () => {
    const logMessage = `console.log('hello')`
    const [content, setContent] = useState(logMessage);

    const rootElem = document.getElementById('root')!;
    const userConfig: UserConfig = {
        htmlElement: rootElem,
        wrapperConfig: {
            serviceConfig: {
                enableKeybindingsService: true,
                debugLogging: true
            },
            editorAppConfig: {
                $type: 'classic',
                languageId: 'typescript',
                useDiffEditor: false,
                theme: 'vs-dark',
                code: content
            }
        }
    };

    const addConsoleMessage = () => {
        setContent(`${content}\n${logMessage}`);
    };

    return (
        <>
            <button onClick={addConsoleMessage}>
                Click me!
            </button>
            <MonacoEditorReactComp
                userConfig={userConfig}
                style={{
                    'paddingTop': '5px',
                    'height': '80vh'
                }}
            />
        </>

    );
};

export default EditorDemo;

how do i disable writing to filesystem?

Im getting the following Error:
**

Unable to write file '\workspace\model63.PatCommands' (NoPermissions (FileSystemError): Not allowed)
FileOperationError@webpack://patc/./node_modules/monaco-editor/esm/vs/platform/files/common/files.js?:428:9
writeFile@webpack://patc/./node_modules/@codingame/monaco-vscode-files-service-override/vscode/src/vs/platform/files/common/fileService.js?:325:19

**

my package.json looks as follows:

{
    "name": "patc",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@codingame/monaco-vscode-configuration-service-override": "~1.85.0",
    "@codingame/monaco-vscode-editor-service-override": "~1.85.0",
    "@codingame/monaco-vscode-keybindings-service-override": "~1.85.0",
        "@typefox/monaco-editor-react": "^2.6.0",
        "@types/react": "^18.2.22",
        "@types/react-dom": "^18.2.7",
        "blue-react": "^9.1.2",
        "clean-webpack-plugin": "^4.0.0",
        "copy-webpack-plugin": "^12.0.2",
        "html-loader": "^5.0.0",
        "html-webpack-plugin": "^5.6.0",
        "mini-css-extract-plugin": "^2.7.7",
        "monaco-editor-workers": "^0.45.0",
        "monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.85.0 <1.86.0",
        "monaco-editor-wrapper": "~3.6.0",
       
        "node-polyfill-webpack-plugin": "^3.0.0",
        "npm-run-all": "^4.1.5",
        "patorg-web-api-js": "^2.4.0",
        "react": "^18.2.0",
        "react-bootstrap-icons": "^1.10.3",
        "react-dom": "^18.2.0",
        "react-router-dom": "^6.22.0",
        "react-scripts": "5.0.1",
        "sass": "^1.68.0",
        "sass-loader": "^14.0.0",
        "vscode": "npm:@codingame/monaco-vscode-api@>=1.85.0 <1.86.0",
        "vscode-languageclient": "^9.0.1",
        "vscode-languageserver-protocol": "^3.17.5",
        "webpack": "^5.90.0",
        "webpack-cli": "^5.1.4",
        "worker-loader": "^3.0.8"
    },
    "scripts": {
        "start": "webpack serve --config webpack.config.js --mode development",
        "backend-start": "node server.js",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": {
        "production": [
            ">0.2%",
            "not dead",
            "not op_mini all"
        ],
        "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
        ]
    },
    "devDependencies": {
        "ts-loader": "^9.5.1"
    },
    "overrides": {
        "monaco-editor": "$monaco-editor",
        "vscode": "$vscode"
    },
    "resolutions": {
        "monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.85.0 <1.86.0",
        "vscode": "npm:@codingame/monaco-vscode-api@>=1.85.0 <1.86.0"
    }
}

i have no webpack-resolutions in place. can anyone tell me how i stop editor from trying to write to my filesystem?

[Monaco Editor React Component] unavailable language server throws unhandled error

When the component mounts and the language server is not available, an error get thrown but not caught, which then also seems to cause the onLoad not to fire. It would be nice if the error simply got caught and logged by the component.

The error thrown:
'''
{
"message": "languageClientWrapper (Python Language Server Example): Websocket connection failed.",
"error": "No error was provided."
}
'''

Provide WebSocket auto reconnection

Automatic reconnection of WebSocket is currently not working. ReconnectingWebSocket was not used here and reconnection capability and configuration should be realized differently. Is it still needed at all. Asses status.

Bundling issues with imported workers from wrapper

When bundling the wrapper in a non-esm project, the following lines throw an error:

// add workers
import 'monaco-editor/esm/vs/language/typescript/monaco.contribution';
import 'monaco-editor/esm/vs/language/html/monaco.contribution';
import 'monaco-editor/esm/vs/language/css/monaco.contribution';
import 'monaco-editor/esm/vs/language/json/monaco.contribution';
// support all basic-languages
import 'monaco-editor/esm/vs/basic-languages/monaco.contribution';

Since these workers aren't necessarily a feature of the wrapper, would it make sense to move them to a separate export that can be imported if a downstream user wants to do that? For most users, importing these workers by default does not pose any advantage.

Multiple Langium Grammars

We have a case where we use multiple grammars in a language project. We have two.langium grammar files and use imports to link them together and reference rules. In the wrapperConfig.editorAppConfig section of UserConfig, there is only support for a single language:

editorAppConfig: {
                $type: 'classic',
                languageId: 'helloworld',
                theme: 'langium-theme',
                code: code,
                useDiffEditor: false,
                editorOptions: {
                    'semanticHighlighting.enabled': true
                },
               languageExtensionConfig: { id: 'langium' },
               languageDef: HelloWorldMonarchContent,
               themeData: LangiumTheme,                
            }

In order to support my case, where we generate multiple monarch definition files, my assumption is that I would need to manually merge the two languages back together into a single monarch definitions file in order to use them as intended in the wrapper. Or is there another way to do this where I can specify multiple monarch definition files?

Wrapper constructs incorrect URIs

When constructing a URI, the text after the first // determines the URI authority property. In order to set the path property another, third / is required here:

monaco.Uri.parse(`inmemory://model.${languageId}`));

This leads to issues when the language server that is connected to this editor tries to perform computations based on the name of the file, as its path is an empty string.

monaco-treemending with vite and npm

I used npm create @vite:latest to scaffold a vanilla TS project. After adding a dependency to monaco-editor-wrapper to my package.json file, the monaco-treemending script never shows up in the node_modules/.bin folder, and the monaco-treemending postinstall script fails. Here is my package.json:

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "postinstall": "monaco-treemending"
  },
  "dependencies": {
    "monaco-editor-workers": "^0.43.0",
    "monaco-editor-wrapper": "^3.0.1",
    "monaco-languageclient": "^6.4.6",
    "vscode-languageclient": "^8.1.0"
  },
  "devDependencies": {
    "typescript": "^5.0.2",
    "vite": "^4.4.5"
  }
}


My assumption here is that I'll need to add the @codingame/monaco-vscode-api in order to fix this.

Shouldn't this script come along with the monaco-editor-wrapper node module?

Wrapper: Passing an Unreachable Worker Url causes Unresponsiveness

For the latest version of monaco-editor-wrapper, and previous versions, passing an invalid LS url causes the application to become unresponsive. This can happen when the languageClientConfig.workerConfigOptions of the UserConfig contains either:

  • a worker setup with an invalid url: (ex. new Worker('oops.js'))
  • a configuration for worker with a url:
{
    url: new URL('oops.js', window.location.href),
    type: 'module',
    name: 'some-name',
}

In either case, if the resulting UserConfig that contains this unreachable url is passed into the start method of a wrapper, the application will hang indefinitely.

const wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.start(userConfig);
// no rejection or resolution happens, effectively frozen

This issue is particularly hard to debug as a result, and once found it's often unclear why the start method isn't returning.

As a possible solution, we should make a 'best attempt' to determine that a given url (or pre-configured Worker) is valid. If not we should reject, allowing the resulting promise to finish up, and report the relevant error back to the user. The question remains at what stage within the wrapper to perform this sanity check, but if we can detect this case that would help others to resolve this issue quickly.

Types missing in monaco editor wrapper

Hello, trying out Langium and stumbled on the following problem:

While trying to use monaco-editor-wrapper by directly importing in a TS frontend project using this command:

import { monaco, MonacoEditorLanguageClientWrapper, vscode } from "monaco-editor-wrapper/bundle";

instead of the tutorial recommended way of copying the dist files, I saw that the types referenced were missing and so I looked it up and it looks like the package is importing monaco-editor here:

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';

but because it's missing from the "dependencies" in package.json, the files point to nowhere, so all the types end up as any. Adding the dependency and installing it manually inside the node_modules/monaco-editor-wrapper dir, works just fine, the issue is that doesn't survive a clean npm install.

Regardless, thank you for making Langium, it's such a nice project!

Render other VSCode UI view parts

Hi there! I have a question about rendering editor parts (e.g. editor group view and side bar) other than the single tab.

I have a working React component set-up similar to monaco-vscode-api's demo where I attach the default VSCode UI parts one by one like so:

     // initiaze our vscode ui by assigning the refs to the corresponding DOM elements
     // and handle their visibility.
        for (const {part, element} of [
            {part: Parts.TITLEBAR_PART, element: titleBarRef.current},
            {part: Parts.BANNER_PART, element: bannerRef.current},
            {part: Parts.SIDEBAR_PART, element: sideBarRef.current},
            {
                part: Parts.ACTIVITYBAR_PART,
                element: activityBarRef.current
            },
            {
                part: Parts.EDITOR_PART,
                element: editorPartRef.current
            }, {part: Parts.STATUSBAR_PART, element: statusBarRef.current}, {
                part: Parts.AUXILIARYBAR_PART,
                element: auxiliaryBarRef.current
            }
        ]) {
            attachPart(part, element!)

            if (!isPartVisibile(part)) {
                element!.style.display = 'none'
            }

            onPartVisibilityChange(part, visible => {
                element!.style.display = visible ? 'block' : 'none'
            })
        } 

I need the editors view of EditorPart which allows multiple tabs and split views and the file system sidebar to view mounted files.

I wonder if it's possible with monaco-editor-react.

I'd really like to use monaco-editor-react UserConfig API etc but I also need the views. Please kindly advise. Thanks!

Having the component twice on a page

Hi, do you have a hint how to have the component twice on a page.
am currently getting

Uncaught (in promise) Error: Services are already initialized
    at checkServicesNotInitialized (lifecycle.js:68:15)
    at initialize2 (services.js:84:5)
    at importAllServices (monaco-vscode-api-services.ts:101:11)
    at initServices (monaco-vscode-api-services.ts:29:15)
    at LanguageClientWrapper.init (languageClientWrapper.ts:93:15)
    at MonacoEditorLanguageClientWrapper.init (wrapper.ts:62:42)

How to modify client's capabilities?

There seems not to export an interface to modify the initialize request's capabilities params?
I want to disable workspace.didChangeWatchedFiles capability, because there are no corresponding files to watch.

Bundling without vscode

Hi, has someone experimented bundling (am using create-react-app) without vscode to reduce bundle size?

Lit Component

My team would like to build a Lit component to wrap an editor for a language that we created using Langium. We have a Lit app almost working with a component that should be able to provide the editor for our language. However, we are running into problems with rollup when we try to build the app. It seems that the monaco-editor-wrapper does some things that rollup doesn't like.

I came across the recent announcement about the monaco-editor-wrapper Lit component being discontinued in the latest release.

image

My questions are:

  1. Is there a way to deliver the editor wrapper as a Lit component at all?
  2. Should we just try to wrap the React editor so that we can use it in a Lit app?
  3. Should my question be redirected to the Langium repo?

Thanks

Samples on @typefox/monaco-editor-react": "2.0.0"

Hi once again:) Huge sorry for tickets spamming, I'm just curious, do you have any plans for monaco-editor-react 2.0.0 release? I'm playing around language server support for JVM languages (kotlin example), and just discovered that the latest version of your libs in NPM is 1.1.1 (according to this page: https://www.npmjs.com/package/@typefox/monaco-editor-react), but examples in this repository are already using 2.0.0, so it's a bit complex to follow

Considerations on having more that one document in workspace in react/wrapper usecase

Considerations on having more that one document in workspace in react/wrapper usecase

We have the following usecase:

  • we want to user give the opportunity to edit one file in the webbrowser (react app)
  • in this files elements from other files should be referrable

Right now we do the following

  • we have customized main-brower to receive a (initial) message with that other files contents and then construct the language worker with a special Workspace Manager that know the files as builtin resources

This works fine until we want to exchange the to be edited file along with its other files in react.

If the component is not remounted, then the componentDidUpdate call wont reinit monaco as before and after we just have a worker
thus we cannot plugin a new worker

we currently circumvent this problem by passing a key to the component to force remount

i am thinking about what could be done to make this nicer or more generic

  • instead of using workspaceMgr and builtin files we could use lsp didOpen calls to open multiple files. if the protocol works fine they all should end up in the same ws and visibile to each other (did not test that yet), but this also would require a hook in the component or a prop to pass multiple resources

  • we at least could make the current approach more robust by adding a prop to force remount on componentDidUpdate

do you have more ideas or hints? Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.