Contributing
May 7, 2026 · View on GitHub
Prerequisites
- .NET 10 SDK (version 10.0.100 or later,
as specified in
global.json)
Build
dotnet build
Run tests
dotnet test
dotnet test will build the project automatically before running the tests.
To run only the unit tests (request scheduling, JSON-RPC transport, etc.) without starting
a server process, filter by category:
dotnet test --filter "FullyQualifiedName~RequestScheduling|FullyQualifiedName~JsonRpc|FullyQualifiedName~ProgressReporter"
Test Guidelines
Inside async {} handler lambdas passed to the transport or scheduler, never use
blocking calls (mre.Wait(), Async.RunSynchronously, task.Result, Thread.Sleep).
They starve the thread pool and deadlock the MailboxProcessor event loop.
Use async equivalents (Async.AwaitWaitHandle, let!, Async.AwaitTask, Async.Sleep) instead.
This restriction does not apply to the test body itself, which runs on a dedicated thread.
Code Style
- Language is F#, not C#. File order in
.fsprojmatters — new files must be inserted at the correct position. - Every handler in
Handlers/must exportprovider,registration, andhandle, and returnAsync<LspResult<'T> * LspWorkspaceUpdate>. - Tag every handler with the correct
RequestMode(ReadOnly,ReadWrite, orReadOnlyBackground) when registering inLsp/Server.fs. - Test functions use top-level
[<Test>]let bindings inside a module — not[<TestFixture>]classes. - Formatter: Fantomas (declared in
.config/dotnet-tools.json). Set up withdotnet tool restore, then run on any F# files you modify before committing:dotnet fantomas <file-or-dir>
Commit Messages
Use Conventional Commits style:
<type>(<scope>): <short summary>
Examples:
feat(hover): include XML doc summary for property symbols
fix(completion): avoid NullReferenceException on empty import list
refactor(diagnostics): extract analyzer helper into Roslyn/Analyzers.fs
test(codeaction): add integration test for organize-imports action
docs(contributing): add conventional commits guidance
chore(deps): bump Fantomas to 7.0.3
Install locally
dotnet pack src/CSharpLanguageServer
dotnet tool install --global --add-source src/CSharpLanguageServer/nupkg csharp-ls