Considering the ongoing rewrite of the compiler in Zig, I was wondering if there were any plans to rewrite the LSP too. I was looking at the LSP TODOs and, having a bit of experience with writing LSP, I thought I could contribute as well. Though being more interested in Zig over Rust I thought it might be worth starting a Zig rewrite on the side and work from there. Would that be worthwhile or is it better to just contribute to the existing Rust code?
Zig for sure, and actually in the compiler code base! :smiley:
I want to bake a lot of this functionality into the compiler, and in the future expose it in a way that can be used for more than just LSP. But as a starting point we can target LSP directly.
happy to chat about it if you'd like some direction getting started!
Thats perfect! I'd love to chat and start tackling this. I'll definitely make a fork of the compiler repo and work on something from there in the same codebase. How should I get started? By the way Im gonna be offline for a little while, Im on some messed up reverse sleep schedule today
Hi Etienne, I'd be very interested in lending a hand with the LSP if you'd be down. I have a vested interest in the NeoVim Roc LSP experience bahaha.
Sounds great! I could definitely use the help ahah I actually have the scaffolding committed on my fork at the moment. It has the transport layer, the data structure and a very basic server with none of the capabilities yet apart from initialized and exit. I will likely make a pull request soon so we can start integrating some functionalities one by one. Im just doing a bit more thorough testing and documenting. It does currently get detected by Neovim though with :LspInfo
Sounds great! Would you have time for a quick call in the next couple days just so I can get on the same page as you? Wanted to hack away on something since I have a long weekend next weekend haha. Very excited!
For sure! I should have time tomorrow during daytime EST if that works with you. If not, better even for me is Thursday evening.
Kind of a messy schedule here, juggling between 40hr/week software dev job, full time university and a girlfriend
Yeah, lemme know if you wanna do around 12 at lunch or maybe 5 PM, I'm also EST. If you're too busy tho that's fine, you can post your PR/post when you merge and I'll pull and start looking at everything. I'm also working so yeah async communication may be easiest to coordinate on the LSP.
12 is good! I might have to make the PR happen early in the morning though. Just got off a double shift so my brain is fried and theres some technical tweaks I want to do. Gonna sleep it off and wake up at around 4am so I'll get something out way before 12
By the way, we might want to take this convo into the DM. Some people might have other things to add here though
If you could just share any plans or updates once you've figured out the details in this thread that would be most appreciated -- it will help others contribute.
I'm really excited to have an LSP for the new syntax :smiley:
I just made the pull request. The request itself contains information about the implementation, but I also added a README.md in the new src/lsp folder alongside the other files.
Simply put the transport.zig and protocol.zig have been abstracted in a way that they shouldn't require change. When it comes to adding new functionnalities it'll be as simple as adding the new handler to the handlers directory and implementing them the same way as the current basic initialize and exit methods. Every handlers takes the ServerType which holds the state of the project as well as the functions to communicate back to the editor.
Also I suggest using the --debug-transport flag when connecting to the LSP with your editor. Since the LSP takes control over the stdin and stdout you can have all the requests and responses mirrored to a temporary log file. That way you can just watch it with tail -f while youre testing things out.
Currently the LSP is started with roc experimental-lsp, should we put the LSP in a separate binary to avoid that people start relying on it being included in the long term @Richard Feldman?
Actually he told me himself to have it be executed like that with roc experimental-lsp
yeah I think for now this will be the easiest way to get everything up and running, and "experimental" should convey "expect the way this works to change!"
Working on some change currently on the base structure of the LSP as I'm figuring out on the implementation of didChange and didOpen notifications. Wouldn't make sense to group them with requests such as initialized and shutdown as those expect a response immediately. Anyway in the LSP specifications they're separated between notification and request. Also working on a DocumentStore to handle the project different documents and store them in a StringHashMap. Could probably implement some caching later on to not have to reload every documents whenever the editor close. Particularly with neovim as it restart an lsp session every time you close all your buffers.
Also working on a DocumentStore to handle the project different documents and store them in a StringHashMap
I'm not 100% on the use case here ... but maybe it would help for you to checkout our cache manager implementation if you haven't seen that yet
We also have a file watcher implementation that is cross-platform
The cache manager is used to store the serialised modules into the roc cache
The StringHashMap is only to store the plain text of the files. Its really just meant to have the current buffer in memory so that we can do some parsing on it for things like syntax check
The file watcher and cache manager might definitely be useful though
Last updated: Nov 28 2025 at 12:16 UTC