openlawlibrary / pygls

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

Add some example servers #440

Closed alcarney closed 3 months ago

alcarney commented 4 months ago

I'm concious of the fact #418 is a rather large PR!

I've also realised that there's a growing amount of work in #418 that is not directly dependant on the new architecture. So, this PR is a first pass at breaking some of that work out into a separate PR which we can merge now.

As part of refactoring the tests under tests/lsp to be end-to-end tests, I have been introducing small example servers which not only help with the tests, but which should help anyone new to pygls/lsp get to grips with how things work. This PR adds the following example servers:

Filename Works With Description
code_lens.py sums.txt Evaluate sums via a code lens
colors.py colors.txt Provides a visual representation of color values and even a color picker in supported clients
goto.py code.txt Implements the various "Goto X" requests in the specification for a dummy programming language
hover.py dates.txt Opens a popup showing the date underneath the cursor in multiple formats
publish_diagnostics.py sums.txt Use "push-model" diagnostics to highlight missing or incorrect answers
pull_diagnostics.py sums.txt Use "pull-model" diagnostics to highlight missing or incorrect answers

Side note: I'm thinking we should start moving away from json_server.py as our flagship example for two reasons.

  1. Small focused examples are probably easier to parse than one big one.
  2. Editors like VSCode have a lot of built-in support for JSON - it might not be obvious to tell which features are from pygls and which are from the editor.

Code review checklist (for code reviewer to complete)

tombh commented 4 months ago

This is epic, so many useful examples and tests 🥰 I'll take a good long look soon.

tombh commented 3 months ago

Sorry for the delay, I've had a good look and think about this now. Again, really epic work here. This is so much more than just adding great new tests, it's self-documenting and generous to newcomers and experts alike.

Also, as always, thank you so much for the self-contained commits, they really make understanding the changes here more digestible.

I'd be happy to merge this as is! But here are some comments, they're very minor, so unless they resonate, don't worry about them:

Dwi'n dysgu am englyn yn fy dosbarthiau cymraeg ddiweddar. Yr PR yma yn atgoffa o y llinell glasurol:

Campwaith dewin hynod

🪄

alcarney commented 3 months ago

Could assert test_uri is not None live in the uri_for function itself?

Yes, good spot

The following seems to be a common pattern: To what extent can it be refactored?

Perhaps get_client_for can handle it and the fixture just becomes yield from get_client_for(...), I'll have a play and see if it will work

alcarney commented 3 months ago

Turns out you can't yield from an async generator, but an async for loop seems to work, so the fixtures now have the form

@pytest_asyncio.fixture()
async def json_server(get_client_for):
    async for result in get_client_for("json_server.py"):
        yield result

And what about linking each example server from the bottom of https://pygls.readthedocs.io/en/latest/pages/getting_started.html#quick-start?

I'll probably handle this in a separate PR - perhaps #427

tombh commented 3 months ago

Great 😊