haskell / haskell/lsp

Unbundle `LSP.Sever`

Open
#417 1 comment 1 reaction 0 assignees View on GitHub
v3
Dominant language
Haskell
Stars
423
Forks
105
PR merge metrics
No merged PRs in 30d

Description

At the moment `LSP.Sever` is "framework-like": you provide various kinds of functions via the monolithic `SeverDefinition`, and then the server framework is responsible for calling them. This has some warts:
- It is unclear what is handled by the framework and what isn't (see e.g. https://github.com/haskell/lsp/issues/414)
- It is difficult to customize parts of the behaviour
- A big example is the message dispatch loop. Our "reactor" example is (IMO) godawful: you have to override the *handlers* in order to sneak in some custom *dispatch* logic. `ghcide` similarly tries to completely bypass this. (Also see e.g. https://github.com/haskell/lsp/issues/409)
- Another example is whether or not to feed the `intializationOptions` to the configuration changed function. This isn't specified in the spec, but some clients expect it, so it's really something the server author should decide about, not us.
- It is difficult to mange state differently. For example, HLS wants to delay updates to the VFS so that long-running processes don't see inconsistent states. To do this they have to implement a complete second layer which takes VFS snapshots!

Here's some ideas for how to unbundle this:
- Modularise the server in/out into `IO` actions that communicate over a channel, which clients can fork as they like.
- Modularise the initialization handlers so we provide a number of standard handlers which do common actions and which can be combined with `<>`.
- Modularise state accesses so that they access the state via a typeclass, allowing multiple implementations.
- More?

Big questions:
- Is this a good direction of travel?
- Are there going to be any bits that will be really difficult?

Contributor guide

Open the contributing guide

Research direction

Start by reading LSP.Sever and the monolithic SeverDefinition, then compare the reactor example and ghcide's handling of dispatch and VFS state. The issue does not identify files or tests; done would require an agreed, implementable decomposition of server I/O, initialization handlers, and state access.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
devtools
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.