Codlab

A code collaboration tool based on the language server protocol.

Goal: allowing easy cross-editor live collaboration

Demo

https://github.com/user-attachments/assets/eaa66fb2-4d6a-40a2-a5e9-34b7714f0609

if viewed on the book: Link to demo video

State

This currently is too unreliable, the editors always end up getting desynced at best or in an infinite editing loop at worst. See why is it complicated to learn more.

TODO

Needed

  • server accept multiple client & broadcast change events
  • doc
  • draw other client cursors
  • check that there is no possible race conditions that would cause a desync in client's documents

Advanced features

  • edit history with author and changes
  • lsp sharing: if one client has an lsp server available but the other doesn't, use the available lsp server remotely
    • requesting to lsp cannot be done from an lsp, this would need to be implemented in an editor specific plugin

$$?

  • branding
  • accounts & authentication
  • vscode extension
  • intellij extension
  • deployment
  • ssl
  • frontpage?

Related Projects

(taken from Ethersync's documentation )

Open-sourceActively developed1Peer-to-peerLocal-first2Editor-agnostic
Ethersync✅ (VS Code, Neovim)
Tandem✅ (Sublime, Neovim, Vim)
Open Collab Tools✅ (VS Code, Eclipse Theia)
crdt.el❌ (Emacs)
instant.nvim❌ (Neovim)
Teletype❌ (Atom)
Etherpad❌ (Web)
HedgeDoc3❌ (Web)
CryptPad❌ (Web)
Nextcloud Text❌ (Web)
Rustpad❌ (Web)
SubEthaEdit❌ (Standalone)
Gobby❌ (Standalone)
Floobits4✅ (Sublime, Atom, Neovim, Vim, IntelliJ, Emacs)
Google Docs❌ (Web)
Visual Studio Live Share❌ (Visual Studio, VS Code)
IntelliJ's Code With Me❌ (IntelliJ)

  1. As of September 2024

  2. This column indicates that the software uses CRDTs, we haven't checked for good offline support

  3. Starting with the (upcoming) version 2.0

  4. Open-source plugins, proprietary server

Random links

Good docs on the topic of document synchronization

Conflict solving libraries to try

From most promising to most obscure:

see Ethersync's comparison here and here (they used both automerge and operational-transform)

Why is it so complicated?

Getting editors synced through an LSP connection is hard, a lot harder than I initially thought.

Overview

To better understand the problem, let's take a simple example:

  • 2 editors are connected to the same server

Here we don't have to deal with 2 or 3 programs but 5:

  • 2 editors, which play the role of LSP clients, sending their modifications to the codlab-clients
  • 2 codlab-clients, which play the role of the LSP servers, receiving modifications from the server and the editor and transfering them
  • 1 codlab-server which for now only broadcasts all the messages it receives, but should be the place conflics should be resolved, before broadcasting
graph TD;
    codlab-server["fa:fa-server Server"]
    codlab-client-1["fa:fa-laptop Client 1"]
    codlab-client-2["fa:fa-laptop Client 2"]
    editor-1["fa:fa-code Editor 1"]
    editor-2["fa:fa-code Editor 2"]
    codlab-server   <--> codlab-client-1
    codlab-server   <--> codlab-client-2
    codlab-client-1 <--> editor-1
    codlab-client-2 <--> editor-2

And we need to keep the documents state in sync for all of these programs.

Editors

Even though we're using the Language server protocol to speak with the editors, all the editors don't behave exactly the same across the editors.

So even though the program might seem to working with a certain combination of editors, it probably will fail with another.

Misc issues

  • I've observed in my tests that helix sometimes sent changes out of order (in "hello world", it sent the w before the space), which caused a desync between the clients.
  • Editors send notification to the LSP servers on each change, including the ones applied by LSP servers themself. And I couldn't find a robust way of detecting changes which come from codlab from the changes the user typed.