Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/board-protocol/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dev.fast/board-protocol",
"version": "0.1.3",
"version": "0.1.4",
"description": "Wire contract between a hosted whiteboard board server and its clients.",
"license": "MIT",
"repository": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
ShareAlignment,
ShareSource,
} from "@dev.fast/review-share-protocol";
import { textualRows } from "@review/review-api/lens-alignment";
import { patchRows } from "@dev.fast/whiteboard-document";
import { type DiffHunk, parseUnifiedPatch } from "@review/unified-diff";
import { afterEach, describe, expect, it } from "vitest";

Expand Down Expand Up @@ -60,8 +60,7 @@ const lineCount = (text: string | null) =>
function share(fixture: Fixture) {
const pins = { repositoryId: "repo", base: fixture.base, head: fixture.head };

const rows = textualRows(
fixture.file,
const rows = patchRows(
fixture.patch,
lineCount(fixture.baseText),
lineCount(fixture.headText),
Expand Down
9 changes: 2 additions & 7 deletions packages/review/src/lens-selection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
anchorSelection,
formatAnchor,
parseAnchor,
patchRows,
resolveDiffSelection,
selectSource,
selectionKey,
Expand All @@ -11,7 +12,6 @@ import {
} from "@dev.fast/whiteboard-document";
import { expect, it } from "vitest";

import { textualRows } from "./review-api/lens-alignment.js";
import {
type CoverageFile,
coverageProgress,
Expand Down Expand Up @@ -122,12 +122,7 @@ it("rejects stale or reversed endpoints instead of inventing correspondence", ()
});

it("resolves selections over existing textual hunks, including unchanged gaps", () => {
const alignment = textualRows(
"a",
"@@ -2,2 +2,1 @@\n-deleted\n context",
4,
3,
);
const alignment = patchRows("@@ -2,2 +2,1 @@\n-deleted\n context", 4, 3);

expect(
resolveDiffSelection(
Expand Down
13 changes: 6 additions & 7 deletions packages/review/src/review-api/comparison-coverage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
applyStructuralUpdate,
structuralRows,
} from "@dev.fast/review-protocol";
import type {
AlignmentRow,
FileLineRange,
Pins,
import {
type AlignmentRow,
type FileLineRange,
type Pins,
patchRows,
} from "@dev.fast/whiteboard-document";
import { parseUnifiedPatch } from "@review/unified-diff.js";
import {
Expand All @@ -23,7 +24,6 @@ import {
unionIntervals,
} from "@review/viewed-coverage.js";

import { textualRows } from "./lens-alignment.js";
import type { LocalReviewData } from "./local-data.js";

const hash = (parts: (string | null)[]) =>
Expand Down Expand Up @@ -91,8 +91,7 @@ export async function comparisonCoverage(

alignments.set(
file.path,
textualRows(
file.path,
patchRows(
patch,
base === null ? 0 : base.split("\n").length,
head === null ? 0 : head.split("\n").length,
Expand Down
52 changes: 0 additions & 52 deletions packages/review/src/review-api/lens-alignment.ts

This file was deleted.

5 changes: 2 additions & 3 deletions packages/review/src/review-api/review-progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
comparisonKey,
fileLineRangeSchema,
lensSelections,
patchRows,
resolveDiffSelection,
selectionKey,
selectionReferences,
Expand All @@ -26,7 +27,6 @@ import {
resolveFileLens,
uncategorizedSources,
} from "./file-lenses.js";
import { textualRows } from "./lens-alignment.js";
import type { LocalReviewData } from "./local-data.js";
import type { ReviewStore, Snapshot } from "./store.js";

Expand Down Expand Up @@ -208,8 +208,7 @@ export async function reviewProgress(
"no_alignment",
"Changed context file has no alignment.",
);
rows = textualRows(
source.file,
rows = patchRows(
"",
base?.split("\n").length ?? 0,
head?.split("\n").length ?? 0,
Expand Down
2 changes: 1 addition & 1 deletion packages/whiteboard-document/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dev.fast/whiteboard-document",
"version": "0.2.1",
"version": "0.2.2",
"description": "The whiteboard document: block schemas, the edit reducer and its summary, for any runtime.",
"license": "MIT",
"repository": {
Expand Down
1 change: 1 addition & 0 deletions packages/whiteboard-document/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export {
comparisonKey,
formatAnchor,
parseAnchor,
patchRows,
rangeAnchor,
resolveDiffSelection,
selectSource,
Expand Down
34 changes: 34 additions & 0 deletions packages/whiteboard-document/src/lens-selection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect, it } from "vitest";

import { patchRows } from "./lens-selection.js";

it("pairs a patch's lines, unchanged gaps and the tail included", () => {
expect(
patchRows(
"@@ -2,2 +2,1 @@\n-deleted\n context\n\\ No newline at end of file",
4,
3,
),
).toEqual([
[0, 0],
[1, null],
[2, 1],
[3, 2],
]);
});

it("pairs an added file's lines with nothing, skipping the git headers", () => {
expect(
patchRows("--- /dev/null\n+++ b/a\n@@ -0,0 +1,2 @@\n+a\n+b", 0, 2),
).toEqual([
[null, 0],
[null, 1],
]);
});

it("pairs each line with itself without a patch", () => {
expect(patchRows("", 2, 2)).toEqual([
[0, 0],
[1, 1],
]);
});
57 changes: 57 additions & 0 deletions packages/whiteboard-document/src/lens-selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,63 @@ export type LensSource = DiffSelection;

export type AlignmentRow = readonly [number | null, number | null];

const HUNK = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;

/** The 0-based line pairs a unified patch aligns, unchanged gaps included,
* for files of `baseCount` and `headCount` lines. An empty patch pairs each
* line with itself. */
export function patchRows(
patch: string,
baseCount: number,
headCount: number,
): AlignmentRow[] {
const rows: AlignmentRow[] = [];
let base = 0;
let head = 0;
let removed = 0;
let added = 0;
let inHunk = false;

const append = (baseEnd: number, headEnd: number) => {
while (base < baseEnd || head < headEnd)
rows.push([
base < baseEnd ? base++ : null,
head < headEnd ? head++ : null,
]);
};

const flush = () => {
append(base + removed, head + added);
removed = added = 0;
};

for (const line of patch.split(/\r?\n/)) {
const hunk = HUNK.exec(line);

if (hunk) {
inHunk = true;
flush();
const [, oldStart, oldLines = "1", newStart, newLines = "1"] = hunk;

append(
Number(oldLines) ? Number(oldStart) - 1 : Number(oldStart),
Number(newLines) ? Number(newStart) - 1 : Number(newStart),
);
} else if (!inHunk) continue;
else if (line.startsWith("+")) added++;
else if (line.startsWith("-")) removed++;
else if (line.startsWith(" ")) {
flush();
append(base + 1, head + 1);
}
}

flush();
append(baseCount, headCount);

return rows;
}

/** Pins-less selections keep the key they always had. */
export function selectionKey(source: LensSource): string {
return JSON.stringify([
Expand Down
Loading