Around mid-2017, some of the major open-source code editors starting adding real-time collaboration (RTC) functionality. This allowed developers to create “live” sessions in which they could share their current workspace with trusted collaborators. The plugins have been used for all sorts of different cases, from performing coding interviews to paired programming to collaborative debugging. This sort of collaboration modality has the potential to be even better than paired programming on a single terminal: each developer can control her own input devices and viewport while still being aware of what the other developer(s) are working on. They can work independently while still able to communicate (over a separate voice or video channel) about shared code constructs.
There are plenty of opinions about the efficacy of collaborative coding, but the market is clearly moving towards at least supporting it. Code is just text, after all, which makes it a fairly straightforward data type to keep in sync between many participants. Like most RTC applications, though, it’s the UX that differentiates them. From day one, we’ve focused our efforts on building a collaboration engine that easily supports an optimal collaborative editing experience, because a frustrated user means a lost user.
Visual Studio Code and the Live Share Extension
Visual Studio Code is currently the dominant tool for development. It provides a nice blend of IDE-like functionality and speed (I’m typing this post in VS Code, in fact). Early on, the VS Code team decided to build and maintain the editor component separately from the greated VS Code codebase, branding it “Monaco”. VS Code’s implementation of RTC is called “Live Share” and is packaged as a collection of extensions. Live Share, however, can’t be used (along with any other VS Code extension) with the underlying Monaco editor, so what is a Monaco user to do?
Filling the Gap
That’s where the Collaborative Extensions for Monaco come in. It was too difficult to implement data sync, shared cursors, and shared selections. To address these deficiencies, the extension consists of these components:
EditorContentManagersimplifies dealing with local and remote changes to the editor. Simplify call e.g.
manager.insert(index, 'text')to insert text, and provide an
onInsert(index, text)callback to listen for insertions to the underlying data model.
RemoteCursorManagerprovides a simple utility for rendering the cursors of any other user.
RemoteSelectionManageris a similar utility for rendering another user’s selections within the current document.
These extensions were built in an agnostic manner, and have no dependencies on Convergence or any other data-sync library.