openlawlibrary / pygls

A pythonic generic language server
https://pygls.readthedocs.io/en/latest/
Apache License 2.0
546 stars 101 forks source link

How to develop and test a language server? #437

Open noklam opened 4 months ago

noklam commented 4 months ago

Context

First of all, thank you for making this amazing library. I have no prior experience to VSCode extension / Javascript / backend, even though I am only making silly hint by following the tutorial. It's still very exciting that it requires fairly little work to make something like this working in my IDE almost instantly.

This is not a bug or feature request, I am looking for guidance for developing a language server. Specifically, I am trying to develop a language server with VSCode extension in mind.

Questions:

I read through the entire documentation, but I am still confused how to setup a proper develop environment. So far I have get VSCode working with the debug option and running the example successfully.

  1. How should I develop / test during development? https://pygls.readthedocs.io/en/latest/pages/user-guide.html#tcp This page mentioned the TCP mode will be useful for developing, but I have no idea how to use this. Do you mindly test via clicking the UI to trigger certain action?

Does it makes sense to use something like Postman to send a request to the language server? So far I have seen the Debug Console showing the response from the Language server, but not the client request. Where can I look for some example?

alcarney commented 4 months ago

So far I have get VSCode working with the debug option and running the example successfully.

Do you mean the vscode-playground extension and one of the example servers? Or have you got your own extension setup?

So far I have seen the Debug Console showing the response from the Language server, but not the client request.

If you're using the vscode-playground extension, then setting the pygls.trace.server option to verbose will log both request and response to the pygls output channel. For example...

2024-02-27 18:38:59.251 [info] [Trace - 18:38:59] Sending request 'textDocument/completion - (6)'.
2024-02-27 18:38:59.251 [info] Params: {
    "textDocument": {
        "uri": "file:///var/home/alex/Projects/pygls/examples/servers/workspace/sums.txt"
    },
    "position": {
        "line": 8,
        "character": 0
    },
    "context": {
        "triggerKind": 1
    }
}

2024-02-27 18:38:59.315 [info] [Trace - 18:38:59] Received response 'textDocument/completion - (6)' in 64ms.
2024-02-27 18:38:59.315 [info] Result: {
    "isIncomplete": false,
    "items": [
        {
            "label": "\""
        },
        {
            "label": "["
        },
        {
            "label": "]"
        },
        {
            "label": "{"
        },
        {
            "label": "}"
        }
    ]
}

If you have your own extension, then a similar option will be available, but the exact name will depend on the id you gave to the LanguageClient constructor.

This page mentioned the TCP mode will be useful for developing, but I have no idea how to use this.

I think the idea behind the TCP mode is that you can start the server in a terminal outside of VSCode (potentially easier to attach debuggers that way) and then tell VSCode to connect over TCP instead. However, the playground now supports debugging over STDIO, so I am not sure how much of a difference TCP makes for development now.

Do you mindly test via clicking the UI to trigger certain action?

Personally, I find interacting with the server via the UI to be the easiest way to try things out and experiment. If however, you are looking to write tests for the server then you might be interested in the pytest-lsp plugin (shameless plug! :sweat_smile: )

Hope that helps!

noklam commented 4 months ago

Thanks, that's a nice tips, I would look for the pygls configuration.

I remember I saw this plugin when I start researching, thanks for reminding me I will have a look at that soon.

Do you mainly find out this from your experience, for example I try to search the verbose option but didn't find the specific configuration you mentioned. 🙏🏼appreciate your quick response.

alcarney commented 4 months ago

Do you mainly find out this from your experience

Ultimately, the more you do the more tricks you pick up... though I admit our getting started docs aren't the best - something I hope to eventually fix in #427

noklam commented 3 months ago

I am starting to work on my LSP VScode extension again. Locally I can use the debugger and the LSP works fine. However when I packaged it up to VSCode Marketplace.

I know that this is not a pygls question but more of a VSCode Extension question, but hoping that someone here is experienced with developing pygls VSCode extension and can share some tips how to debug stuff like this. image

alcarney commented 3 months ago

I've never found the JS errors coming from VSCode to be that useful... your best bet is to try and find the stderr output from the underlying Python process which should hopefully give you enough details to figure out what is going on.

Those log messages look like you have used microsoft's template extension? In which case I think the server's stderr output should be showing up in the output channel you've shared, but it's worth double checking to make sure that there aren't any other output channels containing output related to your server.

You can also try increasing the log level of the output channel using the Developer: Set Log Level... command to see if it provides any additional info.

Since there only seems to be an issue with the packaged version then most likely the issue is going to be something "silly" e.g. missing files/dependencies, incorrect python interpreter/environment etc. So it might be worth double checking the basics and seeing if you can spot any differences between your dev setup and the packaged version.

Good luck! :crossed_fingers:

noklam commented 3 months ago

@alcarney indeed I am using the template. My background is python so I am much more familiar with debugging python. Thank you for the advice. 🙏