diff --git a/frontend/obsidian-plugin/src/views/cursors/remote-cursors-plugin.ts b/frontend/obsidian-plugin/src/views/cursors/remote-cursors-plugin.ts index 04669a16..8801ecda 100644 --- a/frontend/obsidian-plugin/src/views/cursors/remote-cursors-plugin.ts +++ b/frontend/obsidian-plugin/src/views/cursors/remote-cursors-plugin.ts @@ -18,25 +18,6 @@ import { getRandomColor } from "src/utils/get-random-color"; import type { SpanWithHistory } from "reconcile-text"; import { reconcileWithHistory } from "reconcile-text"; -function findWhereToMoveCursor( - cursor: number, - spans: SpanWithHistory[] -): number | null { - let position = 0; - for (const span of spans) { - // left and origin are the same - if (position === cursor && span.history === "AddedFromRight") { - return position + span.text.length; - } - position += span.text.length; - if (position === cursor && span.history === "RemovedFromRight") { - return position - span.text.length; - } - } - - return null; -} - const forceUpdate = StateEffect.define(); export class RemoteCursorsPluginValue implements PluginValue { @@ -98,6 +79,69 @@ export class RemoteCursorsPluginValue implements PluginValue { }); } + private static interpolateRemoteCursorPositions( + original: string, + edited: string + ): void { + if ( + original === edited || + RemoteCursorsPluginValue.cursors.length === 0 + ) { + return; + } + + const updatedPositions: number[] = []; + const reconciled = reconcileWithHistory( + original, + { + text: original, + cursors: RemoteCursorsPluginValue.cursors.flatMap( + ({ span }, i) => [ + { id: i * 2, position: span.start }, + { id: i * 2 + 1, position: span.end } + ] + ) + }, + edited + ); + + reconciled.cursors.forEach(({ id, position }) => { + const whereToJump = RemoteCursorsPluginValue.findWhereToMoveCursor( + position, + reconciled.history + ); + if (whereToJump !== null) { + updatedPositions[id] = whereToJump; + } else { + updatedPositions[id] = position; + } + }); + + RemoteCursorsPluginValue.cursors.forEach(({ span }, i) => { + span.start = updatedPositions[i * 2]; + span.end = updatedPositions[i * 2 + 1]; + }); + } + + private static findWhereToMoveCursor( + cursor: number, + spans: SpanWithHistory[] + ): number | null { + let position = 0; + for (const span of spans) { + // left and origin are the same + if (position === cursor && span.history === "AddedFromRight") { + return position + span.text.length; + } + position += span.text.length; + if (position === cursor && span.history === "RemovedFromRight") { + return position - span.text.length; + } + } + + return null; + } + public update(update: ViewUpdate): void { const original = update.startState.doc.toString(); const edited = update.state.doc.toString(); @@ -179,50 +223,6 @@ export class RemoteCursorsPluginValue implements PluginValue { this.decorations = Decoration.set(decorations, true); } - - private static interpolateRemoteCursorPositions( - original: string, - edited: string - ): void { - if ( - original === edited || - RemoteCursorsPluginValue.cursors.length === 0 - ) { - return; - } - - const updatedPositions: number[] = []; - const reconciled = reconcileWithHistory( - original, - { - text: original, - cursors: RemoteCursorsPluginValue.cursors.flatMap( - ({ span }, i) => [ - { id: i * 2, position: span.start }, - { id: i * 2 + 1, position: span.end } - ] - ) - }, - edited - ); - - reconciled.cursors.forEach(({ id, position }) => { - const whereToJump = findWhereToMoveCursor( - position, - reconciled.history - ); - if (whereToJump !== null) { - updatedPositions[id] = whereToJump; - } else { - updatedPositions[id] = position; - } - }); - - RemoteCursorsPluginValue.cursors.forEach(({ span }, i) => { - span.start = updatedPositions[i * 2]; - span.end = updatedPositions[i * 2 + 1]; - }); - } } export const remoteCursorsPlugin = ViewPlugin.fromClass( diff --git a/scripts/e2e.sh b/scripts/e2e.sh index 821bd0bc..952e1855 100755 --- a/scripts/e2e.sh +++ b/scripts/e2e.sh @@ -26,12 +26,14 @@ npm run build ../scripts/utils/wait-for-server.sh -../scripts/update-api-types.sh +cd .. +scripts/update-api-types.sh if [[ $(git status --porcelain) ]]; then git status --porcelain echo "Failing CI because the working directory is not clean after generating api types" exit 1 fi +cd frontend pids=() for i in $(seq 1 $process_count); do @@ -39,7 +41,7 @@ for i in $(seq 1 $process_count); do pids+=($!) done -cd - +cd .. print_failed_log() { for i in $(seq 1 $process_count); do