From 68a7517decccd5b40bd3fdbbe4287e28bfbf3fb7 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 27 Jan 2026 16:17:33 -0500 Subject: [PATCH] Fix race condition in vim connect with ready signal --- adapters/vim/bridge.ts | 3 +++ adapters/vim/collab.vim | 22 +++++++++++++++++++--- src/protocol.ts | 8 ++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/adapters/vim/bridge.ts b/adapters/vim/bridge.ts index c0a9ad4..80f8ce6 100644 --- a/adapters/vim/bridge.ts +++ b/adapters/vim/bridge.ts @@ -15,6 +15,9 @@ function send(msg: object) { console.log(JSON.stringify(msg)); } +// signal to vim that bridge is ready +send({ type: "ready" }); + function connect(roomName: string) { doc = new Y.Doc(); text = doc.getText("content"); diff --git a/adapters/vim/collab.vim b/adapters/vim/collab.vim index 0a3c8be..a62d013 100644 --- a/adapters/vim/collab.vim +++ b/adapters/vim/collab.vim @@ -6,6 +6,7 @@ vim9script var bridge_job: job var bridge_channel: channel var connected = false +var ready = false var room = "" var suppressing = false @@ -29,7 +30,9 @@ def OnOutput(ch: channel, msg: string) return endtry - if data.type == 'connected' + if data.type == 'ready' + ready = true + elseif data.type == 'connected' connected = true echom '[collab] connected to room: ' .. data.room elseif data.type == 'disconnected' @@ -72,6 +75,7 @@ export def Connect(room_name: string) endif room = room_name + ready = false bridge_job = job_start(['bun', 'run', bridge_script], { mode: 'nl', out_cb: OnOutput, @@ -79,8 +83,19 @@ export def Connect(room_name: string) }) bridge_channel = job_getchannel(bridge_job) - # give it a moment to start - sleep 100m + # wait for bridge ready signal + var timeout = 50 + while !ready && timeout > 0 + sleep 10m + timeout -= 1 + endwhile + + if !ready + echoerr '[collab] bridge failed to start' + Disconnect() + return + endif + Send({type: 'connect', room: room_name}) # set up autocmds to send changes @@ -98,6 +113,7 @@ export def Disconnect() bridge_channel = null endif connected = false + ready = false room = "" augroup CollabVim autocmd! diff --git a/src/protocol.ts b/src/protocol.ts index 16bf9d5..5c6a5c1 100644 --- a/src/protocol.ts +++ b/src/protocol.ts @@ -12,6 +12,14 @@ export type ServerMessage = | { type: "awareness"; data: number[] } | { type: "peers"; count: number }; +export type BridgeMessage = + | { type: "ready" } + | { type: "connected"; room: string } + | { type: "disconnected" } + | { type: "content"; text: string } + | { type: "peers"; count: number } + | { type: "error"; message: string }; + export function encode(msg: ServerMessage): string { return JSON.stringify(msg); }