Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSP Server Connected Successfully but No Automatic Notifications Initiated #812

Open
NGC2207 opened this issue Jan 1, 2025 · 3 comments

Comments

@NGC2207
Copy link

NGC2207 commented Jan 1, 2025

Hello, I referenced the code in example and wrote a C language service.

Since I'm using Next.js, to avoid the annoying SSR issues, I opted for @monaco-editor/react , which is relatively more SSR-friendly.

I then ran my Next.js project and the language server. Fortunately, my language server responded and received the code. Unfortunately, my Editor interface did not display any intelligent suggestions.

I compared the logs of my language server with those of a server that successfully provided intelligent completions (using @typefox/monaco-editor-react ) and found that the issue seems to be that it did not automatically initiate textDocument/didOpen, textDocument/documentLink, textDocument/inlayHint,etc.

I reviewed related issues and tried their solutions, including importing npm:@codingame/monaco-vscode-editor-api,but it still didn't work.

I've been trying to resolve this issue for over two weeks, experimenting with various approaches. The only time I succeeded was when I used @typefox/monaco-editor-react,but due to various reasons, I have to use @monaco-editor/react.

I really hope someone with similar experiences can help me. Thank you very much!

My code is only in here

@NGC2207
Copy link
Author

NGC2207 commented Jan 1, 2025

This is the WebSocket request-response diagram in the browser after my code was executed.
image
This is the WebSocket request-response diagram in the browser after using @typefox/react-editor-react.
image

@kaisalmen
Copy link
Collaborator

@NGC2207 did you enforce the monaco-editor version? I have just updated the monaco-editor/react section in the README. If you don't enforce a specific monaco-editor with overrides you may have rivaling versions.

Also, we have next.js verification example that I forgot to mention in the README (just updated that, too).

@NGC2207
Copy link
Author

NGC2207 commented Jan 3, 2025

@kaisalmen Thank you for your response. I’ve retried the process and believe I’ve pinpointed the issue. Let me walk you through the steps with a new demo:

  1. I created a new Next.js project using npx [email protected].
  2. I installed @monaco-editor/react, which automatically installed [email protected].
    image
  3. Since the version of monaco-editor needs to be enforced to npm:@codingame/monaco-vscode-editor-api@~11.1.2, I ran npm install monaco-editor@npm:@codingame/monaco-vscode-editor-api.
    Initially, everything appeared to work correctly. However, upon checking the version of monaco-editor again, I noticed it had changed to 11.1.2, which is actually the version of @codingame/monaco-vscode-editor-api.
    image

According to the compatibility table, @codingame/[email protected] is compatible with [email protected]. However, @monaco-editor/react seems to interpret it as [email protected], which causes it to malfunction.
image

Here’s a comparison of the behavior:

  • When @monaco-editor/react uses [email protected]:

    • Code in src/app/page.tsx:
      image
    • The editor in the browser displays syntax highlighting:
      image
  • When using @codingame/monaco-vscode-editor-api:

    • Code in src/app/page.tsx:
      image
    • The editor loses syntax highlighting:
      image

I’m unsure if this is the correct approach, but when I attempt to initialize services using initServices:
image
the browser encounters an issue:
image
Even after commenting out initServices, the browser still behaves unexpectedly:
image

Here’s my code:

"use client";

import {
  toSocket,
  WebSocketMessageReader,
  WebSocketMessageWriter,
} from "vscode-ws-jsonrpc";
import * as monaco from "monaco-editor";
import {
  CloseAction,
  ErrorAction,
  MessageTransports,
} from "vscode-languageclient/browser.js";
import { MonacoLanguageClient } from "monaco-languageclient";
import { Editor, loader, Monaco } from "@monaco-editor/react";
import getConfigurationServiceOverride, {
  updateUserConfiguration,
} from "@codingame/monaco-vscode-configuration-service-override";
import { initServices } from "monaco-languageclient/vscode/services";

loader.config({ monaco });

export default function HomePage() {
  return (
    <Editor
      height="100vh"
      language="cpp"
      value={`#include<stdio.h>
int main() {
  printf("Hello, World!");
  return 0;
}
`}
      beforeMount={async (monaco: Monaco) => {
        //   await initServices(
        //     {
        //       serviceOverrides: {
        //         ...getConfigurationServiceOverride(),
        //       },
        //     },
        //     {}
        //   );
        updateUserConfiguration(
          JSON.stringify({
            "editor.experimental.asyncTokenization": true,
          })
        );

        monaco.languages.register({
          id: "cpp",
          extensions: [".cpp"],
          aliases: ["C++", "cpp"],
          mimetypes: ["text/x-c++src"],
        });
      }}
      onMount={(
        editor: monaco.editor.IStandaloneCodeEditor,
        monaco: Monaco
      ) => {
        initWebSocketAndStartClient("ws://localhost:30001/clangd");
      }}
    />
  );
}

/** Parameterized version, supports all language IDs */
export const initWebSocketAndStartClient = (url: string): WebSocket => {
  const webSocket = new WebSocket(url);
  webSocket.onopen = () => {
    const socket = toSocket(webSocket);
    const reader = new WebSocketMessageReader(socket);
    const writer = new WebSocketMessageWriter(socket);
    const languageClient = createLanguageClient({
      reader,
      writer,
    });
    languageClient.start();
    reader.onClose(() => languageClient.stop());
  };
  return webSocket;
};

export const createLanguageClient = (
  messageTransports: MessageTransports
): MonacoLanguageClient => {
  return new MonacoLanguageClient({
    name: "Cpp Language Client",
    clientOptions: {
      // Use a language ID as a document selector
      documentSelector: ["cpp"],
      // Disable the default error handler
      errorHandler: {
        error: () => ({ action: ErrorAction.Continue }),
        closed: () => ({ action: CloseAction.DoNotRestart }),
      },
    },
    // Create a language client connection from the JSON RPC connection on demand
    messageTransports,
  });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants