@codemirror/lsp-client

Hi all. I’ve published my implementation of a language server protocol client for CodeMirror, @codemirror/lsp-client. Its development was kindly sponsored by zoo.dev.

The package, as it stands, supports autocompletion, hover tooltips, signature hints, go-to-definition, symbol rename, reformatting, and finding references for a symbol. If you need support for another aspect of the LSP protocol, and would be willing to sponsor the work of adding it, contact me.

The package is set up to make it relatively easy to make custom requests to the language server, allowing you to use custom protocol extensions or implement things the package doesn’t support yet in client code.

The main points on which this differs from existing implementations are…

  • It tries to be general enough to handle multi-file scenarios and custom code that communicates with the server.

  • It is very careful about asynchronicity issues (where state changes during requests) and tries to, where it makes sense and is safe, reinterpret server responses to apply to the current version of the document, rather than the one that the server knows about, by mapping positions.

  • It uses core CodeMirror tooltips and panels for the UI parts, again helping keeping everything coherent even when the document is changed while the UI elements are active.

The package hasn’t seen a lot of use yet, except my own tests against a TypeScript server and a custom test stub LSP server, so I’m sure there are issues still, as well as unexpected server behaviors that other language servers might show. If you run into problems, please comment here or file and issue.

11 Likes

bloody brilliant! thanks to zoo.dev for the sponsor :slight_smile:

This is lovely, thanks for putting this together :clap: :heart: I’ve immediately had to try it and it works like a charm.

1 Like

Glad to hear we have this. :hand_with_index_finger_and_thumb_crossed:

Hi, I am just starting to explore this and it looks good.

I have an issue getting markdown hover messages displayed. Is this supported? I assumed it is because the initialize message sent to my server has:

"hover": {   "contentFormat": [ "markdown",    "plaintext" ]   },

In response to a client "method":"textDocument/hover" my server sends:

{
    "jsonrpc": "2.0",
    "id": 2,
    "result": {
        "contents": [
            {
                "language": "markdown",
                "value": "markdown: this is **bold** \n      a [link](http:\/\/google.com)\n      The last line."
            },
            {
                "language": "plaintext",
                "value": "plaintext: A hover for {\"line\":0,\"character\":19}"
            }
        ]
    }
}

The client shows

Am I missing some configuration step to get the markdown displayed correctly?

1 Like

The way I read the spec on MarkedString is that the {language, value} format indicates that this is code that should be highlighted, not rendered as Markdown content.

I do see that the library currently interprets plain strings in MarkedString format incorrectly. Those should be treated as Markdown by default. This patch should help with that.

Thanks!
Yes, I misinterpreted the message format. I now send

{
    "jsonrpc": "2.0",
    "id": 2,
    "result": {
        "contents": [
            "markdown: this is **bold** \n      a [link](http:\/\/google.com)\n      The last line.",
            "plaintext: A hover for {\"line\":0,\"character\":2}"
        ]
    }
}

And with your fix I get:

Great to hear. I’ve tagged version 6.0.1 with the fix.

Thanks. I now notice that the \ns are not rendered as new lines as I would expect with markdown even though the 1st hover is sized for 3 lines. This is not an immediate problem for me.

Standard markdown treats single newlines as part of paragraphs. You need a backslash before them create a hard break, or two newlines to start a new paragraph.

1 Like