Show HN: Real-Time Collaboration over LSP

3 days ago 1

A prototype of editor-agnostic real-time collaboration over Language Server Protocol

Note

While I was making this prototype, ethersync changed its name to teamtype and it will take some time to change the package name everywhere

NeoVim <-> Helix

nvim-helix


Zed <-> Helix

zed-helix

The basic usage similar to the ethersync one. Start sharing in the first directory via ethersync share, copy the invite code and run ethersync join <invite code> in the second directory.

Then, in each of those directories open the same file with Helix (or any LSP capable editor. But I find Helix the easiest option) as hx file.teamtype. As of now, both Zed and Helix are configured to only start teamtype-lsp for *.teamtype files only.

Make sure teamtype-lsp command is available in your path

This project is a simple LSP proxy for Teamtype. Teamtype handles p2p and CRDT parts, while the teamtype-lsp simply consists of two loops: one receives messages from the teamtype daemon, converts them to one of LSP requests and send to the editor. The other one is the same, but listens to editor's messages and send them to the daemon.

On the basic level, the flow is as:

# Local changes flow editor -(textDocument/didChange)-> teamtype-lsp -(edit)-> daemon -> peers # Remote change flow daemon -(edit)-> teamtype-lsp -(workspace/applyEdit)-> editor

There are also additional niceties, like showing other peer's cursor via inlay hints

cargo install --git https://github.com/nonscalable/teamtype-lsp

To try out the teamtype-lsp in Zed, follow this guide

Features that are theoretically possible

Share/Join with code actions

The flow could be:

Peer 1

  1. Trigger the code actions menu
  2. Choose "Share"
  3. Once the action is chosen, the language server parses daemon's output, copies the share code and sends it to the editor as a TextEdit
  4. The peer copies the code and sends it to the other peer

Peer 2

  1. The peer gets the code and pastes it to the text file
  2. Select the code and trigger a "Join" code action
  3. The language server validates the code and starts a local daemon

Follow other peer's cursor

If an editor implements window.showDocument with takeFocus option, then it might be possible to use it to change the editor's focus from the language server.

The flow would be:

  1. Trigger the code actions menu
  2. Choose "Follow" option (what if there are multiple peers?)
  3. Once that chosen, the server tracks the incoming edits and sends the showDocument requests
  4. To stop the following, the server might be listening to local textDocument/didChange events and if there is one, stop sending showDocument messages

Right now, the language server assumes that the editor does not implement workspace/inlayHint/refresh request, which lets the server to ask the editor to request the inlay hints.

However, if an editor does implement that (like Zed), it should be possible to track all incoming remote edits and ask the editor to request new inlay hints on each change

Read Entire Article