monaco-languageclient icon indicating copy to clipboard operation
monaco-languageclient copied to clipboard

MonacoEditorLanguageClientWrapper doesn't notify the server about changes

Open soaibsafi opened this issue 1 year ago • 2 comments

I am using monaco-languageclient and monaco-editor-wrapper for my DSL.

I configure the react component as follows:

import React, { useEffect, useRef } from 'react';
import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
import { createUserConfig } from './config.js';


export const App: React.FC = () => {
  const editorRef = useRef<HTMLDivElement | null>(null);
  const wrapperRef = useRef<MonacoEditorLanguageClientWrapper | null>(null);
  const isInitialized = useRef(false);

  useEffect(() => {
    if (isInitialized.current) return; 
    isInitialized.current = true;

    const code = `a -> b`;
    const initializeEditor = async () => {
      const userConfig = createUserConfig(code);
      const editorWrapper = new MonacoEditorLanguageClientWrapper();
      wrapperRef.current = editorWrapper;
      try {
        await editorWrapper.init(userConfig);
        if (editorRef.current) {
          await editorWrapper.start(editorRef.current);
          console.log('Editor started:', editorWrapper.getTextModels());
        }

      } catch (e) {
        console.error('Error during editor initialization:', e);
      }
    };
    initializeEditor();

    return () => {
      if (wrapperRef.current) {
        wrapperRef.current.dispose();
        wrapperRef.current = null;
      }
    };
  }, []);
  useWorkerFactory({
    ignoreMapping: true,
    workerLoaders: {
      editorWorkerService: () => new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' }),
    }
  });

  return (
    <div>
      <div id="monaco-editor-root"
        ref={editorRef}
        style={{
          height: '80vh', width: '80vw',
        }} />
    </div>
  );
};

The configuration file is as follows:

import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
import { UserConfig } from 'monaco-editor-wrapper';

export const createUserConfig = (code: string): UserConfig => {
  return {
    languageClientConfig: {
      languageId: 'limboole',
      name: 'Limboole Language Server',
      options: {
        $type: 'WebSocketUrl',
        url: 'ws://localhost:30002',
      },
      clientOptions: {
        documentSelector: [{ language: 'limboole', scheme: 'file' }],
        synchronize: {
          configurationSection: 'limboole'
        },
      },
    },
    wrapperConfig: {
      serviceConfig: {
        userServices: {
          ...getKeybindingsServiceOverride()
        },
        debugLogging: true
      },
      editorAppConfig: {
        $type: 'classic',
        codeResources: {
          main: {
            text: code,
             fileExt: 'limboole'
          }
        },
        useDiffEditor: false
      }
    },
    loggerConfig: {
      enabled: true,
      debugEnabled: true
    }
  };
};

For the server, I followed the same instructions in the monaco-languageclient documentation for groovy language server.

When the editor is started, the initialization is successful with jsonrpc connection established.

LIMBOOLE Server received:
{
 jsonrpc: '2.0',
 id: 0,
 method: 'initialize',
 params: {
   processId: null,
   clientInfo: { name: 'Code - OSS', version: '1.92.2' },
   locale: 'en',
   rootPath: null,
   rootUri: null,
   capabilities: {
     workspace: [Object],
     textDocument: [Object],
     window: [Object],
     general: [Object],
     notebookDocument: [Object]
   },
   trace: 'off',
   workspaceFolders: []
 }
}
LIMBOOLE Server sent:
{
 jsonrpc: '2.0',
 id: 0,
 result: {
   capabilities: {
     textDocumentSync: 2,
     hoverProvider: true,
     completionProvider: [Object],
     signatureHelpProvider: [Object],
     definitionProvider: true,
     referencesProvider: true,
     documentHighlightProvider: true,
     documentSymbolProvider: true,
     workspaceSymbolProvider: true,
     codeActionProvider: false,
     documentFormattingProvider: true,
     documentRangeFormattingProvider: true,
     renameProvider: [Object],
     foldingRangeProvider: true,
     executeCommandProvider: [Object],
     workspace: [Object],
     semanticTokensProvider: [Object]
   }
 }
}
{"jsonrpc":"2.0","method":"initialized","params":{}}
{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}
{"jsonrpc":"2.0","method":"$/setTrace","params":{"value":"off"}}

After that, if I change the code in the editor, the server is not receiving the changes. I am not sure what I am missing here. Any help is appreciated.

Thanks!

soaibsafi avatar Sep 25 '24 08:09 soaibsafi

Hi @soaibsafi can you make the above code available in the linked repo?

kaisalmen avatar Sep 27 '24 16:09 kaisalmen

@kaisalmen, Thanks for the reply. Here is a repository containing the server and client code.

  • https://github.com/soaib-bot/monaco-ls-play

soaibsafi avatar Sep 27 '24 17:09 soaibsafi

@soaibsafi sorry I only get to this now. I get a 404 on the above repo.

kaisalmen avatar Oct 25 '24 13:10 kaisalmen

@kaisalmen Thanks. I resolved the issue. There was a problem in my xtext server.

soaibsafi avatar Oct 25 '24 17:10 soaibsafi