diff --git a/src/move.ts b/src/move.ts index 2341b71..9689abc 100644 --- a/src/move.ts +++ b/src/move.ts @@ -1,65 +1,50 @@ import * as vscode from "vscode"; import { LiveRunMove } from "./types"; import { addRunMoves } from "./client"; -import { randomInt } from "crypto"; - -let lastText = ""; -let lastCursor = 0; -let moveId = 0; export function startMonitoring(runId: string) { - lastText = ""; + let moveId = 0; + let moves: LiveRunMove[] = []; + let lastLatency = Date.now(); - return setInterval(() => { + const docSub = vscode.workspace.onDidChangeTextDocument((e) => { const editor = vscode.window.activeTextEditor; - if (!editor) return; + if (!editor || e.document !== editor.document) return; + + const edit = e.contentChanges[0]; + if (!edit) return; + + const now = Date.now(); + const latency = capToZeroAbove(now - lastLatency, 350); + lastLatency = now; - const currentText = editor.document.getText(); const cursorOffset = editor.document.offsetAt(editor.selection.active); - let change: { from: number; to: number; insert: string } | undefined; - - if (currentText !== lastText) { - let start = 0; - while ( - start < lastText.length && - start < currentText.length && - lastText[start] === currentText[start] - ) { - start++; - } - - let endOld = lastText.length - 1; - let endNew = currentText.length - 1; - while ( - endOld >= start && - endNew >= start && - lastText[endOld] === currentText[endNew] - ) { - endOld--; - endNew--; - } - - change = { - from: start, - to: endOld + 1, // ⚡ correct range in old text - insert: currentText.slice(start, endNew + 1), - }; - - lastText = currentText; - } - - const move: LiveRunMove = { - latency: 300, + moves.push({ + latency, cursor: cursorOffset, - changes: change, - moveId, - }; + changes: { + from: edit.rangeOffset, + to: edit.rangeOffset + edit.rangeLength, + insert: edit.text, + }, + moveId: moveId++, + }); + }); - if (move.changes || move.cursor !== lastCursor) { - addRunMoves(runId, [move]); + const sendInterval = setInterval(() => { + if (moves.length) { + addRunMoves(runId, moves); + moves = []; } + }, 3000); - lastCursor = move.cursor; - }, 1000); + return () => { + docSub.dispose(); + clearInterval(sendInterval); + }; +} + +function capToZeroAbove(value: number, max: number) { + return value > max ? 0 : value; } diff --git a/src/run.ts b/src/run.ts index 67eae81..75a71a9 100644 --- a/src/run.ts +++ b/src/run.ts @@ -4,7 +4,7 @@ import { startMonitoring } from "./move"; export var currentRun: { interval: NodeJS.Timeout; - monitorInterval: NodeJS.Timeout; + stopMonitoring: () => void; problemId: string; start: Date; id: string; @@ -48,6 +48,7 @@ export async function startRun( id: runId, problemId, start: new Date(), + stopMonitoring: startMonitoring(runId), interval: setInterval(() => { const elapsed = Date.now() - start; @@ -59,7 +60,6 @@ export async function startRun( .toString() .padStart(2, "0")}`; }, 50), - monitorInterval: startMonitoring(runId), }; await vscode.commands.executeCommand("setContext", "devrun.runActive", true); @@ -68,8 +68,6 @@ export async function startRun( export async function stopRun() { if (currentRun) { clearInterval(currentRun.interval); - clearInterval(currentRun.monitorInterval); - submitRun(currentRun.id); currentRun = null;